diff --git a/src/index.tsx b/src/index.tsx index 805847f1..e4d9abd2 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -21,25 +21,30 @@ import './app/i18n'; document.body.classList.add(configClass, varsClass); settings.applyTheme(); -// Register Service Worker -if ('serviceWorker' in navigator) { - const swUrl = - import.meta.env.MODE === 'production' - ? `${trimTrailingSlash(import.meta.env.BASE_URL)}/sw.js` - : `/dev-sw.js?dev-sw`; +const registerServiceWorker = async () => { + if ('serviceWorker' in navigator) { + const swUrl = + import.meta.env.MODE === 'production' + ? `${trimTrailingSlash(import.meta.env.BASE_URL)}/sw.js` + : `/dev-sw.js?dev-sw`; - navigator.serviceWorker.register(swUrl); - navigator.serviceWorker.addEventListener('message', (event) => { - if (event.data?.type === 'token' && event.data?.responseKey) { - // Get the token for SW. - const token = localStorage.getItem('cinny_access_token') ?? undefined; - event.source!.postMessage({ - responseKey: event.data.responseKey, - token, + await navigator.serviceWorker.register(swUrl); + + navigator.serviceWorker.ready.then((registration) => { + navigator.serviceWorker.addEventListener('message', (event) => { + if (event.data?.type === 'token' && event.data?.messageId) { + const token = localStorage.getItem('cinny_access_token') ?? undefined; + registration.active?.postMessage({ + messageId: event.data.messageId, + token, + }); + } }); - } - }); -} + }); + } +}; + +window.addEventListener('load', registerServiceWorker); const mountApp = () => { const rootContainer = document.getElementById('root'); diff --git a/src/sw.ts b/src/sw.ts index 11f7f8b2..60ec9ab4 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -3,16 +3,26 @@ export type {}; declare const self: ServiceWorkerGlobalScope; +type Message = { messageId: string }; +type MessageListener = (message: Message) => void; +const messageListeners = new Map(); + +self.addEventListener('message', (event) => { + const { messageId } = event.data; + if (typeof messageId === 'string') { + messageListeners.get(messageId)?.(event.data); + messageListeners.delete(messageId); + } +}); + +type TokenMessage = Message & { + token?: string; +}; async function askForAccessToken(client: Client): Promise { return new Promise((resolve) => { - const responseKey = Math.random().toString(36); - const listener = (event: ExtendableMessageEvent) => { - if (event.data.responseKey !== responseKey) return; - resolve(event.data.token); - self.removeEventListener('message', listener); - }; - self.addEventListener('message', listener); - client.postMessage({ responseKey, type: 'token' }); + const messageId = Math.random().toString(36); + messageListeners.set(messageId, (message: TokenMessage) => resolve(message.token)); + client.postMessage({ messageId, type: 'token' }); }); }