W WRNexusJS
Frontend · Package reference

@wrnexus/pwa

Progressive Web App manifests, service workers, and offline strategies.

v0.8.7Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/pwa@0.8.7

Request preview access. Never put registry tokens in source control.

Official PWA primitives for manifests, service workers, offline pages and precaching, runtime caching, background synchronization, push notifications, install/update events, offline mutation stores, and conflict resolution. createOfflineQueue() accepts a durable IndexedDB-style store and retries requests with stable idempotency headers.

Complete TypeScript API

Generated from the exact installed package declarations.

interface IndexedDbMigration {
    version: number;
    migrate(db: IDBDatabase, transaction: IDBTransaction): void;
}
declare function openPwaDatabase(name: string, migrations: IndexedDbMigration[], factory?: IDBFactory): Promise<IDBDatabase>;
declare function indexedDbOfflineQueueStore(db: IDBDatabase, storeName?: string): OfflineQueueStore;
declare const offlineQueueMigration: IndexedDbMigration;
interface StoredPushSubscription {
    id: string;
    userId: string;
    endpoint: string;
    expirationTime?: number | null;
    keys: {
        p256dh: string;
        auth: string;
    };
    createdAt: number;
}
interface PushSubscriptionStore {
    put(value: StoredPushSubscription): Promise<void>;
    remove(id: string): Promise<void>;
    list(userId: string): Promise<StoredPushSubscription[]>;
}
declare function memoryPushSubscriptionStore(): PushSubscriptionStore;
interface PushSqlClient {
    query<T = Record<string, unknown>>(sql: string, parameters?: unknown[]): Promise<{
        rows: T[];
    }>;
}
declare function postgresPushSubscriptionStore(db: PushSqlClient): PushSubscriptionStore;
declare const POSTGRES_PUSH_SUBSCRIPTION_SCHEMA = "CREATE TABLE IF NOT EXISTS wrnexus_push_subscriptions (id text PRIMARY KEY,user_id text NOT NULL,endpoint text NOT NULL,expiration_time bigint,p256dh text NOT NULL,auth text NOT NULL,created_at bigint NOT NULL); CREATE INDEX IF NOT EXISTS wrnexus_push_user ON wrnexus_push_subscriptions (user_id);";
declare function createPushSubscriptionService(store: PushSubscriptionStore, options?: {
    now?: () => number;
    maxPerUser?: number;
}): {
    subscribe(userId: string, value: {
        endpoint: string;
        expirationTime?: number | null;
        keys: {
            p256dh: string;
            auth: string;
        };
    }): Promise<{
        keys: {
            p256dh: string;
            auth: string;
        };
        createdAt: number;
        endpoint: string;
        expirationTime?: number | null;
        id: string;
        userId: string;
    }>;
    unsubscribe: (id: string) => Promise<void>;
    list: (userId: string) => Promise<StoredPushSubscription[]>;
};
declare function renderOfflineQueueReview(items: OfflineMutation[], conflicts?: Array<{
    id: string;
    message: string;
}>): string;
declare const PWA_REVIEW_RUNTIME = "document.addEventListener(\"click\",event=>{const button=event.target.closest(\"[data-pwa-retry],[data-pwa-remove],[data-pwa-client],[data-pwa-server]\");if(!button)return;const action=button.hasAttribute(\"data-pwa-retry\")?\"retry\":button.hasAttribute(\"data-pwa-remove\")?\"remove\":button.hasAttribute(\"data-pwa-client\")?\"client\":\"server\";const id=button.getAttribute(\"data-pwa-\"+action);dispatchEvent(new CustomEvent(\"wrnexus:pwa-review\",{detail:{action,id}}))});";

type RuntimeCacheStrategy = "network-first" | "cache-first" | "stale-while-revalidate";
interface RuntimeCacheRule {
    pattern: string;
    strategy: RuntimeCacheStrategy;
    cacheName?: string;
    methods?: string[];
}
interface ServiceWorkerOptions {
    cacheName?: string;
    offlineUrl?: string;
    startUrl?: string;
    cacheUrls?: string[];
    runtimeCaching?: RuntimeCacheRule[];
    backgroundSyncTag?: string;
}
interface WebManifestOptions {
    name: string;
    shortName?: string;
    description?: string;
    id?: string;
    startUrl?: string;
    scope?: string;
    display?: "standalone" | "fullscreen" | "minimal-ui" | "browser";
    themeColor?: string;
    backgroundColor?: string;
    icons?: Array<{
        src: string;
        sizes: string;
        type?: string;
        purpose?: string;
    }>;
    shortcuts?: unknown[];
    screenshots?: unknown[];
    categories?: string[];
    lang?: string;
}
declare function createWebManifest(options: WebManifestOptions): {
    id: string;
    name: string;
    short_name: string;
    description: string | undefined;
    start_url: string;
    scope: string;
    display: "standalone" | "fullscreen" | "minimal-ui" | "browser";
    theme_color: string;
    background_color: string;
    icons: {
        src: string;
        sizes: string;
        type?: string;
        purpose?: string;
    }[];
    shortcuts: unknown[];
    screenshots: unknown[];
    categories: string[];
    lang: string;
};
declare function generateServiceWorker(options?: ServiceWorkerOptions): string;
interface OfflineMutation<T = unknown> {
    id: string;
    createdAt: number;
    updatedAt: number;
    endpoint: string;
    method: string;
    payload: T;
    attempts: number;
}
interface OfflineQueueStore {
    list(): Promise<OfflineMutation[]>;
    put(item: OfflineMutation): Promise<void>;
    remove(id: string): Promise<void>;
}
declare function memoryOfflineQueueStore(): OfflineQueueStore;
type ConflictResolution<T> = {
    action: "client" | "server" | "merge";
    value: T;
};
declare function resolveOfflineConflict<T extends object>(client: T, server: T, strategy?: "client-wins" | "server-wins" | "last-write-wins" | ((client: T, server: T) => T)): ConflictResolution<T>;
declare function createOfflineQueue(options?: {
    store?: OfflineQueueStore;
    fetch?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
    maxItems?: number;
    now?: () => number;
}): {
    enqueue<T>(input: Omit<OfflineMutation<T>, "id" | "createdAt" | "updatedAt" | "attempts">): Promise<OfflineMutation<T>>;
    list: () => Promise<OfflineMutation<unknown>[]>;
    sync(): Promise<{
        id: string;
        ok: boolean;
        status?: number;
    }[]>;
    remove: (id: string) => Promise<void>;
};
declare function pwaClientRuntime(serviceWorkerUrl?: string): string;
declare function subscribeToPush(registration: ServiceWorkerRegistration, publicKey: Uint8Array): Promise<PushSubscription>;

export { type ConflictResolution, type IndexedDbMigration, type OfflineMutation, type OfflineQueueStore, POSTGRES_PUSH_SUBSCRIPTION_SCHEMA, PWA_REVIEW_RUNTIME, type PushSqlClient, type PushSubscriptionStore, type RuntimeCacheRule, type RuntimeCacheStrategy, type ServiceWorkerOptions, type StoredPushSubscription, type WebManifestOptions, createOfflineQueue, createPushSubscriptionService, createWebManifest, generateServiceWorker, indexedDbOfflineQueueStore, memoryOfflineQueueStore, memoryPushSubscriptionStore, offlineQueueMigration, openPwaDatabase, postgresPushSubscriptionStore, pwaClientRuntime, renderOfflineQueueReview, resolveOfflineConflict, subscribeToPush };

Examples

Copy-ready examples from the installed package documentation.

Install @wrnexus/pwa

bun add @wrnexus/pwa

Import @wrnexus/pwa

import * as pwa from "@wrnexus/pwa";