From e26b80696500e3ab2d3f24871dde9358c29f71c7 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 2 Jul 2024 15:53:30 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(service-worker)=20networkFirst=20o?= =?UTF-8?q?n=20api=20request?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some api requests were served by the cache first, which caused the data to be outdated. This change makes sure that the api requests are always served by the network first. --- .../src/features/service-worker/conf.ts | 11 ++++++++++ .../service-worker/service-worker-api.ts | 22 ++++++++++++++++--- .../features/service-worker/service-worker.ts | 15 ++++--------- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/frontend/apps/impress/src/features/service-worker/conf.ts b/src/frontend/apps/impress/src/features/service-worker/conf.ts index de6b240f..fe4ba15e 100644 --- a/src/frontend/apps/impress/src/features/service-worker/conf.ts +++ b/src/frontend/apps/impress/src/features/service-worker/conf.ts @@ -1,5 +1,16 @@ +import pkg from '@/../package.json'; + export const SW_DEV_URL = [ 'http://localhost:3000', 'https://impress.127.0.0.1.nip.io', 'https://impress-staging.beta.numerique.gouv.fr', ]; + +export const SW_DEV_API = 'http://localhost:8071'; + +export const SW_VERSION = `v-${process.env.NEXT_PUBLIC_BUILD_ID}`; + +export const DAYS_EXP = 5; + +export const getCacheNameVersion = (cacheName: string) => + `${pkg.name}-${cacheName}-${SW_VERSION}`; diff --git a/src/frontend/apps/impress/src/features/service-worker/service-worker-api.ts b/src/frontend/apps/impress/src/features/service-worker/service-worker-api.ts index f531ec08..c2636314 100644 --- a/src/frontend/apps/impress/src/features/service-worker/service-worker-api.ts +++ b/src/frontend/apps/impress/src/features/service-worker/service-worker-api.ts @@ -1,9 +1,12 @@ +import { CacheableResponsePlugin } from 'workbox-cacheable-response'; +import { ExpirationPlugin } from 'workbox-expiration'; import { registerRoute } from 'workbox-routing'; -import { NetworkOnly } from 'workbox-strategies'; +import { NetworkFirst, NetworkOnly } from 'workbox-strategies'; import { ApiPlugin } from './ApiPlugin'; import { DocsDB } from './DocsDB'; import { SyncManager } from './SyncManager'; +import { DAYS_EXP, SW_DEV_API, getCacheNameVersion } from './conf'; declare const self: ServiceWorkerGlobalScope; @@ -14,10 +17,9 @@ self.addEventListener('activate', function (event) { }); export const isApiUrl = (href: string) => { - const devDomain = 'http://localhost:8071'; return ( href.includes(`${self.location.origin}/api/`) || - href.includes(`${devDomain}/api/`) + href.includes(`${SW_DEV_API}/api/`) ); }; @@ -91,3 +93,17 @@ registerRoute( }), 'DELETE', ); + +registerRoute( + ({ url }) => isApiUrl(url.href), + new NetworkFirst({ + cacheName: getCacheNameVersion('api'), + plugins: [ + new CacheableResponsePlugin({ statuses: [0, 200] }), + new ExpirationPlugin({ + maxAgeSeconds: 24 * 60 * 60 * DAYS_EXP, + }), + ], + }), + 'GET', +); diff --git a/src/frontend/apps/impress/src/features/service-worker/service-worker.ts b/src/frontend/apps/impress/src/features/service-worker/service-worker.ts index a806726a..a3c30768 100644 --- a/src/frontend/apps/impress/src/features/service-worker/service-worker.ts +++ b/src/frontend/apps/impress/src/features/service-worker/service-worker.ts @@ -19,7 +19,7 @@ import { // eslint-disable-next-line import/order import { ApiPlugin } from './ApiPlugin'; -import { SW_DEV_URL } from './conf'; +import { DAYS_EXP, SW_DEV_URL, SW_VERSION, getCacheNameVersion } from './conf'; import { isApiUrl } from './service-worker-api'; // eslint-disable-next-line import/order @@ -31,16 +31,11 @@ declare const self: ServiceWorkerGlobalScope & { self.__WB_DISABLE_DEV_LOGS = true; -const version = `v-${process.env.NEXT_PUBLIC_BUILD_ID}`; - setCacheNameDetails({ prefix: pkg.name, - suffix: version, + suffix: SW_VERSION, }); -const getCacheNameVersion = (cacheName: string) => - `${pkg.name}-${cacheName}-${version}`; - /** * In development, use NetworkFirst strategy, in production use CacheFirst strategy * We will be able to test the application in development without having to clear the cache. @@ -53,7 +48,7 @@ const getStrategy = ( ): NetworkFirst | CacheFirst => { return SW_DEV_URL.some((devDomain) => self.location.origin.includes(devDomain), - ) + ) || isApiUrl(self.location.href) ? new NetworkFirst(options) : new CacheFirst(options); }; @@ -66,7 +61,7 @@ self.addEventListener('install', function (event) { }); self.addEventListener('activate', function (event) { - const cacheAllow = `${version}`; + const cacheAllow = SW_VERSION; event.waitUntil( // Delete old caches @@ -135,8 +130,6 @@ setCatchHandler(async ({ request, url, event }) => { } }); -const DAYS_EXP = 5; - /** * Cache stategy static files images (images / svg) */