/** A cache-name matcher: a prefix string, a `RegExp`, or a predicate. */ export declare type CacheFilter = string | RegExp | ((name: string) => boolean); /** * Main-thread helpers to inspect and clear the Cache Storage buckets a service * worker fills — for a "X MB cacheado" readout and a "limpar cache" action * (e.g. on logout). All guard `caches` so they no-op safely under SSR / older * browsers. */ /** Per-cache usage summary returned by {@link inspectCaches}. */ export declare interface CacheReport { /** The Cache Storage bucket name. */ name: string; /** Number of cached responses. */ entries: number; /** Approximate total bytes, or `null` when byte measurement was skipped. */ bytes: number | null; } /** * Delete Cache Storage buckets whose name passes `filter` (all of them when no * filter is given). * * @param filter - Which caches to delete. * @returns The names of the caches that were deleted. * * @example * await clearCaches("tempest-"); // drop every SDK-managed cache on logout */ export declare function clearCaches(filter?: CacheFilter): Promise; /** * Build a `206 Partial Content` response from a full one for an HTTP `Range` * request. Supports `bytes=start-end`, open-ended `bytes=start-` and suffix * `bytes=-suffixLength`. Returns the original response when there is no usable * `Range` header, or a `416` when the range is unsatisfiable. * * @param request The incoming request (its `Range` header drives the slice). * @param response The full (200) response to slice. */ export declare function createPartialResponse(request: Request, response: Response): Promise; /** * Report entry counts (and optionally byte sizes) for the Cache Storage * buckets whose name passes `filter`. * * @param options - `filter` narrows which caches to include; `measureBytes` * (default `true`) reads each response to sum sizes — set `false` for a fast, * count-only report. * @returns One {@link CacheReport} per matching cache. Empty when unsupported. * * @example * const reports = await inspectCaches({ filter: "tempest-" }); * const totalMb = reports.reduce((n, r) => n + (r.bytes ?? 0), 0) / 1e6; */ export declare function inspectCaches(options?: { filter?: CacheFilter; measureBytes?: boolean; }): Promise; /** * Install the background-sync queue: on a failed mutating request, the request * is serialized to IndexedDB and a sync is registered; the original fetch still * rejects (so your app can show an offline state), and the request is replayed * later when the network returns. * * @tempest-limits empty-catch — `registration.sync.register` is unavailable on * every non-Chromium browser and fails on a revoked background-sync permission. * The entry is already durable in IndexedDB at that point, and the queue is also * drained opportunistically on the next successful request, so losing the OS-level * wakeup degrades *when* the replay happens, not *whether* it happens. */ export declare function installBackgroundSync(options?: InstallBackgroundSyncOptions): void; /** * Background-sync helper: queue failed mutating requests (POST/PUT/PATCH/DELETE) * while offline and replay them when connectivity returns. A dependency-free * take on Workbox's `BackgroundSyncPlugin`, backed by a tiny IndexedDB queue. * * Import inside your `sw.ts`. Uses the Background Sync API (`registration.sync`) * when available, and also replays opportunistically on the next request as a * fallback for browsers without it (e.g. Safari). * * @example * import { installBackgroundSync } from "tempest-react-sdk/sw"; * * installBackgroundSync({ match: (url) => url.pathname.startsWith("/api/") }); */ /** Options for {@link installBackgroundSync}. */ export declare interface InstallBackgroundSyncOptions { /** * Which requests to queue on failure. A `RegExp` against the URL or a * predicate. Only non-`GET` requests are ever considered. Default: all * non-`GET` requests. */ match?: RegExp | ((url: URL, request: Request) => boolean); /** IndexedDB database name, also used as the sync tag. Default `tempest-bg-sync`. */ queueName?: string; /** Drop queued requests older than this (minutes) on replay. Default `1440` (24h). */ maxRetentionMinutes?: number; /** * Also drain the queue on the `periodicsync` event carrying this tag, * complementing the one-off `sync` replay so long-pending mutations retry * even without a fresh navigation. Register the periodic sync from the main * thread with {@link registerPeriodicSync}. Default `${queueName}-periodic`. */ periodicSyncTag?: string; } /** * Install a `notificationclick` handler that focuses an existing client when * possible and falls back to opening a new window. */ export declare function installNotificationClickHandler(options?: InstallNotificationClickHandlerOptions): void; export declare interface InstallNotificationClickHandlerOptions { /** Resolve the destination URL from the notification data. Default: `data.url`. */ resolveUrl?: (data: unknown) => string; } /** * Precache the app shell at `install` and serve it offline: * - reads `precache-manifest.json` (emitted by `tempestPwaManifest()`), * - caches every listed URL under a versioned cache, * - on `activate`, deletes stale precache versions and claims open clients, * - on `fetch`, serves precached assets cache-first and falls back to the * `navigateFallback` document for offline navigations (SPA routing). * * Same-origin only. Register this LAST, after any {@link installRuntimeCache}. */ export declare function installPrecache(options?: InstallPrecacheOptions): void; /** Options for {@link installPrecache}. */ export declare interface InstallPrecacheOptions { /** URL of the manifest emitted by `tempestPwaManifest()`. Default `/precache-manifest.json`. */ manifestUrl?: string; /** Cache name prefix; the manifest `version` is appended. Default `tempest-precache`. */ cacheName?: string; /** App-shell document served for navigation requests offline. Default `/index.html`. */ navigateFallback?: string; /** Navigation paths that should NOT use the fallback (e.g. `[/^\/api\//]`). */ navigateFallbackDenylist?: RegExp[]; /** Activate the new worker immediately after precaching. Default `true`. */ skipWaiting?: boolean; /** * Enable the Navigation Preload API on `activate`, so the browser fetches * the navigation request in parallel with the worker boot and the handler * serves `event.preloadResponse` — cutting first-navigation latency after * the worker starts. Silently ignored where unsupported. Default `true`. */ navigationPreload?: boolean; } /** * Install a `push` event listener that parses the payload as JSON (with a * plain-text fallback) and shows a notification. */ export declare function installPushHandler(options?: InstallPushHandlerOptions): void; export declare interface InstallPushHandlerOptions { /** Title used when the payload omits one. */ defaultTitle?: string; /** Icon used when the payload omits one. */ defaultIcon?: string; /** Badge image (mobile). */ defaultBadge?: string; /** * Transform the raw payload before showing the notification. Return `null` * to suppress the notification entirely (e.g. silent pings). */ transform?: (payload: PushPayload) => PushPayload | null; } /** * Install a `fetch` handler that resolves matching `GET` requests with the * given runtime strategies. Non-matching requests are left untouched (no * `respondWith`), so a later {@link installPrecache} can handle them. * * Register this BEFORE `installPrecache` so specific routes win over the * precache catch-all. * * @param routes Ordered rules; the first whose `match` passes handles the request. */ export declare function installRuntimeCache(routes: RuntimeRoute[]): void; /** * Install a `message` listener that activates a waiting worker when the host * app sends `{ type: "SKIP_WAITING" }`. */ export declare function installSkipWaitingListener(): void; /** * Service-worker context helpers for handling `push` and `notificationclick` * events. Import these inside your own `sw.ts` — they expect to run in the * service-worker global scope, not in the main thread. * * @example * /// * import { installPushHandler, installNotificationClickHandler } from "tempest-react-sdk"; * * installPushHandler({ defaultIcon: "/icons/Logo.png" }); * installNotificationClickHandler(); */ export declare interface PushPayload { title?: string; body?: string; icon?: string; badge?: string; image?: string; tag?: string; url?: string; /** Arbitrary extra data forwarded to `event.notification.data`. */ data?: Record; } /** * Request a Periodic Background Sync registration. * * Checks the `periodic-background-sync` permission first and only registers * when it is granted, so calling this unconditionally is safe. The browser * ultimately decides whether and how often the `periodicsync` event fires. * * @param options - The registration, tag and interval. * @returns `true` when the periodic sync was registered, else `false` * (unsupported, permission denied, or registration threw). * * @example * const reg = await navigator.serviceWorker.ready; * await registerPeriodicSync({ registration: reg, minIntervalMinutes: 360 }); */ export declare function registerPeriodicSync(options: RegisterPeriodicSyncOptions): Promise; /** * Main-thread helper to register a Periodic Background Sync, the counterpart to * the `periodicsync` listener installed by `installBackgroundSync`. Chrome-only * and gated behind the `periodic-background-sync` permission plus a site * engagement heuristic; degrades to a no-op (returns `false`) everywhere else. */ /** Options for {@link registerPeriodicSync}. */ export declare interface RegisterPeriodicSyncOptions { /** The active service-worker registration. */ registration: ServiceWorkerRegistration; /** Sync tag; must match `installBackgroundSync`'s `periodicSyncTag`. Default `tempest-bg-sync-periodic`. */ tag?: string; /** * Minimum interval between runs, in minutes. The browser treats this as a * floor and may space runs out much further. Default `720` (12h). */ minIntervalMinutes?: number; } /** * Register a service worker with consistent update-detection wiring. * * Skips silently when the runtime has no `serviceWorker` support. The host * app keeps full control over the SW file — this helper only handles the * boilerplate around `register()` and update detection. * * Two things can mean "an update is ready", and only one of them is an event. * `updatefound` covers the worker that installs while this tab is open. The * commoner case has no event at all: the user visited after a deploy, the new * worker installed and went to `waiting`, they closed the tab, and they are back * now. `install` already happened, so nothing fires — which is why `waiting` is * read directly once the registration resolves. Both routes go through the same * dedupe, so a worker is announced once even when both apply. * * Neither route fires without `navigator.serviceWorker.controller`: no * controller means this is the first install, which is `onReady` territory, not * an update the user should be prompted about. * * With `autoUpdate` enabled it additionally polls `registration.update()` on * an interval and (by default) reloads the page when a freshly activated worker * takes control — a framework-agnostic equivalent of `vite-plugin-pwa`'s * auto-update client, implemented directly on `navigator.serviceWorker`. * * @returns The registration when it succeeds, or `null` when unsupported. */ export declare function registerServiceWorker(options: RegisterServiceWorkerOptions): Promise; export declare interface RegisterServiceWorkerOptions { /** Public URL of the compiled service worker file (e.g. `/sw.js`). */ url: string; /** SW scope (default: SW directory). */ scope?: string; /** Called once the registration is active. */ onReady?: (registration: ServiceWorkerRegistration) => void; /** * Called when a new worker has finished installing while another worker * still controls the page. The host app typically prompts the user to * reload and then calls {@link skipWaiting} on the returned worker. * * Fires for a worker that was already `waiting` when `register()` resolved * — the state a user returning after a deploy actually finds — as well as * for one that installs during this session, and at most once per worker. */ onUpdate?: (waiting: ServiceWorker, registration: ServiceWorkerRegistration) => void; /** Called on registration failure. */ onError?: (error: unknown) => void; /** * When `true`, poll the server for a fresh service worker on an interval * (see {@link RegisterServiceWorkerOptions.updateIntervalMs}) and, unless * {@link RegisterServiceWorkerOptions.reloadOnActivate} is disabled, reload * the page as soon as a new worker takes control. Mirrors the auto-update * behaviour of `vite-plugin-pwa` without depending on it. Default `false`. */ autoUpdate?: boolean; /** * How often, in ms, to call `registration.update()` while `autoUpdate` is * on. Browsers already re-check roughly every 24h; an hourly poll keeps * long-lived sessions current without flooding the network. Default * `3600000` (1 hour). */ updateIntervalMs?: number; /** * When `autoUpdate` is on, reload the page once a new worker takes control * (`controllerchange`), guarded against reload loops. Set to `false` to * keep polling but leave the reload to the host app. Default `true`. */ reloadOnActivate?: boolean; } /** A single runtime-caching rule, matched against each `GET` request. */ export declare interface RuntimeRoute { /** A `RegExp` tested against the full URL, or a predicate over the parsed URL. */ match: RegExp | ((url: URL, request: Request) => boolean); /** How to resolve a match. */ strategy: RuntimeStrategy; /** Cache bucket name for this route. */ cacheName: string; /** Trim the cache to at most this many entries (FIFO) after each write. */ maxEntries?: number; /** Treat a cached response older than this (seconds) as a miss. */ maxAgeSeconds?: number; /** For `network-first`: fall back to cache after this timeout (seconds). */ networkTimeoutSeconds?: number; /** * Serve HTTP `Range` requests (206 Partial Content) by slicing the cached * full response. Enable for audio/video so seeking works offline. The full * resource is cached once (the `Range` header is stripped before caching). */ rangeRequests?: boolean; } /** * @tempest-limits file-lines — precache, runtime strategies (cache-first, network- * first, stale-while-revalidate), expiry and the inspect/clear helpers all address * the same Cache Storage namespace, and the naming scheme that keeps them from * evicting each other is the file's whole contract. */ /** * Service-worker caching helpers — a small, dependency-free subset of what * Workbox provides: precaching of the build's app shell (so the app launches * offline) plus runtime caching strategies for fonts, APIs and images. * * Import these inside your own `sw.ts`. They run in the service-worker global * scope, not the main thread. Pair `installPrecache` with the * `tempestPwaManifest()` Vite plugin (from `tempest-react-sdk/vite`), which * emits the `precache-manifest.json` this reads at install time. * * @example * /// * import { installRuntimeCache, installPrecache } from "tempest-react-sdk/sw"; * * // Register specific routes FIRST so they win over the precache catch-all. * installRuntimeCache([ * { match: /\/api\//, strategy: "network-first", cacheName: "api", maxAgeSeconds: 300 }, * ]); * installPrecache(); */ /** Caching strategy for a runtime route. Mirrors the common Workbox trio. */ export declare type RuntimeStrategy = "cache-first" | "network-first" | "stale-while-revalidate"; /** * Tell a waiting worker to activate immediately. Pair with `onUpdate` to roll * out updates after the user confirms a reload prompt. */ export declare function skipWaiting(worker: ServiceWorker): void; /** * Unregister all registered service workers for this origin. * * @returns Number of workers that were unregistered. */ export declare function unregisterAllServiceWorkers(): Promise; export { }