Skip to content

Commit f000b86

Browse files
committed
docs: activate service worker immediately, serve network first
1 parent 91c4392 commit f000b86

16 files changed

+221
-284
lines changed

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"version": "node scripts/confirm-npm-tag.js",
2424
"prepare": "node scripts/post-install.js",
2525
"postversion": "node scripts/post-release-merge.js",
26-
"postinstall": "patch-package",
2726
"clean": "lerna clean",
2827
"changelog": "conventional-changelog -u -p vuetify",
2928
"all-checks": "yarn lint && lerna run test && lerna run cy:run && yarn build"

packages/docs/src/App.vue

-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<template>
2-
<v-progress-linear v-if="pwa.loading" indeterminate color="primary" height="3" class="pwa-loader" />
32
<router-view />
43
</template>
54

@@ -14,7 +13,6 @@
1413
// Stores
1514
import { useAuthStore } from '@/store/auth'
1615
import { useUserStore } from '@/store/user'
17-
import { usePwaStore } from '@/store/pwa'
1816
1917
// Utilities
2018
import { computed, nextTick, onBeforeMount, ref, watch, watchEffect } from 'vue'
@@ -25,7 +23,6 @@
2523
import { IN_BROWSER } from '@/util/globals'
2624
2725
const user = useUserStore()
28-
const pwa = usePwaStore()
2926
const router = useRouter()
3027
const route = useRoute()
3128
const theme = useTheme()

packages/docs/src/components/app/PwaSnackbar.vue

-38
This file was deleted.

packages/docs/src/components/app/settings/Options.vue

-3
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818

1919
<api-option />
2020

21-
<pwa-option />
22-
2321
<slash-search-option />
2422

2523
<sync-option />
@@ -30,7 +28,6 @@
3028
// Components
3129
import ApiOption from '@/components/app/settings/options/ApiOption.vue'
3230
import CodeOption from '@/components/app/settings/options/CodeOption.vue'
33-
import PwaOption from '@/components/app/settings/options/PwaOption.vue'
3431
import SettingsHeader from '@/components/app/settings/SettingsHeader.vue'
3532
import SlashSearchOption from '@/components/app/settings/options/SlashSearchOption.vue'
3633
import SyncOption from '@/components/app/settings/options/SyncOption.vue'

packages/docs/src/components/app/settings/options/PwaOption.vue

-24
This file was deleted.

packages/docs/src/i18n/messages/en.json

-6
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,6 @@
232232
"progress": "Progress",
233233
"providers": "Providers",
234234
"published": "Published: {date}",
235-
"pwa": {
236-
"install": "Install Vuetify Documentation",
237-
"new-content-available": "New content is available. Click **Refresh** to update.",
238-
"refresh": "Refresh",
239-
"ignore": "Don't ask again"
240-
},
241235
"range": "Range",
242236
"read": "View Read ({number})",
243237
"ready-text": "Continue your learning with related content selected by the {team} or move between pages by using the navigation links below.",

packages/docs/src/layouts/404.vue

-11
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,13 @@
2929
</template>
3030

3131
<script setup lang="ts">
32-
import { onMounted } from 'vue'
3332
import { useRoute } from 'vue-router'
3433
import { rpath } from '@/util/routes'
35-
import { usePwaStore } from '@/store/pwa'
3634
import { useHead } from '@vueuse/head'
3735
import DefaultLayout from '@/layouts/default.vue'
3836
3937
const route = useRoute()
40-
const pwa = usePwaStore()
4138
useHead({
4239
title: 'Page not found',
4340
})
44-
45-
onMounted(async () => {
46-
const sw = await navigator.serviceWorker?.getRegistration()
47-
await sw?.update()
48-
if (sw?.waiting) {
49-
pwa.update()
50-
}
51-
})
5241
</script>

packages/docs/src/layouts/default.vue

-3
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212

1313
<app-back-to-top />
1414

15-
<app-pwa-snackbar />
16-
1715
<v-main>
1816
<slot>
1917
<v-container
@@ -45,7 +43,6 @@
4543
import AppDrawer from '@/components/app/drawer/Drawer.vue'
4644
import AppSettingsDrawer from '@/components/app/settings/Drawer.vue'
4745
import AppToc from '@/components/app/Toc.vue'
48-
import AppPwaSnackbar from '@/components/app/PwaSnackbar.vue'
4946
5047
// Composables
5148
import { useRoute } from 'vue-router'

packages/docs/src/layouts/user.vue

-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88

99
<app-drawer />
1010

11-
<app-pwa-snackbar />
12-
1311
<v-main>
1412
<slot>
1513
<v-container
@@ -52,7 +50,6 @@
5250
import AppBar from '@/components/app/bar/Bar.vue'
5351
import AppDrawer from '@/components/app/drawer/Drawer.vue'
5452
import AppSettingsDrawer from '@/components/app/settings/Drawer.vue'
55-
import AppPwaSnackbar from '@/components/app/PwaSnackbar.vue'
5653
import UserProfile from '@/components/user/UserProfile.vue'
5754
import UserTabs from '@/components/user/UserTabs.vue'
5855

packages/docs/src/main.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,18 @@ router.afterEach((to, from) => {
131131
setTimeout(() => window.location.reload(), 100)
132132
}
133133
})
134-
router.onError(err => {
135-
console.error(err)
134+
router.onError((err, to) => {
135+
if (err?.message?.includes?.('Failed to fetch dynamically imported module')) {
136+
if (!localStorage.getItem('vuetify:dynamic-reload')) {
137+
console.log('Reloading page to fix dynamic import error')
138+
localStorage.setItem('vuetify:dynamic-reload', 'true')
139+
location.assign(to.fullPath)
140+
} else {
141+
console.error('Dynamic import error, reloading page did not fix it', err)
142+
}
143+
} else {
144+
console.error(err)
145+
}
136146
})
137147

138148
installGlobalComponents(app)
@@ -144,5 +154,6 @@ installPinia(app, router)
144154
installVuetify(app)
145155

146156
router.isReady().then(() => {
157+
localStorage.removeItem('vuetify:dynamic-reload')
147158
app.mount('#app')
148159
})

packages/docs/src/plugins/pwa.ts

+11-49
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,26 @@
1-
// Stores
2-
import { usePwaStore } from '@/store/pwa'
3-
import { useUserStore } from '@/store/user'
4-
51
// Types
62
import type { Router } from 'vue-router'
73

84
export async function installPwa (router: Router) {
9-
const { registerSW } = await import('virtual:pwa-register')
10-
115
await router.isReady()
126

13-
const pwa = usePwaStore()
14-
const user = useUserStore()
15-
pwa.updateSW = registerSW({
16-
async onNeedRefresh () {
17-
const registration = await navigator.serviceWorker?.getRegistration()
18-
if (registration?.active && registration?.waiting) {
19-
const manifest = await messageSW(registration.active, { type: 'GET_MANIFEST' })
20-
await messageSW(registration.waiting, { type: 'SET_MANIFEST', manifest })
21-
}
7+
let pendingUpdate = false
8+
if ('serviceWorker' in navigator) {
9+
navigator.serviceWorker.addEventListener('controllerchange', async () => {
10+
pendingUpdate = true
11+
})
12+
}
2213

23-
if (user.pwaRefresh) pwa.snackbar = true
24-
},
25-
})
26-
27-
let registration: ServiceWorkerRegistration | undefined
2814
router.beforeEach(async (to, from) => {
2915
if (to.path !== from.path) {
16+
if (pendingUpdate) {
17+
console.log('Reloading page to update service worker')
18+
window.location.pathname = to.fullPath
19+
}
20+
3021
navigator.serviceWorker?.getRegistration().then(reg => {
31-
registration = reg
3222
reg?.update()
3323
})
34-
35-
if (!user.pwaRefresh && registration?.active && registration?.waiting) {
36-
pwa.loading = true
37-
const promise = new Promise<void>(resolve => {
38-
registration!.waiting?.addEventListener('statechange', e => {
39-
const sw = e.target as ServiceWorker
40-
console.log('SW state change:', sw.state)
41-
if (sw.state === 'activated') {
42-
window.location.pathname = to.fullPath
43-
resolve()
44-
} else if (sw.state === 'redundant') {
45-
resolve()
46-
}
47-
})
48-
})
49-
await messageSW(registration.waiting, { type: 'SKIP_WAITING' })
50-
await promise
51-
}
52-
}
53-
})
54-
}
55-
56-
function messageSW (sw: ServiceWorker, data: {}): Promise<any> {
57-
return new Promise(resolve => {
58-
const messageChannel = new MessageChannel()
59-
messageChannel.port1.onmessage = (event: MessageEvent) => {
60-
resolve(event.data)
6124
}
62-
sw.postMessage(data, [messageChannel.port2])
6325
})
6426
}

0 commit comments

Comments
 (0)