jekyll-pwa-workbox 5.1.4 → 5.1.41

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jekyll-pwa-workbox.rb +1 -1
  3. data/lib/vendor/workbox-v5.1.4/workbox-background-sync.dev.js +818 -818
  4. data/lib/vendor/workbox-v5.1.4/workbox-background-sync.prod.js +2 -2
  5. data/lib/vendor/workbox-v5.1.4/workbox-broadcast-update.dev.js +288 -288
  6. data/lib/vendor/workbox-v5.1.4/workbox-broadcast-update.prod.js +2 -2
  7. data/lib/vendor/workbox-v5.1.4/workbox-cacheable-response.dev.js +191 -191
  8. data/lib/vendor/workbox-v5.1.4/workbox-cacheable-response.prod.js +2 -2
  9. data/lib/vendor/workbox-v5.1.4/workbox-core.dev.js +1858 -1858
  10. data/lib/vendor/workbox-v5.1.4/workbox-core.prod.js +2 -2
  11. data/lib/vendor/workbox-v5.1.4/workbox-expiration.dev.js +649 -649
  12. data/lib/vendor/workbox-v5.1.4/workbox-expiration.prod.js +2 -2
  13. data/lib/vendor/workbox-v5.1.4/workbox-navigation-preload.dev.js +102 -102
  14. data/lib/vendor/workbox-v5.1.4/workbox-navigation-preload.prod.js +2 -2
  15. data/lib/vendor/workbox-v5.1.4/workbox-offline-ga.dev.js +235 -235
  16. data/lib/vendor/workbox-v5.1.4/workbox-offline-ga.prod.js +2 -2
  17. data/lib/vendor/workbox-v5.1.4/workbox-precaching.dev.js +1210 -1210
  18. data/lib/vendor/workbox-v5.1.4/workbox-precaching.prod.js +2 -2
  19. data/lib/vendor/workbox-v5.1.4/workbox-range-requests.dev.js +262 -262
  20. data/lib/vendor/workbox-v5.1.4/workbox-range-requests.prod.js +2 -2
  21. data/lib/vendor/workbox-v5.1.4/workbox-routing.dev.js +923 -923
  22. data/lib/vendor/workbox-v5.1.4/workbox-routing.prod.js +2 -2
  23. data/lib/vendor/workbox-v5.1.4/workbox-strategies.dev.js +923 -923
  24. data/lib/vendor/workbox-v5.1.4/workbox-strategies.prod.js +2 -2
  25. data/lib/vendor/workbox-v5.1.4/workbox-streams.dev.js +318 -318
  26. data/lib/vendor/workbox-v5.1.4/workbox-streams.prod.js +2 -2
  27. data/lib/vendor/workbox-v5.1.4/workbox-sw.js +2 -2
  28. data/lib/vendor/workbox-v5.1.4/workbox-window.dev.es5.mjs +1125 -1125
  29. data/lib/vendor/workbox-v5.1.4/workbox-window.dev.mjs +943 -943
  30. data/lib/vendor/workbox-v5.1.4/workbox-window.dev.umd.js +1136 -1136
  31. data/lib/vendor/workbox-v5.1.4/workbox-window.prod.es5.mjs +2 -2
  32. data/lib/vendor/workbox-v5.1.4/workbox-window.prod.mjs +2 -2
  33. data/lib/vendor/workbox-v5.1.4/workbox-window.prod.umd.js +2 -2
  34. metadata +2 -2
@@ -1,943 +1,943 @@
1
- try {
2
- self['workbox:window:5.1.4'] && _();
3
- } catch (e) {}
4
-
5
- /*
6
- Copyright 2019 Google LLC
7
-
8
- Use of this source code is governed by an MIT-style
9
- license that can be found in the LICENSE file or at
10
- https://opensource.org/licenses/MIT.
11
- */
12
- /**
13
- * Sends a data object to a service worker via `postMessage` and resolves with
14
- * a response (if any).
15
- *
16
- * A response can be set in a message handler in the service worker by
17
- * calling `event.ports[0].postMessage(...)`, which will resolve the promise
18
- * returned by `messageSW()`. If no response is set, the promise will not
19
- * resolve.
20
- *
21
- * @param {ServiceWorker} sw The service worker to send the message to.
22
- * @param {Object} data An object to send to the service worker.
23
- * @return {Promise<Object|undefined>}
24
- * @memberof module:workbox-window
25
- */
26
-
27
- function messageSW(sw, data) {
28
- return new Promise(resolve => {
29
- const messageChannel = new MessageChannel();
30
-
31
- messageChannel.port1.onmessage = event => {
32
- resolve(event.data);
33
- };
34
-
35
- sw.postMessage(data, [messageChannel.port2]);
36
- });
37
- }
38
-
39
- try {
40
- self['workbox:core:5.1.4'] && _();
41
- } catch (e) {}
42
-
43
- /*
44
- Copyright 2018 Google LLC
45
-
46
- Use of this source code is governed by an MIT-style
47
- license that can be found in the LICENSE file or at
48
- https://opensource.org/licenses/MIT.
49
- */
50
- /**
51
- * The Deferred class composes Promises in a way that allows for them to be
52
- * resolved or rejected from outside the constructor. In most cases promises
53
- * should be used directly, but Deferreds can be necessary when the logic to
54
- * resolve a promise must be separate.
55
- *
56
- * @private
57
- */
58
-
59
- class Deferred {
60
- /**
61
- * Creates a promise and exposes its resolve and reject functions as methods.
62
- */
63
- constructor() {
64
- this.promise = new Promise((resolve, reject) => {
65
- this.resolve = resolve;
66
- this.reject = reject;
67
- });
68
- }
69
-
70
- }
71
-
72
- /*
73
- Copyright 2019 Google LLC
74
- Use of this source code is governed by an MIT-style
75
- license that can be found in the LICENSE file or at
76
- https://opensource.org/licenses/MIT.
77
- */
78
- /**
79
- * A helper function that prevents a promise from being flagged as unused.
80
- *
81
- * @private
82
- **/
83
-
84
- function dontWaitFor(promise) {
85
- // Effective no-op.
86
- promise.then(() => {});
87
- }
88
-
89
- /*
90
- Copyright 2019 Google LLC
91
- Use of this source code is governed by an MIT-style
92
- license that can be found in the LICENSE file or at
93
- https://opensource.org/licenses/MIT.
94
- */
95
- const logger = (() => {
96
- // Don't overwrite this value if it's already set.
97
- // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923
98
- if (!('__WB_DISABLE_DEV_LOGS' in self)) {
99
- self.__WB_DISABLE_DEV_LOGS = false;
100
- }
101
-
102
- let inGroup = false;
103
- const methodToColorMap = {
104
- debug: `#7f8c8d`,
105
- log: `#2ecc71`,
106
- warn: `#f39c12`,
107
- error: `#c0392b`,
108
- groupCollapsed: `#3498db`,
109
- groupEnd: null
110
- };
111
-
112
- const print = function (method, args) {
113
- if (self.__WB_DISABLE_DEV_LOGS) {
114
- return;
115
- }
116
-
117
- if (method === 'groupCollapsed') {
118
- // Safari doesn't print all console.groupCollapsed() arguments:
119
- // https://bugs.webkit.org/show_bug.cgi?id=182754
120
- if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
121
- console[method](...args);
122
- return;
123
- }
124
- }
125
-
126
- const styles = [`background: ${methodToColorMap[method]}`, `border-radius: 0.5em`, `color: white`, `font-weight: bold`, `padding: 2px 0.5em`]; // When in a group, the workbox prefix is not displayed.
127
-
128
- const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')];
129
- console[method](...logPrefix, ...args);
130
-
131
- if (method === 'groupCollapsed') {
132
- inGroup = true;
133
- }
134
-
135
- if (method === 'groupEnd') {
136
- inGroup = false;
137
- }
138
- };
139
-
140
- const api = {};
141
- const loggerMethods = Object.keys(methodToColorMap);
142
-
143
- for (const key of loggerMethods) {
144
- const method = key;
145
-
146
- api[method] = (...args) => {
147
- print(method, args);
148
- };
149
- }
150
-
151
- return api;
152
- })();
153
-
154
- /*
155
- Copyright 2019 Google LLC
156
-
157
- Use of this source code is governed by an MIT-style
158
- license that can be found in the LICENSE file or at
159
- https://opensource.org/licenses/MIT.
160
- */
161
-
162
- /**
163
- * A minimal `EventTarget` shim.
164
- * This is necessary because not all browsers support constructable
165
- * `EventTarget`, so using a real `EventTarget` will error.
166
- * @private
167
- */
168
- class WorkboxEventTarget {
169
- constructor() {
170
- this._eventListenerRegistry = new Map();
171
- }
172
- /**
173
- * @param {string} type
174
- * @param {Function} listener
175
- * @private
176
- */
177
-
178
-
179
- addEventListener(type, listener) {
180
- const foo = this._getEventListenersByType(type);
181
-
182
- foo.add(listener);
183
- }
184
- /**
185
- * @param {string} type
186
- * @param {Function} listener
187
- * @private
188
- */
189
-
190
-
191
- removeEventListener(type, listener) {
192
- this._getEventListenersByType(type).delete(listener);
193
- }
194
- /**
195
- * @param {Object} event
196
- * @private
197
- */
198
-
199
-
200
- dispatchEvent(event) {
201
- event.target = this;
202
-
203
- const listeners = this._getEventListenersByType(event.type);
204
-
205
- for (const listener of listeners) {
206
- listener(event);
207
- }
208
- }
209
- /**
210
- * Returns a Set of listeners associated with the passed event type.
211
- * If no handlers have been registered, an empty Set is returned.
212
- *
213
- * @param {string} type The event type.
214
- * @return {Set<ListenerCallback>} An array of handler functions.
215
- * @private
216
- */
217
-
218
-
219
- _getEventListenersByType(type) {
220
- if (!this._eventListenerRegistry.has(type)) {
221
- this._eventListenerRegistry.set(type, new Set());
222
- }
223
-
224
- return this._eventListenerRegistry.get(type);
225
- }
226
-
227
- }
228
-
229
- /*
230
- Copyright 2019 Google LLC
231
-
232
- Use of this source code is governed by an MIT-style
233
- license that can be found in the LICENSE file or at
234
- https://opensource.org/licenses/MIT.
235
- */
236
- /**
237
- * Returns true if two URLs have the same `.href` property. The URLS can be
238
- * relative, and if they are the current location href is used to resolve URLs.
239
- *
240
- * @private
241
- * @param {string} url1
242
- * @param {string} url2
243
- * @return {boolean}
244
- */
245
-
246
- function urlsMatch(url1, url2) {
247
- const {
248
- href
249
- } = location;
250
- return new URL(url1, href).href === new URL(url2, href).href;
251
- }
252
-
253
- /*
254
- Copyright 2019 Google LLC
255
-
256
- Use of this source code is governed by an MIT-style
257
- license that can be found in the LICENSE file or at
258
- https://opensource.org/licenses/MIT.
259
- */
260
- /**
261
- * A minimal `Event` subclass shim.
262
- * This doesn't *actually* subclass `Event` because not all browsers support
263
- * constructable `EventTarget`, and using a real `Event` will error.
264
- * @private
265
- */
266
-
267
- class WorkboxEvent {
268
- constructor(type, props) {
269
- this.type = type;
270
- Object.assign(this, props);
271
- }
272
-
273
- }
274
-
275
- /*
276
- Copyright 2019 Google LLC
277
-
278
- Use of this source code is governed by an MIT-style
279
- license that can be found in the LICENSE file or at
280
- https://opensource.org/licenses/MIT.
281
- */
282
- // `skipWaiting()` wasn't called. This 200 amount wasn't scientifically
283
- // chosen, but it seems to avoid false positives in my testing.
284
-
285
- const WAITING_TIMEOUT_DURATION = 200; // The amount of time after a registration that we can reasonably conclude
286
- // that the registration didn't trigger an update.
287
-
288
- const REGISTRATION_TIMEOUT_DURATION = 60000;
289
- /**
290
- * A class to aid in handling service worker registration, updates, and
291
- * reacting to service worker lifecycle events.
292
- *
293
- * @fires [message]{@link module:workbox-window.Workbox#message}
294
- * @fires [installed]{@link module:workbox-window.Workbox#installed}
295
- * @fires [waiting]{@link module:workbox-window.Workbox#waiting}
296
- * @fires [controlling]{@link module:workbox-window.Workbox#controlling}
297
- * @fires [activated]{@link module:workbox-window.Workbox#activated}
298
- * @fires [redundant]{@link module:workbox-window.Workbox#redundant}
299
- * @fires [externalinstalled]{@link module:workbox-window.Workbox#externalinstalled}
300
- * @fires [externalwaiting]{@link module:workbox-window.Workbox#externalwaiting}
301
- * @fires [externalactivated]{@link module:workbox-window.Workbox#externalactivated}
302
- * @memberof module:workbox-window
303
- */
304
-
305
- class Workbox extends WorkboxEventTarget {
306
- /**
307
- * Creates a new Workbox instance with a script URL and service worker
308
- * options. The script URL and options are the same as those used when
309
- * calling `navigator.serviceWorker.register(scriptURL, options)`. See:
310
- * https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register
311
- *
312
- * @param {string} scriptURL The service worker script associated with this
313
- * instance.
314
- * @param {Object} [registerOptions] The service worker options associated
315
- * with this instance.
316
- */
317
- constructor(scriptURL, registerOptions = {}) {
318
- super();
319
- this._registerOptions = {};
320
- this._updateFoundCount = 0; // Deferreds we can resolve later.
321
-
322
- this._swDeferred = new Deferred();
323
- this._activeDeferred = new Deferred();
324
- this._controllingDeferred = new Deferred();
325
- this._registrationTime = 0;
326
- this._ownSWs = new Set();
327
- /**
328
- * @private
329
- */
330
-
331
- this._onUpdateFound = () => {
332
- // `this._registration` will never be `undefined` after an update is found.
333
- const registration = this._registration;
334
- const installingSW = registration.installing; // If the script URL passed to `navigator.serviceWorker.register()` is
335
- // different from the current controlling SW's script URL, we know any
336
- // successful registration calls will trigger an `updatefound` event.
337
- // But if the registered script URL is the same as the current controlling
338
- // SW's script URL, we'll only get an `updatefound` event if the file
339
- // changed since it was last registered. This can be a problem if the user
340
- // opens up the same page in a different tab, and that page registers
341
- // a SW that triggers an update. It's a problem because this page has no
342
- // good way of knowing whether the `updatefound` event came from the SW
343
- // script it registered or from a registration attempt made by a newer
344
- // version of the page running in another tab.
345
- // To minimize the possibility of a false positive, we use the logic here:
346
-
347
- const updateLikelyTriggeredExternally = // Since we enforce only calling `register()` once, and since we don't
348
- // add the `updatefound` event listener until the `register()` call, if
349
- // `_updateFoundCount` is > 0 then it means this method has already
350
- // been called, thus this SW must be external
351
- this._updateFoundCount > 0 || // If the script URL of the installing SW is different from this
352
- // instance's script URL, we know it's definitely not from our
353
- // registration.
354
- !urlsMatch(installingSW.scriptURL, this._scriptURL) || // If all of the above are false, then we use a time-based heuristic:
355
- // Any `updatefound` event that occurs long after our registration is
356
- // assumed to be external.
357
- performance.now() > this._registrationTime + REGISTRATION_TIMEOUT_DURATION ? // If any of the above are not true, we assume the update was
358
- // triggered by this instance.
359
- true : false;
360
-
361
- if (updateLikelyTriggeredExternally) {
362
- this._externalSW = installingSW;
363
- registration.removeEventListener('updatefound', this._onUpdateFound);
364
- } else {
365
- // If the update was not triggered externally we know the installing
366
- // SW is the one we registered, so we set it.
367
- this._sw = installingSW;
368
-
369
- this._ownSWs.add(installingSW);
370
-
371
- this._swDeferred.resolve(installingSW); // The `installing` state isn't something we have a dedicated
372
- // callback for, but we do log messages for it in development.
373
-
374
-
375
- {
376
- if (navigator.serviceWorker.controller) {
377
- logger.log('Updated service worker found. Installing now...');
378
- } else {
379
- logger.log('Service worker is installing...');
380
- }
381
- }
382
- } // Increment the `updatefound` count, so future invocations of this
383
- // method can be sure they were triggered externally.
384
-
385
-
386
- ++this._updateFoundCount; // Add a `statechange` listener regardless of whether this update was
387
- // triggered externally, since we have callbacks for both.
388
-
389
- installingSW.addEventListener('statechange', this._onStateChange);
390
- };
391
- /**
392
- * @private
393
- * @param {Event} originalEvent
394
- */
395
-
396
-
397
- this._onStateChange = originalEvent => {
398
- // `this._registration` will never be `undefined` after an update is found.
399
- const registration = this._registration;
400
- const sw = originalEvent.target;
401
- const {
402
- state
403
- } = sw;
404
- const isExternal = sw === this._externalSW;
405
- const eventPrefix = isExternal ? 'external' : '';
406
- const eventProps = {
407
- sw,
408
- originalEvent
409
- };
410
-
411
- if (!isExternal && this._isUpdate) {
412
- eventProps.isUpdate = true;
413
- }
414
-
415
- this.dispatchEvent(new WorkboxEvent(eventPrefix + state, eventProps));
416
-
417
- if (state === 'installed') {
418
- // This timeout is used to ignore cases where the service worker calls
419
- // `skipWaiting()` in the install event, thus moving it directly in the
420
- // activating state. (Since all service workers *must* go through the
421
- // waiting phase, the only way to detect `skipWaiting()` called in the
422
- // install event is to observe that the time spent in the waiting phase
423
- // is very short.)
424
- // NOTE: we don't need separate timeouts for the own and external SWs
425
- // since they can't go through these phases at the same time.
426
- this._waitingTimeout = self.setTimeout(() => {
427
- // Ensure the SW is still waiting (it may now be redundant).
428
- if (state === 'installed' && registration.waiting === sw) {
429
- this.dispatchEvent(new WorkboxEvent(eventPrefix + 'waiting', eventProps));
430
-
431
- {
432
- if (isExternal) {
433
- logger.warn('An external service worker has installed but is ' + 'waiting for this client to close before activating...');
434
- } else {
435
- logger.warn('The service worker has installed but is waiting ' + 'for existing clients to close before activating...');
436
- }
437
- }
438
- }
439
- }, WAITING_TIMEOUT_DURATION);
440
- } else if (state === 'activating') {
441
- clearTimeout(this._waitingTimeout);
442
-
443
- if (!isExternal) {
444
- this._activeDeferred.resolve(sw);
445
- }
446
- }
447
-
448
- {
449
- switch (state) {
450
- case 'installed':
451
- if (isExternal) {
452
- logger.warn('An external service worker has installed. ' + 'You may want to suggest users reload this page.');
453
- } else {
454
- logger.log('Registered service worker installed.');
455
- }
456
-
457
- break;
458
-
459
- case 'activated':
460
- if (isExternal) {
461
- logger.warn('An external service worker has activated.');
462
- } else {
463
- logger.log('Registered service worker activated.');
464
-
465
- if (sw !== navigator.serviceWorker.controller) {
466
- logger.warn('The registered service worker is active but ' + 'not yet controlling the page. Reload or run ' + '`clients.claim()` in the service worker.');
467
- }
468
- }
469
-
470
- break;
471
-
472
- case 'redundant':
473
- if (sw === this._compatibleControllingSW) {
474
- logger.log('Previously controlling service worker now redundant!');
475
- } else if (!isExternal) {
476
- logger.log('Registered service worker now redundant!');
477
- }
478
-
479
- break;
480
- }
481
- }
482
- };
483
- /**
484
- * @private
485
- * @param {Event} originalEvent
486
- */
487
-
488
-
489
- this._onControllerChange = originalEvent => {
490
- const sw = this._sw;
491
-
492
- if (sw === navigator.serviceWorker.controller) {
493
- this.dispatchEvent(new WorkboxEvent('controlling', {
494
- sw,
495
- originalEvent,
496
- isUpdate: this._isUpdate
497
- }));
498
-
499
- {
500
- logger.log('Registered service worker now controlling this page.');
501
- }
502
-
503
- this._controllingDeferred.resolve(sw);
504
- }
505
- };
506
- /**
507
- * @private
508
- * @param {Event} originalEvent
509
- */
510
-
511
-
512
- this._onMessage = async originalEvent => {
513
- const {
514
- data,
515
- source
516
- } = originalEvent; // Wait until there's an "own" service worker. This is used to buffer
517
- // `message` events that may be received prior to calling `register()`.
518
-
519
- await this.getSW(); // If the service worker that sent the message is in the list of own
520
- // service workers for this instance, dispatch a `message` event.
521
- // NOTE: we check for all previously owned service workers rather than
522
- // just the current one because some messages (e.g. cache updates) use
523
- // a timeout when sent and may be delayed long enough for a service worker
524
- // update to be found.
525
-
526
- if (this._ownSWs.has(source)) {
527
- this.dispatchEvent(new WorkboxEvent('message', {
528
- data,
529
- sw: source,
530
- originalEvent
531
- }));
532
- }
533
- };
534
-
535
- this._scriptURL = scriptURL;
536
- this._registerOptions = registerOptions; // Add a message listener immediately since messages received during
537
- // page load are buffered only until the DOMContentLoaded event:
538
- // https://github.com/GoogleChrome/workbox/issues/2202
539
-
540
- navigator.serviceWorker.addEventListener('message', this._onMessage);
541
- }
542
- /**
543
- * Registers a service worker for this instances script URL and service
544
- * worker options. By default this method delays registration until after
545
- * the window has loaded.
546
- *
547
- * @param {Object} [options]
548
- * @param {Function} [options.immediate=false] Setting this to true will
549
- * register the service worker immediately, even if the window has
550
- * not loaded (not recommended).
551
- */
552
-
553
-
554
- async register({
555
- immediate = false
556
- } = {}) {
557
- {
558
- if (this._registrationTime) {
559
- logger.error('Cannot re-register a Workbox instance after it has ' + 'been registered. Create a new instance instead.');
560
- return;
561
- }
562
- }
563
-
564
- if (!immediate && document.readyState !== 'complete') {
565
- await new Promise(res => window.addEventListener('load', res));
566
- } // Set this flag to true if any service worker was controlling the page
567
- // at registration time.
568
-
569
-
570
- this._isUpdate = Boolean(navigator.serviceWorker.controller); // Before registering, attempt to determine if a SW is already controlling
571
- // the page, and if that SW script (and version, if specified) matches this
572
- // instance's script.
573
-
574
- this._compatibleControllingSW = this._getControllingSWIfCompatible();
575
- this._registration = await this._registerScript(); // If we have a compatible controller, store the controller as the "own"
576
- // SW, resolve active/controlling deferreds and add necessary listeners.
577
-
578
- if (this._compatibleControllingSW) {
579
- this._sw = this._compatibleControllingSW;
580
-
581
- this._activeDeferred.resolve(this._compatibleControllingSW);
582
-
583
- this._controllingDeferred.resolve(this._compatibleControllingSW);
584
-
585
- this._compatibleControllingSW.addEventListener('statechange', this._onStateChange, {
586
- once: true
587
- });
588
- } // If there's a waiting service worker with a matching URL before the
589
- // `updatefound` event fires, it likely means that this site is open
590
- // in another tab, or the user refreshed the page (and thus the previous
591
- // page wasn't fully unloaded before this page started loading).
592
- // https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#waiting
593
-
594
-
595
- const waitingSW = this._registration.waiting;
596
-
597
- if (waitingSW && urlsMatch(waitingSW.scriptURL, this._scriptURL)) {
598
- // Store the waiting SW as the "own" Sw, even if it means overwriting
599
- // a compatible controller.
600
- this._sw = waitingSW; // Run this in the next microtask, so any code that adds an event
601
- // listener after awaiting `register()` will get this event.
602
-
603
- dontWaitFor(Promise.resolve().then(() => {
604
- this.dispatchEvent(new WorkboxEvent('waiting', {
605
- sw: waitingSW,
606
- wasWaitingBeforeRegister: true
607
- }));
608
-
609
- {
610
- logger.warn('A service worker was already waiting to activate ' + 'before this script was registered...');
611
- }
612
- }));
613
- } // If an "own" SW is already set, resolve the deferred.
614
-
615
-
616
- if (this._sw) {
617
- this._swDeferred.resolve(this._sw);
618
-
619
- this._ownSWs.add(this._sw);
620
- }
621
-
622
- {
623
- logger.log('Successfully registered service worker.', this._scriptURL);
624
-
625
- if (navigator.serviceWorker.controller) {
626
- if (this._compatibleControllingSW) {
627
- logger.debug('A service worker with the same script URL ' + 'is already controlling this page.');
628
- } else {
629
- logger.debug('A service worker with a different script URL is ' + 'currently controlling the page. The browser is now fetching ' + 'the new script now...');
630
- }
631
- }
632
-
633
- const currentPageIsOutOfScope = () => {
634
- const scopeURL = new URL(this._registerOptions.scope || this._scriptURL, document.baseURI);
635
- const scopeURLBasePath = new URL('./', scopeURL.href).pathname;
636
- return !location.pathname.startsWith(scopeURLBasePath);
637
- };
638
-
639
- if (currentPageIsOutOfScope()) {
640
- logger.warn('The current page is not in scope for the registered ' + 'service worker. Was this a mistake?');
641
- }
642
- }
643
-
644
- this._registration.addEventListener('updatefound', this._onUpdateFound);
645
-
646
- navigator.serviceWorker.addEventListener('controllerchange', this._onControllerChange, {
647
- once: true
648
- });
649
- return this._registration;
650
- }
651
- /**
652
- * Checks for updates of the registered service worker.
653
- */
654
-
655
-
656
- async update() {
657
- if (!this._registration) {
658
- {
659
- logger.error('Cannot update a Workbox instance without ' + 'being registered. Register the Workbox instance first.');
660
- }
661
-
662
- return;
663
- } // Try to update registration
664
-
665
-
666
- await this._registration.update();
667
- }
668
- /**
669
- * Resolves to the service worker registered by this instance as soon as it
670
- * is active. If a service worker was already controlling at registration
671
- * time then it will resolve to that if the script URLs (and optionally
672
- * script versions) match, otherwise it will wait until an update is found
673
- * and activates.
674
- *
675
- * @return {Promise<ServiceWorker>}
676
- */
677
-
678
-
679
- get active() {
680
- return this._activeDeferred.promise;
681
- }
682
- /**
683
- * Resolves to the service worker registered by this instance as soon as it
684
- * is controlling the page. If a service worker was already controlling at
685
- * registration time then it will resolve to that if the script URLs (and
686
- * optionally script versions) match, otherwise it will wait until an update
687
- * is found and starts controlling the page.
688
- * Note: the first time a service worker is installed it will active but
689
- * not start controlling the page unless `clients.claim()` is called in the
690
- * service worker.
691
- *
692
- * @return {Promise<ServiceWorker>}
693
- */
694
-
695
-
696
- get controlling() {
697
- return this._controllingDeferred.promise;
698
- }
699
- /**
700
- * Resolves with a reference to a service worker that matches the script URL
701
- * of this instance, as soon as it's available.
702
- *
703
- * If, at registration time, there's already an active or waiting service
704
- * worker with a matching script URL, it will be used (with the waiting
705
- * service worker taking precedence over the active service worker if both
706
- * match, since the waiting service worker would have been registered more
707
- * recently).
708
- * If there's no matching active or waiting service worker at registration
709
- * time then the promise will not resolve until an update is found and starts
710
- * installing, at which point the installing service worker is used.
711
- *
712
- * @return {Promise<ServiceWorker>}
713
- */
714
-
715
-
716
- async getSW() {
717
- // If `this._sw` is set, resolve with that as we want `getSW()` to
718
- // return the correct (new) service worker if an update is found.
719
- return this._sw !== undefined ? this._sw : this._swDeferred.promise;
720
- }
721
- /**
722
- * Sends the passed data object to the service worker registered by this
723
- * instance (via [`getSW()`]{@link module:workbox-window.Workbox#getSW}) and resolves
724
- * with a response (if any).
725
- *
726
- * A response can be set in a message handler in the service worker by
727
- * calling `event.ports[0].postMessage(...)`, which will resolve the promise
728
- * returned by `messageSW()`. If no response is set, the promise will never
729
- * resolve.
730
- *
731
- * @param {Object} data An object to send to the service worker
732
- * @return {Promise<Object>}
733
- */
734
-
735
-
736
- async messageSW(data) {
737
- const sw = await this.getSW();
738
- return messageSW(sw, data);
739
- }
740
- /**
741
- * Checks for a service worker already controlling the page and returns
742
- * it if its script URL matches.
743
- *
744
- * @private
745
- * @return {ServiceWorker|undefined}
746
- */
747
-
748
-
749
- _getControllingSWIfCompatible() {
750
- const controller = navigator.serviceWorker.controller;
751
-
752
- if (controller && urlsMatch(controller.scriptURL, this._scriptURL)) {
753
- return controller;
754
- } else {
755
- return undefined;
756
- }
757
- }
758
- /**
759
- * Registers a service worker for this instances script URL and register
760
- * options and tracks the time registration was complete.
761
- *
762
- * @private
763
- */
764
-
765
-
766
- async _registerScript() {
767
- try {
768
- const reg = await navigator.serviceWorker.register(this._scriptURL, this._registerOptions); // Keep track of when registration happened, so it can be used in the
769
- // `this._onUpdateFound` heuristic. Also use the presence of this
770
- // property as a way to see if `.register()` has been called.
771
-
772
- this._registrationTime = performance.now();
773
- return reg;
774
- } catch (error) {
775
- {
776
- logger.error(error);
777
- } // Re-throw the error.
778
-
779
-
780
- throw error;
781
- }
782
- }
783
-
784
- }
785
- // -----------------------------------------------------------------------
786
-
787
- /**
788
- * The `message` event is dispatched any time a `postMessage` is received.
789
- *
790
- * @event module:workbox-window.Workbox#message
791
- * @type {WorkboxEvent}
792
- * @property {*} data The `data` property from the original `message` event.
793
- * @property {Event} originalEvent The original [`message`]{@link https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent}
794
- * event.
795
- * @property {string} type `message`.
796
- * @property {Workbox} target The `Workbox` instance.
797
- */
798
-
799
- /**
800
- * The `installed` event is dispatched if the state of a
801
- * [`Workbox`]{@link module:workbox-window.Workbox} instance's
802
- * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
803
- * changes to `installed`.
804
- *
805
- * Then can happen either the very first time a service worker is installed,
806
- * or after an update to the current service worker is found. In the case
807
- * of an update being found, the event's `isUpdate` property will be `true`.
808
- *
809
- * @event module:workbox-window.Workbox#installed
810
- * @type {WorkboxEvent}
811
- * @property {ServiceWorker} sw The service worker instance.
812
- * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
813
- * event.
814
- * @property {boolean|undefined} isUpdate True if a service worker was already
815
- * controlling when this `Workbox` instance called `register()`.
816
- * @property {string} type `installed`.
817
- * @property {Workbox} target The `Workbox` instance.
818
- */
819
-
820
- /**
821
- * The `waiting` event is dispatched if the state of a
822
- * [`Workbox`]{@link module:workbox-window.Workbox} instance's
823
- * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
824
- * changes to `installed` and then doesn't immediately change to `activating`.
825
- * It may also be dispatched if a service worker with the same
826
- * [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
827
- * was already waiting when the [`register()`]{@link module:workbox-window.Workbox#register}
828
- * method was called.
829
- *
830
- * @event module:workbox-window.Workbox#waiting
831
- * @type {WorkboxEvent}
832
- * @property {ServiceWorker} sw The service worker instance.
833
- * @property {Event|undefined} originalEvent The original
834
- * [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
835
- * event, or `undefined` in the case where the service worker was waiting
836
- * to before `.register()` was called.
837
- * @property {boolean|undefined} isUpdate True if a service worker was already
838
- * controlling when this `Workbox` instance called `register()`.
839
- * @property {boolean|undefined} wasWaitingBeforeRegister True if a service worker with
840
- * a matching `scriptURL` was already waiting when this `Workbox`
841
- * instance called `register()`.
842
- * @property {string} type `waiting`.
843
- * @property {Workbox} target The `Workbox` instance.
844
- */
845
-
846
- /**
847
- * The `controlling` event is dispatched if a
848
- * [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
849
- * fires on the service worker [container]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer}
850
- * and the [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
851
- * of the new [controller]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/controller}
852
- * matches the `scriptURL` of the `Workbox` instance's
853
- * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}.
854
- *
855
- * @event module:workbox-window.Workbox#controlling
856
- * @type {WorkboxEvent}
857
- * @property {ServiceWorker} sw The service worker instance.
858
- * @property {Event} originalEvent The original [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
859
- * event.
860
- * @property {boolean|undefined} isUpdate True if a service worker was already
861
- * controlling when this service worker was registered.
862
- * @property {string} type `controlling`.
863
- * @property {Workbox} target The `Workbox` instance.
864
- */
865
-
866
- /**
867
- * The `activated` event is dispatched if the state of a
868
- * [`Workbox`]{@link module:workbox-window.Workbox} instance's
869
- * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
870
- * changes to `activated`.
871
- *
872
- * @event module:workbox-window.Workbox#activated
873
- * @type {WorkboxEvent}
874
- * @property {ServiceWorker} sw The service worker instance.
875
- * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
876
- * event.
877
- * @property {boolean|undefined} isUpdate True if a service worker was already
878
- * controlling when this `Workbox` instance called `register()`.
879
- * @property {string} type `activated`.
880
- * @property {Workbox} target The `Workbox` instance.
881
- */
882
-
883
- /**
884
- * The `redundant` event is dispatched if the state of a
885
- * [`Workbox`]{@link module:workbox-window.Workbox} instance's
886
- * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
887
- * changes to `redundant`.
888
- *
889
- * @event module:workbox-window.Workbox#redundant
890
- * @type {WorkboxEvent}
891
- * @property {ServiceWorker} sw The service worker instance.
892
- * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
893
- * event.
894
- * @property {boolean|undefined} isUpdate True if a service worker was already
895
- * controlling when this `Workbox` instance called `register()`.
896
- * @property {string} type `redundant`.
897
- * @property {Workbox} target The `Workbox` instance.
898
- */
899
-
900
- /**
901
- * The `externalinstalled` event is dispatched if the state of an
902
- * [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}
903
- * changes to `installed`.
904
- *
905
- * @event module:workbox-window.Workbox#externalinstalled
906
- * @type {WorkboxEvent}
907
- * @property {ServiceWorker} sw The service worker instance.
908
- * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
909
- * event.
910
- * @property {string} type `externalinstalled`.
911
- * @property {Workbox} target The `Workbox` instance.
912
- */
913
-
914
- /**
915
- * The `externalwaiting` event is dispatched if the state of an
916
- * [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}
917
- * changes to `waiting`.
918
- *
919
- * @event module:workbox-window.Workbox#externalwaiting
920
- * @type {WorkboxEvent}
921
- * @property {ServiceWorker} sw The service worker instance.
922
- * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
923
- * event.
924
- * @property {string} type `externalwaiting`.
925
- * @property {Workbox} target The `Workbox` instance.
926
- */
927
-
928
- /**
929
- * The `externalactivated` event is dispatched if the state of an
930
- * [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}
931
- * changes to `activated`.
932
- *
933
- * @event module:workbox-window.Workbox#externalactivated
934
- * @type {WorkboxEvent}
935
- * @property {ServiceWorker} sw The service worker instance.
936
- * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
937
- * event.
938
- * @property {string} type `externalactivated`.
939
- * @property {Workbox} target The `Workbox` instance.
940
- */
941
-
942
- export { Workbox, messageSW };
943
- //# sourceMappingURL=workbox-window.dev.mjs.map
1
+ try {
2
+ self['workbox:window:5.1.4'] && _();
3
+ } catch (e) {}
4
+
5
+ /*
6
+ Copyright 2019 Google LLC
7
+
8
+ Use of this source code is governed by an MIT-style
9
+ license that can be found in the LICENSE file or at
10
+ https://opensource.org/licenses/MIT.
11
+ */
12
+ /**
13
+ * Sends a data object to a service worker via `postMessage` and resolves with
14
+ * a response (if any).
15
+ *
16
+ * A response can be set in a message handler in the service worker by
17
+ * calling `event.ports[0].postMessage(...)`, which will resolve the promise
18
+ * returned by `messageSW()`. If no response is set, the promise will not
19
+ * resolve.
20
+ *
21
+ * @param {ServiceWorker} sw The service worker to send the message to.
22
+ * @param {Object} data An object to send to the service worker.
23
+ * @return {Promise<Object|undefined>}
24
+ * @memberof module:workbox-window
25
+ */
26
+
27
+ function messageSW(sw, data) {
28
+ return new Promise(resolve => {
29
+ const messageChannel = new MessageChannel();
30
+
31
+ messageChannel.port1.onmessage = event => {
32
+ resolve(event.data);
33
+ };
34
+
35
+ sw.postMessage(data, [messageChannel.port2]);
36
+ });
37
+ }
38
+
39
+ try {
40
+ self['workbox:core:5.1.4'] && _();
41
+ } catch (e) {}
42
+
43
+ /*
44
+ Copyright 2018 Google LLC
45
+
46
+ Use of this source code is governed by an MIT-style
47
+ license that can be found in the LICENSE file or at
48
+ https://opensource.org/licenses/MIT.
49
+ */
50
+ /**
51
+ * The Deferred class composes Promises in a way that allows for them to be
52
+ * resolved or rejected from outside the constructor. In most cases promises
53
+ * should be used directly, but Deferreds can be necessary when the logic to
54
+ * resolve a promise must be separate.
55
+ *
56
+ * @private
57
+ */
58
+
59
+ class Deferred {
60
+ /**
61
+ * Creates a promise and exposes its resolve and reject functions as methods.
62
+ */
63
+ constructor() {
64
+ this.promise = new Promise((resolve, reject) => {
65
+ this.resolve = resolve;
66
+ this.reject = reject;
67
+ });
68
+ }
69
+
70
+ }
71
+
72
+ /*
73
+ Copyright 2019 Google LLC
74
+ Use of this source code is governed by an MIT-style
75
+ license that can be found in the LICENSE file or at
76
+ https://opensource.org/licenses/MIT.
77
+ */
78
+ /**
79
+ * A helper function that prevents a promise from being flagged as unused.
80
+ *
81
+ * @private
82
+ **/
83
+
84
+ function dontWaitFor(promise) {
85
+ // Effective no-op.
86
+ promise.then(() => {});
87
+ }
88
+
89
+ /*
90
+ Copyright 2019 Google LLC
91
+ Use of this source code is governed by an MIT-style
92
+ license that can be found in the LICENSE file or at
93
+ https://opensource.org/licenses/MIT.
94
+ */
95
+ const logger = (() => {
96
+ // Don't overwrite this value if it's already set.
97
+ // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923
98
+ if (!('__WB_DISABLE_DEV_LOGS' in self)) {
99
+ self.__WB_DISABLE_DEV_LOGS = false;
100
+ }
101
+
102
+ let inGroup = false;
103
+ const methodToColorMap = {
104
+ debug: `#7f8c8d`,
105
+ log: `#2ecc71`,
106
+ warn: `#f39c12`,
107
+ error: `#c0392b`,
108
+ groupCollapsed: `#3498db`,
109
+ groupEnd: null
110
+ };
111
+
112
+ const print = function (method, args) {
113
+ if (self.__WB_DISABLE_DEV_LOGS) {
114
+ return;
115
+ }
116
+
117
+ if (method === 'groupCollapsed') {
118
+ // Safari doesn't print all console.groupCollapsed() arguments:
119
+ // https://bugs.webkit.org/show_bug.cgi?id=182754
120
+ if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
121
+ console[method](...args);
122
+ return;
123
+ }
124
+ }
125
+
126
+ const styles = [`background: ${methodToColorMap[method]}`, `border-radius: 0.5em`, `color: white`, `font-weight: bold`, `padding: 2px 0.5em`]; // When in a group, the workbox prefix is not displayed.
127
+
128
+ const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')];
129
+ console[method](...logPrefix, ...args);
130
+
131
+ if (method === 'groupCollapsed') {
132
+ inGroup = true;
133
+ }
134
+
135
+ if (method === 'groupEnd') {
136
+ inGroup = false;
137
+ }
138
+ };
139
+
140
+ const api = {};
141
+ const loggerMethods = Object.keys(methodToColorMap);
142
+
143
+ for (const key of loggerMethods) {
144
+ const method = key;
145
+
146
+ api[method] = (...args) => {
147
+ print(method, args);
148
+ };
149
+ }
150
+
151
+ return api;
152
+ })();
153
+
154
+ /*
155
+ Copyright 2019 Google LLC
156
+
157
+ Use of this source code is governed by an MIT-style
158
+ license that can be found in the LICENSE file or at
159
+ https://opensource.org/licenses/MIT.
160
+ */
161
+
162
+ /**
163
+ * A minimal `EventTarget` shim.
164
+ * This is necessary because not all browsers support constructable
165
+ * `EventTarget`, so using a real `EventTarget` will error.
166
+ * @private
167
+ */
168
+ class WorkboxEventTarget {
169
+ constructor() {
170
+ this._eventListenerRegistry = new Map();
171
+ }
172
+ /**
173
+ * @param {string} type
174
+ * @param {Function} listener
175
+ * @private
176
+ */
177
+
178
+
179
+ addEventListener(type, listener) {
180
+ const foo = this._getEventListenersByType(type);
181
+
182
+ foo.add(listener);
183
+ }
184
+ /**
185
+ * @param {string} type
186
+ * @param {Function} listener
187
+ * @private
188
+ */
189
+
190
+
191
+ removeEventListener(type, listener) {
192
+ this._getEventListenersByType(type).delete(listener);
193
+ }
194
+ /**
195
+ * @param {Object} event
196
+ * @private
197
+ */
198
+
199
+
200
+ dispatchEvent(event) {
201
+ event.target = this;
202
+
203
+ const listeners = this._getEventListenersByType(event.type);
204
+
205
+ for (const listener of listeners) {
206
+ listener(event);
207
+ }
208
+ }
209
+ /**
210
+ * Returns a Set of listeners associated with the passed event type.
211
+ * If no handlers have been registered, an empty Set is returned.
212
+ *
213
+ * @param {string} type The event type.
214
+ * @return {Set<ListenerCallback>} An array of handler functions.
215
+ * @private
216
+ */
217
+
218
+
219
+ _getEventListenersByType(type) {
220
+ if (!this._eventListenerRegistry.has(type)) {
221
+ this._eventListenerRegistry.set(type, new Set());
222
+ }
223
+
224
+ return this._eventListenerRegistry.get(type);
225
+ }
226
+
227
+ }
228
+
229
+ /*
230
+ Copyright 2019 Google LLC
231
+
232
+ Use of this source code is governed by an MIT-style
233
+ license that can be found in the LICENSE file or at
234
+ https://opensource.org/licenses/MIT.
235
+ */
236
+ /**
237
+ * Returns true if two URLs have the same `.href` property. The URLS can be
238
+ * relative, and if they are the current location href is used to resolve URLs.
239
+ *
240
+ * @private
241
+ * @param {string} url1
242
+ * @param {string} url2
243
+ * @return {boolean}
244
+ */
245
+
246
+ function urlsMatch(url1, url2) {
247
+ const {
248
+ href
249
+ } = location;
250
+ return new URL(url1, href).href === new URL(url2, href).href;
251
+ }
252
+
253
+ /*
254
+ Copyright 2019 Google LLC
255
+
256
+ Use of this source code is governed by an MIT-style
257
+ license that can be found in the LICENSE file or at
258
+ https://opensource.org/licenses/MIT.
259
+ */
260
+ /**
261
+ * A minimal `Event` subclass shim.
262
+ * This doesn't *actually* subclass `Event` because not all browsers support
263
+ * constructable `EventTarget`, and using a real `Event` will error.
264
+ * @private
265
+ */
266
+
267
+ class WorkboxEvent {
268
+ constructor(type, props) {
269
+ this.type = type;
270
+ Object.assign(this, props);
271
+ }
272
+
273
+ }
274
+
275
+ /*
276
+ Copyright 2019 Google LLC
277
+
278
+ Use of this source code is governed by an MIT-style
279
+ license that can be found in the LICENSE file or at
280
+ https://opensource.org/licenses/MIT.
281
+ */
282
+ // `skipWaiting()` wasn't called. This 200 amount wasn't scientifically
283
+ // chosen, but it seems to avoid false positives in my testing.
284
+
285
+ const WAITING_TIMEOUT_DURATION = 200; // The amount of time after a registration that we can reasonably conclude
286
+ // that the registration didn't trigger an update.
287
+
288
+ const REGISTRATION_TIMEOUT_DURATION = 60000;
289
+ /**
290
+ * A class to aid in handling service worker registration, updates, and
291
+ * reacting to service worker lifecycle events.
292
+ *
293
+ * @fires [message]{@link module:workbox-window.Workbox#message}
294
+ * @fires [installed]{@link module:workbox-window.Workbox#installed}
295
+ * @fires [waiting]{@link module:workbox-window.Workbox#waiting}
296
+ * @fires [controlling]{@link module:workbox-window.Workbox#controlling}
297
+ * @fires [activated]{@link module:workbox-window.Workbox#activated}
298
+ * @fires [redundant]{@link module:workbox-window.Workbox#redundant}
299
+ * @fires [externalinstalled]{@link module:workbox-window.Workbox#externalinstalled}
300
+ * @fires [externalwaiting]{@link module:workbox-window.Workbox#externalwaiting}
301
+ * @fires [externalactivated]{@link module:workbox-window.Workbox#externalactivated}
302
+ * @memberof module:workbox-window
303
+ */
304
+
305
+ class Workbox extends WorkboxEventTarget {
306
+ /**
307
+ * Creates a new Workbox instance with a script URL and service worker
308
+ * options. The script URL and options are the same as those used when
309
+ * calling `navigator.serviceWorker.register(scriptURL, options)`. See:
310
+ * https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register
311
+ *
312
+ * @param {string} scriptURL The service worker script associated with this
313
+ * instance.
314
+ * @param {Object} [registerOptions] The service worker options associated
315
+ * with this instance.
316
+ */
317
+ constructor(scriptURL, registerOptions = {}) {
318
+ super();
319
+ this._registerOptions = {};
320
+ this._updateFoundCount = 0; // Deferreds we can resolve later.
321
+
322
+ this._swDeferred = new Deferred();
323
+ this._activeDeferred = new Deferred();
324
+ this._controllingDeferred = new Deferred();
325
+ this._registrationTime = 0;
326
+ this._ownSWs = new Set();
327
+ /**
328
+ * @private
329
+ */
330
+
331
+ this._onUpdateFound = () => {
332
+ // `this._registration` will never be `undefined` after an update is found.
333
+ const registration = this._registration;
334
+ const installingSW = registration.installing; // If the script URL passed to `navigator.serviceWorker.register()` is
335
+ // different from the current controlling SW's script URL, we know any
336
+ // successful registration calls will trigger an `updatefound` event.
337
+ // But if the registered script URL is the same as the current controlling
338
+ // SW's script URL, we'll only get an `updatefound` event if the file
339
+ // changed since it was last registered. This can be a problem if the user
340
+ // opens up the same page in a different tab, and that page registers
341
+ // a SW that triggers an update. It's a problem because this page has no
342
+ // good way of knowing whether the `updatefound` event came from the SW
343
+ // script it registered or from a registration attempt made by a newer
344
+ // version of the page running in another tab.
345
+ // To minimize the possibility of a false positive, we use the logic here:
346
+
347
+ const updateLikelyTriggeredExternally = // Since we enforce only calling `register()` once, and since we don't
348
+ // add the `updatefound` event listener until the `register()` call, if
349
+ // `_updateFoundCount` is > 0 then it means this method has already
350
+ // been called, thus this SW must be external
351
+ this._updateFoundCount > 0 || // If the script URL of the installing SW is different from this
352
+ // instance's script URL, we know it's definitely not from our
353
+ // registration.
354
+ !urlsMatch(installingSW.scriptURL, this._scriptURL) || // If all of the above are false, then we use a time-based heuristic:
355
+ // Any `updatefound` event that occurs long after our registration is
356
+ // assumed to be external.
357
+ performance.now() > this._registrationTime + REGISTRATION_TIMEOUT_DURATION ? // If any of the above are not true, we assume the update was
358
+ // triggered by this instance.
359
+ true : false;
360
+
361
+ if (updateLikelyTriggeredExternally) {
362
+ this._externalSW = installingSW;
363
+ registration.removeEventListener('updatefound', this._onUpdateFound);
364
+ } else {
365
+ // If the update was not triggered externally we know the installing
366
+ // SW is the one we registered, so we set it.
367
+ this._sw = installingSW;
368
+
369
+ this._ownSWs.add(installingSW);
370
+
371
+ this._swDeferred.resolve(installingSW); // The `installing` state isn't something we have a dedicated
372
+ // callback for, but we do log messages for it in development.
373
+
374
+
375
+ {
376
+ if (navigator.serviceWorker.controller) {
377
+ logger.log('Updated service worker found. Installing now...');
378
+ } else {
379
+ logger.log('Service worker is installing...');
380
+ }
381
+ }
382
+ } // Increment the `updatefound` count, so future invocations of this
383
+ // method can be sure they were triggered externally.
384
+
385
+
386
+ ++this._updateFoundCount; // Add a `statechange` listener regardless of whether this update was
387
+ // triggered externally, since we have callbacks for both.
388
+
389
+ installingSW.addEventListener('statechange', this._onStateChange);
390
+ };
391
+ /**
392
+ * @private
393
+ * @param {Event} originalEvent
394
+ */
395
+
396
+
397
+ this._onStateChange = originalEvent => {
398
+ // `this._registration` will never be `undefined` after an update is found.
399
+ const registration = this._registration;
400
+ const sw = originalEvent.target;
401
+ const {
402
+ state
403
+ } = sw;
404
+ const isExternal = sw === this._externalSW;
405
+ const eventPrefix = isExternal ? 'external' : '';
406
+ const eventProps = {
407
+ sw,
408
+ originalEvent
409
+ };
410
+
411
+ if (!isExternal && this._isUpdate) {
412
+ eventProps.isUpdate = true;
413
+ }
414
+
415
+ this.dispatchEvent(new WorkboxEvent(eventPrefix + state, eventProps));
416
+
417
+ if (state === 'installed') {
418
+ // This timeout is used to ignore cases where the service worker calls
419
+ // `skipWaiting()` in the install event, thus moving it directly in the
420
+ // activating state. (Since all service workers *must* go through the
421
+ // waiting phase, the only way to detect `skipWaiting()` called in the
422
+ // install event is to observe that the time spent in the waiting phase
423
+ // is very short.)
424
+ // NOTE: we don't need separate timeouts for the own and external SWs
425
+ // since they can't go through these phases at the same time.
426
+ this._waitingTimeout = self.setTimeout(() => {
427
+ // Ensure the SW is still waiting (it may now be redundant).
428
+ if (state === 'installed' && registration.waiting === sw) {
429
+ this.dispatchEvent(new WorkboxEvent(eventPrefix + 'waiting', eventProps));
430
+
431
+ {
432
+ if (isExternal) {
433
+ logger.warn('An external service worker has installed but is ' + 'waiting for this client to close before activating...');
434
+ } else {
435
+ logger.warn('The service worker has installed but is waiting ' + 'for existing clients to close before activating...');
436
+ }
437
+ }
438
+ }
439
+ }, WAITING_TIMEOUT_DURATION);
440
+ } else if (state === 'activating') {
441
+ clearTimeout(this._waitingTimeout);
442
+
443
+ if (!isExternal) {
444
+ this._activeDeferred.resolve(sw);
445
+ }
446
+ }
447
+
448
+ {
449
+ switch (state) {
450
+ case 'installed':
451
+ if (isExternal) {
452
+ logger.warn('An external service worker has installed. ' + 'You may want to suggest users reload this page.');
453
+ } else {
454
+ logger.log('Registered service worker installed.');
455
+ }
456
+
457
+ break;
458
+
459
+ case 'activated':
460
+ if (isExternal) {
461
+ logger.warn('An external service worker has activated.');
462
+ } else {
463
+ logger.log('Registered service worker activated.');
464
+
465
+ if (sw !== navigator.serviceWorker.controller) {
466
+ logger.warn('The registered service worker is active but ' + 'not yet controlling the page. Reload or run ' + '`clients.claim()` in the service worker.');
467
+ }
468
+ }
469
+
470
+ break;
471
+
472
+ case 'redundant':
473
+ if (sw === this._compatibleControllingSW) {
474
+ logger.log('Previously controlling service worker now redundant!');
475
+ } else if (!isExternal) {
476
+ logger.log('Registered service worker now redundant!');
477
+ }
478
+
479
+ break;
480
+ }
481
+ }
482
+ };
483
+ /**
484
+ * @private
485
+ * @param {Event} originalEvent
486
+ */
487
+
488
+
489
+ this._onControllerChange = originalEvent => {
490
+ const sw = this._sw;
491
+
492
+ if (sw === navigator.serviceWorker.controller) {
493
+ this.dispatchEvent(new WorkboxEvent('controlling', {
494
+ sw,
495
+ originalEvent,
496
+ isUpdate: this._isUpdate
497
+ }));
498
+
499
+ {
500
+ logger.log('Registered service worker now controlling this page.');
501
+ }
502
+
503
+ this._controllingDeferred.resolve(sw);
504
+ }
505
+ };
506
+ /**
507
+ * @private
508
+ * @param {Event} originalEvent
509
+ */
510
+
511
+
512
+ this._onMessage = async originalEvent => {
513
+ const {
514
+ data,
515
+ source
516
+ } = originalEvent; // Wait until there's an "own" service worker. This is used to buffer
517
+ // `message` events that may be received prior to calling `register()`.
518
+
519
+ await this.getSW(); // If the service worker that sent the message is in the list of own
520
+ // service workers for this instance, dispatch a `message` event.
521
+ // NOTE: we check for all previously owned service workers rather than
522
+ // just the current one because some messages (e.g. cache updates) use
523
+ // a timeout when sent and may be delayed long enough for a service worker
524
+ // update to be found.
525
+
526
+ if (this._ownSWs.has(source)) {
527
+ this.dispatchEvent(new WorkboxEvent('message', {
528
+ data,
529
+ sw: source,
530
+ originalEvent
531
+ }));
532
+ }
533
+ };
534
+
535
+ this._scriptURL = scriptURL;
536
+ this._registerOptions = registerOptions; // Add a message listener immediately since messages received during
537
+ // page load are buffered only until the DOMContentLoaded event:
538
+ // https://github.com/GoogleChrome/workbox/issues/2202
539
+
540
+ navigator.serviceWorker.addEventListener('message', this._onMessage);
541
+ }
542
+ /**
543
+ * Registers a service worker for this instances script URL and service
544
+ * worker options. By default this method delays registration until after
545
+ * the window has loaded.
546
+ *
547
+ * @param {Object} [options]
548
+ * @param {Function} [options.immediate=false] Setting this to true will
549
+ * register the service worker immediately, even if the window has
550
+ * not loaded (not recommended).
551
+ */
552
+
553
+
554
+ async register({
555
+ immediate = false
556
+ } = {}) {
557
+ {
558
+ if (this._registrationTime) {
559
+ logger.error('Cannot re-register a Workbox instance after it has ' + 'been registered. Create a new instance instead.');
560
+ return;
561
+ }
562
+ }
563
+
564
+ if (!immediate && document.readyState !== 'complete') {
565
+ await new Promise(res => window.addEventListener('load', res));
566
+ } // Set this flag to true if any service worker was controlling the page
567
+ // at registration time.
568
+
569
+
570
+ this._isUpdate = Boolean(navigator.serviceWorker.controller); // Before registering, attempt to determine if a SW is already controlling
571
+ // the page, and if that SW script (and version, if specified) matches this
572
+ // instance's script.
573
+
574
+ this._compatibleControllingSW = this._getControllingSWIfCompatible();
575
+ this._registration = await this._registerScript(); // If we have a compatible controller, store the controller as the "own"
576
+ // SW, resolve active/controlling deferreds and add necessary listeners.
577
+
578
+ if (this._compatibleControllingSW) {
579
+ this._sw = this._compatibleControllingSW;
580
+
581
+ this._activeDeferred.resolve(this._compatibleControllingSW);
582
+
583
+ this._controllingDeferred.resolve(this._compatibleControllingSW);
584
+
585
+ this._compatibleControllingSW.addEventListener('statechange', this._onStateChange, {
586
+ once: true
587
+ });
588
+ } // If there's a waiting service worker with a matching URL before the
589
+ // `updatefound` event fires, it likely means that this site is open
590
+ // in another tab, or the user refreshed the page (and thus the previous
591
+ // page wasn't fully unloaded before this page started loading).
592
+ // https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#waiting
593
+
594
+
595
+ const waitingSW = this._registration.waiting;
596
+
597
+ if (waitingSW && urlsMatch(waitingSW.scriptURL, this._scriptURL)) {
598
+ // Store the waiting SW as the "own" Sw, even if it means overwriting
599
+ // a compatible controller.
600
+ this._sw = waitingSW; // Run this in the next microtask, so any code that adds an event
601
+ // listener after awaiting `register()` will get this event.
602
+
603
+ dontWaitFor(Promise.resolve().then(() => {
604
+ this.dispatchEvent(new WorkboxEvent('waiting', {
605
+ sw: waitingSW,
606
+ wasWaitingBeforeRegister: true
607
+ }));
608
+
609
+ {
610
+ logger.warn('A service worker was already waiting to activate ' + 'before this script was registered...');
611
+ }
612
+ }));
613
+ } // If an "own" SW is already set, resolve the deferred.
614
+
615
+
616
+ if (this._sw) {
617
+ this._swDeferred.resolve(this._sw);
618
+
619
+ this._ownSWs.add(this._sw);
620
+ }
621
+
622
+ {
623
+ logger.log('Successfully registered service worker.', this._scriptURL);
624
+
625
+ if (navigator.serviceWorker.controller) {
626
+ if (this._compatibleControllingSW) {
627
+ logger.debug('A service worker with the same script URL ' + 'is already controlling this page.');
628
+ } else {
629
+ logger.debug('A service worker with a different script URL is ' + 'currently controlling the page. The browser is now fetching ' + 'the new script now...');
630
+ }
631
+ }
632
+
633
+ const currentPageIsOutOfScope = () => {
634
+ const scopeURL = new URL(this._registerOptions.scope || this._scriptURL, document.baseURI);
635
+ const scopeURLBasePath = new URL('./', scopeURL.href).pathname;
636
+ return !location.pathname.startsWith(scopeURLBasePath);
637
+ };
638
+
639
+ if (currentPageIsOutOfScope()) {
640
+ logger.warn('The current page is not in scope for the registered ' + 'service worker. Was this a mistake?');
641
+ }
642
+ }
643
+
644
+ this._registration.addEventListener('updatefound', this._onUpdateFound);
645
+
646
+ navigator.serviceWorker.addEventListener('controllerchange', this._onControllerChange, {
647
+ once: true
648
+ });
649
+ return this._registration;
650
+ }
651
+ /**
652
+ * Checks for updates of the registered service worker.
653
+ */
654
+
655
+
656
+ async update() {
657
+ if (!this._registration) {
658
+ {
659
+ logger.error('Cannot update a Workbox instance without ' + 'being registered. Register the Workbox instance first.');
660
+ }
661
+
662
+ return;
663
+ } // Try to update registration
664
+
665
+
666
+ await this._registration.update();
667
+ }
668
+ /**
669
+ * Resolves to the service worker registered by this instance as soon as it
670
+ * is active. If a service worker was already controlling at registration
671
+ * time then it will resolve to that if the script URLs (and optionally
672
+ * script versions) match, otherwise it will wait until an update is found
673
+ * and activates.
674
+ *
675
+ * @return {Promise<ServiceWorker>}
676
+ */
677
+
678
+
679
+ get active() {
680
+ return this._activeDeferred.promise;
681
+ }
682
+ /**
683
+ * Resolves to the service worker registered by this instance as soon as it
684
+ * is controlling the page. If a service worker was already controlling at
685
+ * registration time then it will resolve to that if the script URLs (and
686
+ * optionally script versions) match, otherwise it will wait until an update
687
+ * is found and starts controlling the page.
688
+ * Note: the first time a service worker is installed it will active but
689
+ * not start controlling the page unless `clients.claim()` is called in the
690
+ * service worker.
691
+ *
692
+ * @return {Promise<ServiceWorker>}
693
+ */
694
+
695
+
696
+ get controlling() {
697
+ return this._controllingDeferred.promise;
698
+ }
699
+ /**
700
+ * Resolves with a reference to a service worker that matches the script URL
701
+ * of this instance, as soon as it's available.
702
+ *
703
+ * If, at registration time, there's already an active or waiting service
704
+ * worker with a matching script URL, it will be used (with the waiting
705
+ * service worker taking precedence over the active service worker if both
706
+ * match, since the waiting service worker would have been registered more
707
+ * recently).
708
+ * If there's no matching active or waiting service worker at registration
709
+ * time then the promise will not resolve until an update is found and starts
710
+ * installing, at which point the installing service worker is used.
711
+ *
712
+ * @return {Promise<ServiceWorker>}
713
+ */
714
+
715
+
716
+ async getSW() {
717
+ // If `this._sw` is set, resolve with that as we want `getSW()` to
718
+ // return the correct (new) service worker if an update is found.
719
+ return this._sw !== undefined ? this._sw : this._swDeferred.promise;
720
+ }
721
+ /**
722
+ * Sends the passed data object to the service worker registered by this
723
+ * instance (via [`getSW()`]{@link module:workbox-window.Workbox#getSW}) and resolves
724
+ * with a response (if any).
725
+ *
726
+ * A response can be set in a message handler in the service worker by
727
+ * calling `event.ports[0].postMessage(...)`, which will resolve the promise
728
+ * returned by `messageSW()`. If no response is set, the promise will never
729
+ * resolve.
730
+ *
731
+ * @param {Object} data An object to send to the service worker
732
+ * @return {Promise<Object>}
733
+ */
734
+
735
+
736
+ async messageSW(data) {
737
+ const sw = await this.getSW();
738
+ return messageSW(sw, data);
739
+ }
740
+ /**
741
+ * Checks for a service worker already controlling the page and returns
742
+ * it if its script URL matches.
743
+ *
744
+ * @private
745
+ * @return {ServiceWorker|undefined}
746
+ */
747
+
748
+
749
+ _getControllingSWIfCompatible() {
750
+ const controller = navigator.serviceWorker.controller;
751
+
752
+ if (controller && urlsMatch(controller.scriptURL, this._scriptURL)) {
753
+ return controller;
754
+ } else {
755
+ return undefined;
756
+ }
757
+ }
758
+ /**
759
+ * Registers a service worker for this instances script URL and register
760
+ * options and tracks the time registration was complete.
761
+ *
762
+ * @private
763
+ */
764
+
765
+
766
+ async _registerScript() {
767
+ try {
768
+ const reg = await navigator.serviceWorker.register(this._scriptURL, this._registerOptions); // Keep track of when registration happened, so it can be used in the
769
+ // `this._onUpdateFound` heuristic. Also use the presence of this
770
+ // property as a way to see if `.register()` has been called.
771
+
772
+ this._registrationTime = performance.now();
773
+ return reg;
774
+ } catch (error) {
775
+ {
776
+ logger.error(error);
777
+ } // Re-throw the error.
778
+
779
+
780
+ throw error;
781
+ }
782
+ }
783
+
784
+ }
785
+ // -----------------------------------------------------------------------
786
+
787
+ /**
788
+ * The `message` event is dispatched any time a `postMessage` is received.
789
+ *
790
+ * @event module:workbox-window.Workbox#message
791
+ * @type {WorkboxEvent}
792
+ * @property {*} data The `data` property from the original `message` event.
793
+ * @property {Event} originalEvent The original [`message`]{@link https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent}
794
+ * event.
795
+ * @property {string} type `message`.
796
+ * @property {Workbox} target The `Workbox` instance.
797
+ */
798
+
799
+ /**
800
+ * The `installed` event is dispatched if the state of a
801
+ * [`Workbox`]{@link module:workbox-window.Workbox} instance's
802
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
803
+ * changes to `installed`.
804
+ *
805
+ * Then can happen either the very first time a service worker is installed,
806
+ * or after an update to the current service worker is found. In the case
807
+ * of an update being found, the event's `isUpdate` property will be `true`.
808
+ *
809
+ * @event module:workbox-window.Workbox#installed
810
+ * @type {WorkboxEvent}
811
+ * @property {ServiceWorker} sw The service worker instance.
812
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
813
+ * event.
814
+ * @property {boolean|undefined} isUpdate True if a service worker was already
815
+ * controlling when this `Workbox` instance called `register()`.
816
+ * @property {string} type `installed`.
817
+ * @property {Workbox} target The `Workbox` instance.
818
+ */
819
+
820
+ /**
821
+ * The `waiting` event is dispatched if the state of a
822
+ * [`Workbox`]{@link module:workbox-window.Workbox} instance's
823
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
824
+ * changes to `installed` and then doesn't immediately change to `activating`.
825
+ * It may also be dispatched if a service worker with the same
826
+ * [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
827
+ * was already waiting when the [`register()`]{@link module:workbox-window.Workbox#register}
828
+ * method was called.
829
+ *
830
+ * @event module:workbox-window.Workbox#waiting
831
+ * @type {WorkboxEvent}
832
+ * @property {ServiceWorker} sw The service worker instance.
833
+ * @property {Event|undefined} originalEvent The original
834
+ * [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
835
+ * event, or `undefined` in the case where the service worker was waiting
836
+ * to before `.register()` was called.
837
+ * @property {boolean|undefined} isUpdate True if a service worker was already
838
+ * controlling when this `Workbox` instance called `register()`.
839
+ * @property {boolean|undefined} wasWaitingBeforeRegister True if a service worker with
840
+ * a matching `scriptURL` was already waiting when this `Workbox`
841
+ * instance called `register()`.
842
+ * @property {string} type `waiting`.
843
+ * @property {Workbox} target The `Workbox` instance.
844
+ */
845
+
846
+ /**
847
+ * The `controlling` event is dispatched if a
848
+ * [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
849
+ * fires on the service worker [container]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer}
850
+ * and the [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
851
+ * of the new [controller]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/controller}
852
+ * matches the `scriptURL` of the `Workbox` instance's
853
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}.
854
+ *
855
+ * @event module:workbox-window.Workbox#controlling
856
+ * @type {WorkboxEvent}
857
+ * @property {ServiceWorker} sw The service worker instance.
858
+ * @property {Event} originalEvent The original [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
859
+ * event.
860
+ * @property {boolean|undefined} isUpdate True if a service worker was already
861
+ * controlling when this service worker was registered.
862
+ * @property {string} type `controlling`.
863
+ * @property {Workbox} target The `Workbox` instance.
864
+ */
865
+
866
+ /**
867
+ * The `activated` event is dispatched if the state of a
868
+ * [`Workbox`]{@link module:workbox-window.Workbox} instance's
869
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
870
+ * changes to `activated`.
871
+ *
872
+ * @event module:workbox-window.Workbox#activated
873
+ * @type {WorkboxEvent}
874
+ * @property {ServiceWorker} sw The service worker instance.
875
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
876
+ * event.
877
+ * @property {boolean|undefined} isUpdate True if a service worker was already
878
+ * controlling when this `Workbox` instance called `register()`.
879
+ * @property {string} type `activated`.
880
+ * @property {Workbox} target The `Workbox` instance.
881
+ */
882
+
883
+ /**
884
+ * The `redundant` event is dispatched if the state of a
885
+ * [`Workbox`]{@link module:workbox-window.Workbox} instance's
886
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
887
+ * changes to `redundant`.
888
+ *
889
+ * @event module:workbox-window.Workbox#redundant
890
+ * @type {WorkboxEvent}
891
+ * @property {ServiceWorker} sw The service worker instance.
892
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
893
+ * event.
894
+ * @property {boolean|undefined} isUpdate True if a service worker was already
895
+ * controlling when this `Workbox` instance called `register()`.
896
+ * @property {string} type `redundant`.
897
+ * @property {Workbox} target The `Workbox` instance.
898
+ */
899
+
900
+ /**
901
+ * The `externalinstalled` event is dispatched if the state of an
902
+ * [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}
903
+ * changes to `installed`.
904
+ *
905
+ * @event module:workbox-window.Workbox#externalinstalled
906
+ * @type {WorkboxEvent}
907
+ * @property {ServiceWorker} sw The service worker instance.
908
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
909
+ * event.
910
+ * @property {string} type `externalinstalled`.
911
+ * @property {Workbox} target The `Workbox` instance.
912
+ */
913
+
914
+ /**
915
+ * The `externalwaiting` event is dispatched if the state of an
916
+ * [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}
917
+ * changes to `waiting`.
918
+ *
919
+ * @event module:workbox-window.Workbox#externalwaiting
920
+ * @type {WorkboxEvent}
921
+ * @property {ServiceWorker} sw The service worker instance.
922
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
923
+ * event.
924
+ * @property {string} type `externalwaiting`.
925
+ * @property {Workbox} target The `Workbox` instance.
926
+ */
927
+
928
+ /**
929
+ * The `externalactivated` event is dispatched if the state of an
930
+ * [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}
931
+ * changes to `activated`.
932
+ *
933
+ * @event module:workbox-window.Workbox#externalactivated
934
+ * @type {WorkboxEvent}
935
+ * @property {ServiceWorker} sw The service worker instance.
936
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
937
+ * event.
938
+ * @property {string} type `externalactivated`.
939
+ * @property {Workbox} target The `Workbox` instance.
940
+ */
941
+
942
+ export { Workbox, messageSW };
943
+ //# sourceMappingURL=workbox-window.dev.mjs.map