Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SOK-31] Service Worker #19

Merged
merged 4 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/favicon.png" />
<link rel="manifest" href="/manifest.json">

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
Expand Down
15 changes: 15 additions & 0 deletions packages/client/public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"short_name": "FTanks",
"name": "Falcon Tanks",
"icons": [
{
"src": "./public/favicon.png",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
55 changes: 55 additions & 0 deletions packages/client/public/serviceWorker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const CACHE_NAME = 'cache-data-v1'
const urlsToCache = [
'/'
]

const networkFirst = async (request) => {
const cache = await caches.open(CACHE_NAME)
try {
const response = await fetch(request)
const cachePutCondition = response && response.status === 200 && response.type === 'basic'
if (cachePutCondition) {
await cache.put(request, response.clone())
}
return response
} catch (error) {
console.error('Fetch failed; returning cached page instead.', error)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Возможно не стоит это указывать в error. Ведь это поведение мы отлавливаем. И ожидаем, что такой сценарий может быть.

Возможно стоит warning или info использовать. Но не уверен.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут на ваше усмотрение. Консоль только разработчики открывают. Если так удобно, то окей.

В реальном же мире, на реальном продукте, тут будет отправка запроса в аналитику (раз интернета нет, то сохранение где-то в localStorage, а отправка уже при появлении инета), чтобы аналитики, да и разработчики могли отслеживать графики того, как часто у юзеров отваливается инет

const cachedResponse = await cache.match(request)
if (cachedResponse) {
return cachedResponse
}
return new Response('Network error happened', {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Выглядит так, что где-то тут приложение упадет, если пользователь не залогинен. Нам нужно как-то обработать сценарий, где пользователь попал на главую, приложение закешировалось, затем интернет отвалился. У пользователя должна остаться возможность хотябы попасть на главую.

Верхом будет, если закинуть ему тостер, что "Ваше интернет соединение не стабильно".

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Так смотри. Если после отвала интернета, пользователь заходит в приложение (на главную), то тут сработает сценарий на 19 строке. Он достанет страницу из кеша и отдаст. Так что тут всё хорошо в плане логики.

status: 503,
headers: { 'Content-Type': 'text/plain' },
})
}
}

self.addEventListener('install', (event) => {
event.waitUntil(
caches
.open(CACHE_NAME)
.then((cache) => {
return cache.addAll(urlsToCache)
})
.then(() => self.skipWaiting())
.catch((err) => {
console.error('Cache installation failed:', err)
})
)
})

self.addEventListener('fetch', (event) => {
const { request } = event
const { url, method } = request

if (method !== 'GET') {
return
}

if (!url.startsWith('http')) {
return
}

event.respondWith(networkFirst(request))
})
3 changes: 3 additions & 0 deletions packages/client/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ToastContainer } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css'
import App from './app/App'
import '@/scss/styles.scss'
import { registerServiceWorker } from './registerServiceWorker'

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
Expand All @@ -15,3 +16,5 @@ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
</Provider>
</React.StrictMode>
)

registerServiceWorker()
24 changes: 24 additions & 0 deletions packages/client/src/registerServiceWorker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const registerServiceWorker = () => {
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('./serviceWorker.js')
.then(
registration => {
console.log(
'ServiceWorker registration successful with scope: ',
registration.scope
)
},
err => {
throw new Error(`ServiceWorker registration failed: ${err}`)
}
)
.catch(err => {
throw new Error(err)
})
})
} else {
throw new Error('service worker is not supported')
}
}
9 changes: 9 additions & 0 deletions packages/client/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,13 @@ export default defineConfig({
},
plugins: [react()],
envDir: '../../',
build: {
outDir: 'dist',
rollupOptions: {
input: {
main: path.resolve(__dirname, 'index.html'),
serviceWorker: path.resolve(__dirname, 'public/serviceWorker.js'),
},
},
},
})
Loading