diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e2d2a05..95cfd33 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -31,7 +31,9 @@ "source-sans": "^3.46.0", "vue": "^3.4.11", "vue-i18n": "^9.13.1", - "vue-router": "^4.3.2" + "vue-router": "^4.3.2", + "workbox-core": "^7.1.0", + "workbox-precaching": "^7.1.0" }, "devDependencies": { "@types/node": "^20.12.12", @@ -8806,7 +8808,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==", - "dev": true + "license": "MIT" }, "node_modules/workbox-expiration": { "version": "7.1.0", @@ -8843,7 +8845,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.1.0.tgz", "integrity": "sha512-LyxzQts+UEpgtmfnolo0hHdNjoB7EoRWcF7EDslt+lQGd0lW4iTvvSe3v5JiIckQSB5KTW5xiCqjFviRKPj1zA==", - "dev": true, + "license": "MIT", "dependencies": { "workbox-core": "7.1.0", "workbox-routing": "7.1.0", @@ -8877,7 +8879,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.1.0.tgz", "integrity": "sha512-oOYk+kLriUY2QyHkIilxUlVcFqwduLJB7oRZIENbqPGeBP/3TWHYNNdmGNhz1dvKuw7aqvJ7CQxn27/jprlTdg==", - "dev": true, "dependencies": { "workbox-core": "7.1.0" } @@ -8886,7 +8887,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.1.0.tgz", "integrity": "sha512-/UracPiGhUNehGjRm/tLUQ+9PtWmCbRufWtV0tNrALuf+HZ4F7cmObSEK+E4/Bx1p8Syx2tM+pkIrvtyetdlew==", - "dev": true, "dependencies": { "workbox-core": "7.1.0" } diff --git a/frontend/package.json b/frontend/package.json index bd35f2f..7b4b4fc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -53,6 +53,8 @@ "vite": "^5.2.11", "vite-plugin-pwa": "^0.20.0", "vitest": "^1.6.0", - "vue-tsc": "^1.8.27" + "vue-tsc": "^1.8.27", + "workbox-core": "^7.1.0", + "workbox-precaching": "^7.1.0" } } diff --git a/frontend/public/sw.js b/frontend/public/sw.js new file mode 100644 index 0000000..a2616c3 --- /dev/null +++ b/frontend/public/sw.js @@ -0,0 +1,28 @@ +import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching'; +import { clientsClaim } from 'workbox-core'; + +self.skipWaiting(); +clientsClaim(); + +cleanupOutdatedCaches(); + +// Precache the files from the manifest +precacheAndRoute(self.__WB_MANIFEST); + +// Custom precaching logic for the /api/modules endpoint +self.addEventListener('install', (event) => { + event.waitUntil( + caches.open('api-modules-cache').then((cache) => { + return fetch('/api/modules') + .then((response) => { + if (response.ok) { + return cache.put('/api/modules', response); + } + throw new Error('Failed to fetch /api/modules'); + }) + .catch((error) => { + console.error('Precaching /api/modules failed:', error); + }); + }) + ); +}); diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 2eaf19d..087a244 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -28,7 +28,13 @@ export default defineConfig({ mode: "development", base: "/", injectRegister: "auto", - includeAssets: ["favicon.ico", "apple-touch-icon.png", "mask-icon.svg"], + includeAssets: [ + "favicon.ico", + "apple-touch-icon.png", + "mask-icon.svg", + "robots.txt", + "sitemap.xml" + ], manifest: { name: "HTWKalender", short_name: "HTWKalender", @@ -81,47 +87,6 @@ export default defineConfig({ ], }, registerType: "autoUpdate", - workbox: { - globPatterns: ["**/*.{js,css,html,ico,png,svg,json,vue,txt,woff2}"], - cleanupOutdatedCaches: true, - runtimeCaching: [ - { - urlPattern: ({ url }) => url.pathname.startsWith("/api/feed"), - method: "GET", - handler: "NetworkFirst", - options: { - cacheName: "calendar-feed-cache", - expiration: { - maxAgeSeconds: 12 * 60 * 60, // 12 hours - }, - }, - }, - { - // Add the runtime caching strategy for /api/modules - urlPattern: ({url}) => url.pathname.startsWith('/api/modules'), - method: 'GET', - handler: 'NetworkFirst', - options: { - cacheName: 'modules-cache', - expiration: { - maxAgeSeconds: 24 * 60 * 60, // 1 day - }, - }, - }, - { - urlPattern: /^https?.*/, - handler: "NetworkFirst", - options: { - cacheName: "https-calls", - expiration: { - maxEntries: 150, - maxAgeSeconds: 30 * 12 * 60 * 60, // 1 month - }, - networkTimeoutSeconds: 10, // fall back to cache if api does not response within 10 seconds - }, - }, - ], - }, devOptions: { enabled: true, /* when using generateSW the PWA plugin will switch to classic */ @@ -129,6 +94,7 @@ export default defineConfig({ navigateFallback: "index.html", suppressWarnings: true, }, + strategies: "injectManifest", }), ], resolve: {