← Public packages
@kentcdodds/package-app-kit
Design tokens, PWA install/update, About/version, cache helpers, and optional realtime notes sync for Kody package apps.
src/client/sw-register.ts
55 lines · 1.6 KB · TypeScript/** Service worker registration with stale-registration cleanup. */
import { readClientConfig } from './config.ts'
declare global {
interface Window {
pakRegisterServiceWorker?: () => Promise<ServiceWorkerRegistration | null>
}
}
export function bootServiceWorkerRegistration() {
const config = readClientConfig()
async function unregisterStaleWorkers() {
if (!('serviceWorker' in navigator)) return
const regs = await navigator.serviceWorker.getRegistrations()
const scopePrefix = `${config.appBase}/`
await Promise.all(
regs.map((reg) => {
let scopePath = ''
try {
scopePath = new URL(reg.scope).pathname
} catch {
return null
}
const underApp =
scopePath === config.appBase ||
scopePath === scopePrefix ||
scopePath.startsWith(scopePrefix)
if (underApp) return null
if (scopePath.startsWith('/packages/') && !scopePath.startsWith(scopePrefix)) {
return reg.unregister()
}
return null
}),
)
}
async function register() {
if (!('serviceWorker' in navigator)) return null
await unregisterStaleWorkers()
// Platform assets SW: register `${assetBasePath}/sw.js` with app mount scope.
// Interim (no clientModuleUrl / older platform): Worker-served `/sw.js`.
const scriptUrl = config.swUrl.startsWith('http')
? config.swUrl
: config.swUrl.startsWith('/')
? config.swUrl
: `${config.appBase}/${config.swUrl}`
return navigator.serviceWorker.register(scriptUrl, {
scope: `${config.appBase}/`,
updateViaCache: 'none',
})
}
window.pakRegisterServiceWorker = register
}