Skip to content

Commit

Permalink
fix: config loading on subdomains waits for updated config
Browse files Browse the repository at this point in the history
  • Loading branch information
SgtPooki committed Mar 8, 2024
1 parent d3d9169 commit 1bae5f2
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 28 deletions.
13 changes: 8 additions & 5 deletions src/components/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { ConfigContext } from '../context/config-context.tsx'
import { HeliaServiceWorkerCommsChannel } from '../lib/channel.ts'
import { getConfig, loadConfigFromLocalStorage } from '../lib/config-db.ts'
import { LOCAL_STORAGE_KEYS } from '../lib/local-storage.ts'
import { Collapsible } from './collapsible'
import { trace } from '../lib/logger.ts'
import { Collapsible } from './collapsible.tsx'
import LocalStorageInput from './local-storage-input.tsx'
import { LocalStorageToggle } from './local-storage-toggle'
import { ServiceWorkerReadyButton } from './sw-ready-button.tsx'
Expand Down Expand Up @@ -47,14 +48,14 @@ export default (): JSX.Element | null => {
// TODO: why we need this origin here? where is targetOrigin used?
const targetOrigin = decodeURIComponent(window.location.hash.split('@origin=')[1])
const config = await getConfig()
// eslint-disable-next-line no-console
console.log('config-page: postMessage config to origin ', config, origin)
trace('config-page: postMessage config to origin ', config, origin)
/**
* The reload page in the parent window is listening for this message, and then it passes a RELOAD_CONFIG message to the service worker
*/
window.parent?.postMessage({ source: 'helia-sw-config-iframe', target: 'PARENT', action: 'RELOAD_CONFIG', config }, {
targetOrigin
})
trace('config-page: RELOAD_CONFIG sent to parent window')
}, [])

useEffect(() => {
Expand All @@ -67,9 +68,11 @@ export default (): JSX.Element | null => {
const saveConfig = useCallback(async () => {
try {
await loadConfigFromLocalStorage()
trace('config-page: sending RELOAD_CONFIG to service worker')
// update the BASE_URL service worker
// TODO: use channel.messageAndWaitForResponse to ensure that the config is loaded before proceeding.
channel.postMessage({ target: 'SW', action: 'RELOAD_CONFIG' })
await channel.messageAndWaitForResponse('SW', { target: 'SW', action: 'RELOAD_CONFIG' })
// base_domain service worker is updated
trace('config-page: RELOAD_CONFIG_SUCCESS')
// update the <subdomain>.<namespace>.BASE_URL service worker
await postFromIframeToParentSw()
setConfigExpanded(false)
Expand Down
1 change: 1 addition & 0 deletions src/lib/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export enum COLORS {

export enum ChannelActions {
RELOAD_CONFIG = 'RELOAD_CONFIG',
RELOAD_CONFIG_SUCCESS = 'RELOAD_CONFIG_SUCCESS'
}
13 changes: 2 additions & 11 deletions src/redirectPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,9 @@ export default function RedirectPage (): JSX.Element {
async function doWork (config: ConfigDb): Promise<void> {
try {
await setConfig(config)
// TODO: use channel.messageAndWaitForResponse to ensure that the config is loaded before proceeding.
channel.postMessage({ target: 'SW', action: 'RELOAD_CONFIG' })
await channel.messageAndWaitForResponse('SW', { target: 'SW', action: 'RELOAD_CONFIG' })
// try to preload the content
setTimeout(() => {
fetch(window.location.href, { method: 'GET' }).then((response) => {
// eslint-disable-next-line no-console
console.log('response', response)
}).catch((err) => {
// eslint-disable-next-line no-console
console.error('error fetching', err)
})
}, 500)
await fetch(window.location.href, { method: 'GET' })
} catch (err) {
error('config-debug: error setting config on subdomain', err)
}
Expand Down
26 changes: 14 additions & 12 deletions src/sw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,35 @@ declare let self: ServiceWorkerGlobalScope

let verifiedFetch: VerifiedFetch

const updateVerifiedFetch = async (): Promise<void> => {
verifiedFetch = await getVerifiedFetch()
}

self.addEventListener('install', (event) => {
// 👇 When a new version of the SW is installed, activate immediately
void self.skipWaiting()
event.waitUntil(updateVerifiedFetch())
})

const channel = new HeliaServiceWorkerCommsChannel('SW')

self.addEventListener('activate', () => {
// Set verified fetch initially
void getVerifiedFetch().then((newVerifiedFetch) => {
verifiedFetch = newVerifiedFetch
})

self.addEventListener('activate', (event) => {
channel.onmessagefrom('WINDOW', async (message: MessageEvent<ChannelMessage<'WINDOW', null>>) => {
const { action } = message.data

switch (action) {
case 'RELOAD_CONFIG':
void getVerifiedFetch().then((newVerifiedFetch) => {
verifiedFetch = newVerifiedFetch
})
event.waitUntil(updateVerifiedFetch().then(() => {
channel.postMessage({ action: 'RELOAD_CONFIG_SUCCESS' })
trace('sw: RELOAD_CONFIG_SUCCESS')
}))
break
default:
log('unknown action: ', action)
}
})
})

const channel = new HeliaServiceWorkerCommsChannel('SW')

/**
* Not available in ServiceWorkerGlobalScope
*/
Expand Down Expand Up @@ -133,7 +135,7 @@ function isSubdomainRequest (event: FetchEvent): boolean {
const isValidRequestForSW = (event: FetchEvent): boolean =>
isSubdomainRequest(event) || isRootRequestForContent(event) || isReferrerPreviouslyIntercepted(event)

self.addEventListener('fetch', event => {
self.addEventListener('fetch', (event) => {
const request = event.request
const urlString = request.url
const url = new URL(urlString)
Expand Down

0 comments on commit 1bae5f2

Please sign in to comment.