Skip to content

Instantly share code, notes, and snippets.

@JamieMason
Created December 16, 2024 13:53
Show Gist options
  • Save JamieMason/f1fe7973089d9b0c16f6c855adc08735 to your computer and use it in GitHub Desktop.
Save JamieMason/f1fe7973089d9b0c16f6c855adc08735 to your computer and use it in GitHub Desktop.
on active service worker

onActiveServiceWorker

Abandoned this as being over the top, but saving it as this Gist.

import { isDev } from '@builder.io/qwik/build';

let memo: Promise<ServiceWorker> | null;

export async function getActiveServiceWorker(): Promise<ServiceWorker> {
  if (memo) {
    const serviceWorker = await memo;
    if (serviceWorker.state === 'activated') return serviceWorker;
  }
  memo = registerServiceWorker();
  return await memo;
}

async function registerServiceWorker(): Promise<ServiceWorker> {
  if ('serviceWorker' in navigator) {
    await onWindowLoaded();
    const registration = await registerServiceWorker();
    const serviceWorker = await onActiveServiceWorker(registration);

    return serviceWorker;

    function registerServiceWorker() {
      return navigator.serviceWorker.register(!isDev ? '/service-worker.js' : '/dev-sw.js?dev-sw', {
        type: !isDev ? 'classic' : 'module',
      });
    }

    function onWindowLoaded() {
      return new Promise<void>(resolve => {
        if (document.readyState === 'complete') {
          resolve();
        } else {
          window.addEventListener('load', () => resolve());
        }
      });
    }

    async function onActiveServiceWorker(
      registration: ServiceWorkerRegistration,
    ): Promise<ServiceWorker> {
      const serviceWorker = registration.installing || registration.waiting;
      if (registration.active) {
        return registration.active;
      } else if (serviceWorker) {
        return new Promise<ServiceWorker>(resolve => {
          serviceWorker.addEventListener('statechange', () => {
            if (serviceWorker.state === 'activated') {
              resolve(serviceWorker);
            }
          });
        });
      }
      throw new Error('Unable to locate service worker');
    }
  } else {
    throw new Error('Service workers are not supported');
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment