Skip to content

Commit 0a6c543

Browse files
authored
feat: add SW stub (#368)
1 parent cd28922 commit 0a6c543

File tree

3 files changed

+19
-270
lines changed

3 files changed

+19
-270
lines changed

web/public/service-worker.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Self-destructible service worker stub to self-destruct old broken v1 SW
2+
3+
self.addEventListener('install', function(e) {
4+
self.skipWaiting();
5+
})
6+
7+
self.addEventListener('activate', function(e) {
8+
self.registration.unregister()
9+
.then(function () {
10+
return self.clients.matchAll();
11+
})
12+
.then(function (clients) {
13+
clients.forEach(client => {
14+
if (client instanceof WindowClient) {
15+
client.navigate(client.url)
16+
}
17+
})
18+
});
19+
})

web/src/service-worker.ts

Lines changed: 0 additions & 107 deletions
This file was deleted.

web/src/serviceWorkerRegistration.ts

Lines changed: 0 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,4 @@
11
/// <reference types="node" />
2-
// This optional code is used to register a service worker.
3-
// register() is not called by default.
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 subsequent visits to a page, after all the
8-
// existing tabs open on the page have been closed, since previously cached
9-
// resources are updated in the background.
10-
11-
// To learn more about the benefits of this model and instructions on how to
12-
// opt-in, read https://cra.link/PWA
13-
import { trimSuffix } from './utils/path'
14-
15-
const BASE_URL = trimSuffix(import.meta.env.BASE_URL, '/')
16-
17-
const isLocalhost = Boolean(
18-
window.location.hostname === 'localhost' ||
19-
// [::1] is the IPv6 localhost address.
20-
window.location.hostname === '[::1]' ||
21-
// 127.0.0.0/8 are considered localhost for IPv4.
22-
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/),
23-
)
24-
25-
interface Config {
26-
onSuccess?: (registration: ServiceWorkerRegistration) => void
27-
onUpdate?: (registration: ServiceWorkerRegistration) => void
28-
}
29-
30-
export function register(config?: Config) {
31-
if (import.meta.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
32-
// The URL constructor is available in all browsers that support SW.
33-
const publicUrl = new URL(BASE_URL, window.location.href)
34-
if (publicUrl.origin !== window.location.origin) {
35-
// Our service worker won't work if BASE_URL is on a different origin
36-
// from what our page is served on. This might happen if a CDN is used to
37-
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
38-
return
39-
}
40-
41-
window.addEventListener('load', () => {
42-
const swUrl = `${BASE_URL}/service-worker.js`
43-
44-
if (isLocalhost) {
45-
// This is running on localhost. Let's check if a service worker still exists or not.
46-
checkValidServiceWorker(swUrl, config)
47-
48-
// Add some additional logging to localhost, pointing developers to the
49-
// service worker/PWA documentation.
50-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
51-
navigator.serviceWorker.ready.then((reg) => {
52-
console.log(
53-
'This web app is being served cache-first by a service ' +
54-
'worker. To learn more, visit https://cra.link/PWA',
55-
)
56-
reg.update().catch((err) => {
57-
console.error('Failed to update service worker: ', err)
58-
})
59-
})
60-
} else {
61-
// Is not localhost. Just register service worker
62-
registerValidSW(swUrl, config)
63-
}
64-
})
65-
}
66-
}
67-
68-
/**
69-
* Manually registers service worker
70-
*
71-
* @param config
72-
*/
73-
export function manualRegister(config?: Config) {
74-
if (import.meta.env.DEV) {
75-
return
76-
}
77-
if (!('serviceWorker' in navigator)) {
78-
return
79-
}
80-
81-
const publicUrl = new URL(BASE_URL, window.location.href)
82-
if (publicUrl.origin !== window.location.origin) {
83-
return
84-
}
85-
86-
const swUrl = `${BASE_URL}/service-worker.js`
87-
if (isLocalhost) {
88-
checkValidServiceWorker(swUrl, config)
89-
return
90-
}
91-
92-
registerValidSW(swUrl, config)
93-
}
94-
95-
function registerValidSW(swUrl: string, config?: Config) {
96-
navigator.serviceWorker
97-
.register(swUrl)
98-
.then((registration) => {
99-
registration.onupdatefound = () => {
100-
const installingWorker = registration.installing
101-
if (installingWorker == null) {
102-
return
103-
}
104-
installingWorker.onstatechange = () => {
105-
if (installingWorker.state === 'installed') {
106-
if (navigator.serviceWorker.controller) {
107-
// At this point, the updated precached content has been fetched,
108-
// but the previous service worker will still serve the older
109-
// content until all client tabs are closed.
110-
console.log(
111-
'New content is available and will be used when all ' +
112-
'tabs for this page are closed. See https://cra.link/PWA.',
113-
)
114-
115-
// Execute callback
116-
if (config?.onUpdate) {
117-
config.onUpdate(registration)
118-
}
119-
} else {
120-
// At this point, everything has been precached.
121-
// It's the perfect time to display a
122-
// "Content is cached for offline use." message.
123-
console.log('Content is cached for offline use.')
124-
125-
// Execute callback
126-
if (config?.onSuccess) {
127-
config.onSuccess(registration)
128-
}
129-
}
130-
}
131-
}
132-
}
133-
})
134-
.catch((error) => {
135-
console.error('Error during service worker registration:', error)
136-
})
137-
}
138-
139-
function checkValidServiceWorker(swUrl: string, config?: Config) {
140-
// Check if the service worker can be found. If it can't reload the page.
141-
fetch(swUrl, {
142-
headers: { 'Service-Worker': 'script' },
143-
})
144-
.then((response) => {
145-
// Ensure service worker exists, and that we really are getting a JS file.
146-
const contentType = response.headers.get('content-type')
147-
if (response.status === 404 || (contentType != null && !contentType.includes('javascript'))) {
148-
// No service worker found. Probably a different app. Reload the page.
149-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
150-
navigator.serviceWorker.ready.then((registration) => {
151-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
152-
registration.unregister().then(() => {
153-
window.location.reload()
154-
})
155-
})
156-
} else {
157-
// Service worker found. Proceed as normal.
158-
registerValidSW(swUrl, config)
159-
}
160-
})
161-
.catch(() => {
162-
console.log('No internet connection found. App is running in offline mode.')
163-
})
164-
}
1652

1663
export function unregister() {
1674
if ('serviceWorker' in navigator) {

0 commit comments

Comments
 (0)