Swoff Swoff

Framework Adapters

How Swoff bridges service worker events to your framework's reactive system.

What is an Adapter?

An adapter listens to window events dispatched by the service worker registration code and exposes them as reactive state in your framework — hooks, composables, stores, signals, or services.

The adapter layer is the only framework-specific code in Swoff. Everything else (SW template, build script, registration logic) is plain JavaScript.

Event Flow

SW Registration Code (framework-agnostic)
     ↓ dispatches
window.addEventListener('sw-update-available', ...)
window.addEventListener('sw-progress', ...)
window.addEventListener('sw-ready', ...)
window.addEventListener('sw-error', ...)
window.addEventListener('sw-auth-state-change', ...)
window.addEventListener('cache-invalidated', ...)
window.addEventListener('background-sync-complete', ...)
window.addEventListener('mutation-sync-complete', ...)
window.addEventListener('mutation-queue-changed', ...)
window.addEventListener('push-subscription-changed', ...)
window.addEventListener('push-permission-changed', ...)

Adapter (framework-specific)
     ↓ exposes
useSWUpdate() / useSWProgress() / useCachedFetch() / useMutationQueue() / useAuth() / usePushSubscription() / useNetworkStatus() / useBackgroundSync() / useCacheInvalidation()  — React
useSWUpdate() / useSWProgress() / useNetworkStatus() / useBackgroundSync() / useCacheInvalidation()  — Vue composables
...                                                                       — Svelte stores, Solid signals, Angular services

Events to Listen To

EventDetailWhen
sw-update-available{ version: string }New SW version detected
sw-progress{ percent: number }During SW download
sw-readynoneSW activated and ready
sw-errornoneSW registration failed
sw-auth-state-changenoneAuth state changed (login/logout/refresh)
cache-invalidated{ tags: string[] }Cache tags invalidated (by this tab or another)
mutation-sync-complete{ succeeded: number, failed: number }Queue sync finished
mutation-queue-changednoneQueue contents changed (added/processed)
background-sync-complete{ succeeded: number, failed: number }Background sync finished
push-subscription-changed{ subscribed: boolean }Push subscription added/removed
push-permission-changed{ permission: NotificationPermission }Permission granted/denied

Window Properties

PropertyTypePurpose
currentSWVersionstring | undefinedActive SW version
latestSWVersionstring | undefinedServer-side version
swMinSupportedVersionstring | undefinedMinimum version that can still serve
swUpdateRequiredboolean | undefinedWhether update is enforced

Adapter Responsibility

Your adapter should:

  1. Listen to sw-update-available and expose availableVersion, forceUpdate
  2. Listen to sw-progress and expose progress, status
  3. Provide acceptUpdate() — registers new SW via registerServiceWorker()
  4. Provide dismissUpdate() — sets sessionStorage['sw-dismissed-update']
  5. Provide checkForUpdates() — manually fetches version.json
  6. Listen to cache-invalidated / mutation-sync-complete / background-sync-complete / push-subscription-changed and expose reactive state for each feature

React Implementation

React uses hooks with useState, useEffect, and useCallback. See React Hooks.

Vue Implementation

Vue uses composables with ref, reactive, and onMounted/onUnmounted. See Vue Composables.

Svelte Implementation

Svelte uses stores with writable and lifecycle functions. See Svelte Stores.

Next Steps

On this page