11'use strict' ;
22
3+ // In production, we register a service worker to serve assets from local cache.
4+
5+ // This lets the app load faster on subsequent visits in production, and gives
6+ // it offline capabilities. However, it also means that developers (and users)
7+ // will only see deployed updates on the "N+1" visit to a page, since previously
8+ // cached resources are updated in the background.
9+
10+ // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
11+
312/**
413 * The default register service worker function
14+ * @returns {AppServiceWorker }
515 */
616function registerServiceWorker ( ) {
7- // TODO
17+ return AppServiceWorker . getInstance ( )
18+ }
19+
20+ /**
21+ * App Service Worker Class
22+ *
23+ * @export
24+ * @class AppServiceWorker
25+ */
26+ export class AppServiceWorker {
27+ /**
28+ * Creates an instance of AppServiceWorker.
29+ *
30+ * @memberof AppServiceWorker
31+ */
32+ constructor ( ) {
33+
34+ this . isLocalhost = Boolean (
35+ window . location . hostname === "localhost" ||
36+ // [::1] is the IPv6 localhost address.
37+ window . location . hostname === "[::1]" ||
38+ // 127.0.0.1/8 is considered localhost for IPv4.
39+ window . location . hostname . match (
40+ / ^ 1 2 7 (?: \. (?: 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] [ 0 - 9 ] | [ 0 1 ] ? [ 0 - 9 ] [ 0 - 9 ] ? ) ) { 3 } $ /
41+ )
42+ ) ;
43+
44+ this . installPromise = new Promise ( resolve => this . installPromiseResolver = resolve )
45+ this . updatePromise = new Promise ( resolve => this . updatePromiseResolver = resolve )
46+
47+ this . onUpdateFound ( ( ) => console . log ( "New content is available; please refresh." ) )
48+ this . onInstalled ( ( ) => console . log ( "Content is cached for offline use." ) )
49+
50+ }
51+ /**
52+ * Register the service worker
53+ *
54+ * @returns
55+ * @memberof AppServiceWorker
56+ */
57+ register ( ) {
58+ if ( process . env . NODE_ENV === "production" && "serviceWorker" in navigator ) {
59+ // The URL constructor is available in all browsers that support SW.
60+ const publicUrl = new URL ( process . env . PUBLIC_URL , window . location ) ;
61+ if ( publicUrl . origin !== window . location . origin ) {
62+ // Our service worker won't work if PUBLIC_URL is on a different origin
63+ // from what our page is served on. This might happen if a CDN is used to
64+ // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
65+ return ;
66+ }
67+
68+ window . addEventListener ( "load" , ( ) => {
69+ const swUrl = `${ process . env . PUBLIC_URL } /service-worker.js` ;
70+
71+ if ( this . isLocalhost ) {
72+ // This is running on localhost. Lets check if a service worker still exists or not.
73+ this . checkValidServiceWorker ( swUrl ) ;
74+
75+ // Add some additional logging to localhost, pointing developers to the
76+ // service worker/PWA documentation.
77+ navigator . serviceWorker . ready . then ( ( ) => {
78+ console . log (
79+ "This web app is being served cache-first by a service " +
80+ "worker. To learn more, visit https://goo.gl/SC7cgQ"
81+ ) ;
82+ } ) ;
83+ } else {
84+ // Is not local host. Just register service worker
85+ this . registerValidSW ( swUrl ) ;
86+ }
87+ } ) ;
88+ }
89+ return this
90+ }
91+
92+ registerValidSW ( swUrl ) {
93+
94+ navigator . serviceWorker
95+ . register ( swUrl )
96+ . then ( registration => {
97+
98+ registration . onupdatefound = ( ) => {
99+ const installingWorker = registration . installing ;
100+ installingWorker . onstatechange = ( ) => {
101+ if ( installingWorker . state === "installed" ) {
102+ if ( navigator . serviceWorker . controller ) {
103+ // At this point, the old content will have been purged and
104+ // the fresh content will have been added to the cache.
105+ // It's the perfect time to display a "New content is
106+ // available; please refresh." message in your web app.
107+ this . updatePromiseResolver ( )
108+ } else {
109+ // At this point, everything has been precached.
110+ // It's the perfect time to display a
111+ // "Content is cached for offline use." message.
112+ this . installPromiseResolver ( )
113+ }
114+ }
115+ } ;
116+ } ;
117+ } )
118+ . catch ( error => {
119+ console . error ( "Error during service worker registration:" , error ) ;
120+ } ) ;
121+ }
122+
123+ checkValidServiceWorker ( swUrl ) {
124+ // Check if the service worker can be found. If it can't reload the page.
125+ fetch ( swUrl )
126+ . then ( response => {
127+ // Ensure service worker exists, and that we really are getting a JS file.
128+ if (
129+ response . status === 404 ||
130+ response . headers . get ( "content-type" ) . indexOf ( "javascript" ) === - 1
131+ ) {
132+ // No service worker found. Probably a different app. Reload the page.
133+ navigator . serviceWorker . ready . then ( registration => {
134+ registration . unregister ( ) . then ( ( ) => {
135+ window . location . reload ( ) ;
136+ } ) ;
137+ } ) ;
138+ } else {
139+ // Service worker found. Proceed as normal.
140+ this . registerValidSW ( swUrl ) ;
141+ }
142+ } )
143+ . catch ( ( ) => {
144+ console . log (
145+ "No internet connection found. App is running in offline mode."
146+ ) ;
147+ } ) ;
148+ }
149+
150+ unregister ( ) {
151+ if ( "serviceWorker" in navigator ) {
152+ navigator . serviceWorker . ready . then ( registration => {
153+ registration . unregister ( ) ;
154+ } ) ;
155+ }
156+ }
157+
158+ onInstalled ( callback ) {
159+ this . installPromise . then ( callback ) . catch ( console . error )
160+
161+ }
162+
163+ onUpdateFound ( callback ) {
164+ this . updatePromise . then ( callback ) . catch ( console . error )
165+ }
166+
167+ static getInstance ( ) {
168+ return this . instance ? this . instance : this . instance = new this ( ) . register ( )
169+ }
8170}
9171
10- export default registerServiceWorker ;
172+ export default registerServiceWorker ;
0 commit comments