feat(pwa): ✨ add service worker and registration
This commit is contained in:
parent
8d7ad1dc2f
commit
c971542ec8
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
|
@ -17,7 +17,12 @@
|
||||||
"explorer.fileNesting.patterns": {
|
"explorer.fileNesting.patterns": {
|
||||||
"*.tsx": "${capture}.*"
|
"*.tsx": "${capture}.*"
|
||||||
},
|
},
|
||||||
"cSpell.words": ["technoshop", "Technoshop", "univoq"],
|
"cSpell.words": [
|
||||||
|
"startserviceworker",
|
||||||
|
"technoshop",
|
||||||
|
"Technoshop",
|
||||||
|
"univoq"
|
||||||
|
],
|
||||||
"cssvar.enable": true,
|
"cssvar.enable": true,
|
||||||
"cssvar.files": ["./_fresh/*"],
|
"cssvar.files": ["./_fresh/*"],
|
||||||
"conventionalCommits.scopes": ["css", "config", "ui", "pwa"],
|
"conventionalCommits.scopes": ["css", "config", "ui", "pwa"],
|
||||||
|
|
5
components/ProgressiveWebApp.tsx
Normal file
5
components/ProgressiveWebApp.tsx
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import RegisterServiceWorker from '../islands/RegisterServiceWorker.tsx'
|
||||||
|
|
||||||
|
export function ProgressiveWebApp() {
|
||||||
|
return <RegisterServiceWorker />
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
export default function RegisterServiceWorker({ href }: { href: string }) {
|
export default function RegisterServiceWorker() {
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
navigator.serviceWorker.register(href)
|
import('./StartServiceWorker.tsx').then((mod) => {
|
||||||
|
const href = mod.default()
|
||||||
|
navigator.serviceWorker.register(href, { scope: '/', type: 'module' })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return <></>
|
return <></>
|
||||||
|
|
10
islands/StartServiceWorker.tsx
Normal file
10
islands/StartServiceWorker.tsx
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { main } from '../src/serviceworker/mod.ts'
|
||||||
|
|
||||||
|
const IS_SW = 'onpushsubscriptionchange' in self
|
||||||
|
|
||||||
|
export default function StartServiceWorker() {
|
||||||
|
if (IS_SW) {
|
||||||
|
main()
|
||||||
|
}
|
||||||
|
return new URL(import.meta.url).pathname
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ import { asset, Head, Partial } from '$fresh/runtime.ts'
|
||||||
import { type PageProps } from '$fresh/server.ts'
|
import { type PageProps } from '$fresh/server.ts'
|
||||||
import { Footer } from '../components/Footer.tsx'
|
import { Footer } from '../components/Footer.tsx'
|
||||||
import { Header } from '../components/Header.tsx'
|
import { Header } from '../components/Header.tsx'
|
||||||
import RegisterServiceWorker from '../islands/RegisterServiceWorker.tsx'
|
import { ProgressiveWebApp } from '../components/ProgressiveWebApp.tsx'
|
||||||
|
|
||||||
export default function App({ Component }: PageProps) {
|
export default function App({ Component }: PageProps) {
|
||||||
return (
|
return (
|
||||||
|
@ -53,7 +53,7 @@ export default function App({ Component }: PageProps) {
|
||||||
<Component />
|
<Component />
|
||||||
</Partial>
|
</Partial>
|
||||||
</main>
|
</main>
|
||||||
<RegisterServiceWorker href={asset('/sw.js')} />
|
<ProgressiveWebApp />
|
||||||
<Footer />
|
<Footer />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
11
routes/_middleware.ts
Normal file
11
routes/_middleware.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { FreshContext } from '$fresh/server.ts'
|
||||||
|
|
||||||
|
export async function handler(request: Request, ctx: FreshContext) {
|
||||||
|
// Allow service worker to serve root scope
|
||||||
|
const response = await ctx.next()
|
||||||
|
const url = new URL(request.url)
|
||||||
|
if (url.pathname.endsWith('island-startserviceworker.js')) {
|
||||||
|
response.headers.set('Service-Worker-Allowed', '/')
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
31
src/serviceworker/mod.ts
Normal file
31
src/serviceworker/mod.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/// <reference no-default-lib="true"/>
|
||||||
|
/// <reference lib="webworker" />
|
||||||
|
|
||||||
|
// Force load service worker types
|
||||||
|
const self = globalThis as unknown as ServiceWorkerGlobalScope
|
||||||
|
|
||||||
|
const cacheName = 'v1' //TODO dynamique cache key
|
||||||
|
const _preCachedPaths = ['/', '/css/*', '/assets/*'] //TODO pre-cache these paths
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
self.addEventListener('install', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
addToCache([]),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
self.addEventListener('activate', () => {
|
||||||
|
console.log('sw activated')
|
||||||
|
})
|
||||||
|
|
||||||
|
self.addEventListener('fetch', (_event) => {
|
||||||
|
//TODO add fetch strategies
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function addToCache(ressources: string[]) {
|
||||||
|
const cache = await caches.open(cacheName) //TODO dynamique cache key
|
||||||
|
|
||||||
|
await cache.addAll(ressources)
|
||||||
|
|
||||||
|
//TODO list statics
|
||||||
|
}
|
Loading…
Reference in a new issue