# @suaveplan/pwa - Enterprise browser-tier PWA primitives: ServiceWorkerManager + UpdateController, pluggable SyncQueue (memory / localStorage / IndexedDB stores) with Zod-validated entries + version migration + Background Sync bridge, PushNotificationManager + VAPID decoder, InstallPromptManager with persisted dismissal, caching-strategy DSL (cacheFirst / networkFirst / staleWhileRevalidate / cacheOnly / networkOnly) + Router, Web App Manifest builder, OTel counters + histograms, typed PWA.* error registry. Enterprise browser-tier PWA primitives for Suaveplan applications. - **Tier**: browser - **Category / plugin**: `foundation / data` - **Version**: 0.1.0 ## Documentation tree - [caching-strategies](./src/caching-strategies/caching-strategies.md) — Five pure async strategy functions (`cacheFirst`, `networkFirst`, `staleWhileRevalidate`, `cacheOnly`, `networkOnly`) t… - [caching-strategies](./src/caching-strategies/caching-strategies.md) — Five pure async strategy functions (`cacheFirst`, `networkFirst`, `staleWhileRevalidate`, `cacheOnly`, `networkOnly`) t… - [router](./src/caching-strategies/router.md) — `Router` evaluates incoming `Request`s against a list of registered routes in order and dispatches the first match to i… - [errors](./src/errors/errors.md) — Defines the `PWA_CODES` stable error-code registry, the `PwaError` base class, and the frozen `PWA_ERROR_METADATA` tabl… - [errors](./src/errors/errors.md) — Defines the `PWA_CODES` stable error-code registry, the `PwaError` base class, and the frozen `PWA_ERROR_METADATA` tabl… - [install-prompt](./src/install-prompt/install-prompt.md) — `InstallPromptManager` captures the browser-fired `beforeinstallprompt` event and exposes it as a typed state machine t… - [install-prompt](./src/install-prompt/install-prompt.md) — `InstallPromptManager` captures the browser-fired `beforeinstallprompt` event and exposes it as a typed state machine t… - [manifest](./src/manifest/manifest.md) — `ManifestBuilder` provides a fluent, type-safe builder for the W3C Web App Manifest. Every setter returns `this` so con… - [manifest](./src/manifest/manifest.md) — `ManifestBuilder` provides a fluent, type-safe builder for the W3C Web App Manifest. Every setter returns `this` so con… - [observability](./src/observability/observability.md) — Single factory function that builds the `PwaObservability` bundle threaded through every public manager in `@suaveplan/… - [observability](./src/observability/observability.md) — Single factory function that builds the `PwaObservability` bundle threaded through every public manager in `@suaveplan/… - [push-notifications](./src/push-notifications/push-notifications.md) — `PushNotificationManager` wraps the W3C Push API and `Notification` static interface behind injectable seams. The manag… - [push-notifications](./src/push-notifications/push-notifications.md) — `PushNotificationManager` wraps the W3C Push API and `Notification` static interface behind injectable seams. The manag… - [vapid](./src/push-notifications/vapid.md) — Single-helper module that decodes a URL-safe base64 VAPID application server key into the raw `Uint8Array` the Push API… - [schemas](./src/schemas/schemas.md) — Zod schemas guarding the package's two persisted boundaries: the sync-queue entry and the Web App Manifest. Every value… - [schemas](./src/schemas/schemas.md) — Zod schemas guarding the package's two persisted boundaries: the sync-queue entry and the Web App Manifest. Every value… - [service-worker](./src/service-worker/service-worker.md) — `ServiceWorkerManager` wraps the browser `ServiceWorkerContainer` API behind an injectable seam so production code reac… - [service-worker](./src/service-worker/service-worker.md) — `ServiceWorkerManager` wraps the browser `ServiceWorkerContainer` API behind an injectable seam so production code reac… - [sync-queue](./src/sync-queue/sync-queue.md) — Offline-first request queue that persists requests while the device is offline and replays them when connectivity retur… - [background-sync](./src/sync-queue/background-sync.md) — Bridges the standard W3C Background Sync API (`SyncManager.register(tag)`) into the `@suaveplan/pwa` package. Where the… - [indexeddb-store](./src/sync-queue/indexeddb-store.md) — Default production `SyncQueueStore` implementation, backed by IndexedDB. IDB is the only browser-native storage that su… - [local-storage-store](./src/sync-queue/local-storage-store.md) — Backwards-compatible `SyncQueueStore` backed by the synchronous `Storage` interface (`localStorage` in production). Ret… - [memory-store](./src/sync-queue/memory-store.md) — Fastest possible `SyncQueueStore` implementation, backed by a private array. Used as the default in unit tests and as a… - [sync-queue](./src/sync-queue/sync-queue.md) — Offline-first request queue that persists requests while the device is offline and replays them when connectivity retur… - [version-migration](./src/sync-queue/version-migration.md) — Forward-migrates raw `SyncQueueEntry` records loaded from persistent storage (IndexedDB / localStorage) to the current… - [types](./src/types/common.md) — Central type definitions shared across the `@suaveplan/pwa` package. The module owns every cross-module structural cont… - [common](./src/types/common.md) — Central type definitions shared across the `@suaveplan/pwa` package. The module owns every cross-module structural cont… - [update-controller](./src/update-controller/update-controller.md) — `UpdateController` coordinates a synchronised page reload across every tab the application is open in when a new servic… - [update-controller](./src/update-controller/update-controller.md) — `UpdateController` coordinates a synchronised page reload across every tab the application is open in when a new servic… ## Overview `@suaveplan/pwa` ships the full set of progressive-web-app primitives every Suaveplan browser app needs: - `ServiceWorkerManager` + `UpdateController` — registration, update polling, `skipWaiting`, and cross-tab reload coordination via `BroadcastChannel`. - `SyncQueue` — pluggable offline-first request queue with three shipped store implementations (`MemoryStore`, `LocalStorageStore`, `IndexedDbStore`), Zod-validated entries, exponential-backoff retry, version migration, and a `BackgroundSyncBridge` for `SyncManager` + `visibilitychange` fallback. - `PushNotificationManager` — permission flow, VAPID-based subscribe / unsubscribe through an injectable `ServiceWorkerContainer`. - `InstallPromptManager` — `beforeinstallprompt` capture with persisted dismissal across sessions. - Caching strategies — `cacheFirst`, `networkFirst`, `staleWhileRevalidate`, `cacheOnly`, `networkOnly` + a route `Router`. - `ManifestBuilder` — fluent, Zod-validated Web App Manifest builder. - Typed `PWA_CODES` error registry + `PwaError`. - OTel counters + histograms wired into every manager. ## Quick start ```ts import { ServiceWorkerManager, UpdateController, SyncQueue, IndexedDbStore, PushNotificationManager, InstallPromptManager, Router, cacheFirst, networkFirst, ManifestBuilder, } from "@suaveplan/pwa"; const swm = new ServiceWorkerManager(); const updates = new UpdateController(); const queue = new SyncQueue({ store: new IndexedDbStore() }); const push = new PushNotificationManager(); const ipm = new InstallPromptManager(); await swm.register({ scriptUrl: "/sw.js" }); swm.onStateChange((state) => { if (state === "activated") updates.signalReload(); }); ipm.listen(); const result = await push.subscribe({ applicationServerKey: process.env.VAPID_PUBLIC_KEY, }); const manifest = new ManifestBuilder() .setName("Suaveplan") .addIcon({ src: "/icon-512.png", sizes: "512x512" }) .build(); ``` Inside the SW: ```ts import { Router, cacheFirst, networkFirst } from "@suaveplan/pwa"; const router = new Router({ cacheName: "v1" }); router.registerRoute({ pattern: /\.(png|jpg|webp)$/, strategy: cacheFirst() }); router.registerRoute({ pattern: /\/api\//, strategy: networkFirst() }); self.addEventListener("fetch", (e) => e.respondWith(router.handle(e.request))); ``` ## Subpath exports | Subpath | Module | | --- | --- | | `.` | barrel — every public symbol | | `./errors` | `PWA_CODES`, `PwaError`, metadata table | | `./schemas` | Zod schemas for sync-queue entry + Web App Manifest | | `./observability` | `createPwaObservability` factory + types | | `./service-worker` | `ServiceWorkerManager` | | `./update-controller` | `UpdateController` | | `./sync-queue` | `SyncQueue`, stores, migrator, background-sync bridge | | `./push-notifications` | `PushNotificationManager` + `urlBase64ToUint8Array` | | `./install-prompt` | `InstallPromptManager` | | `./caching-strategies` | 5 strategies + `Router` | | `./manifest` | `ManifestBuilder` | ## Tests ```bash bunx turbo lint typecheck test build --filter=@suaveplan/pwa bunx turbo test:coverage --filter=@suaveplan/pwa ``` Targets `happy-dom` for DOM stubs and `fake-indexeddb` for `IDBFactory` in the `IndexedDbStore` conformance test.