@wrnexus/pwa
Progressive Web App manifests, service workers, and offline strategies.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/pwa@0.8.7Request 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/pwaImport @wrnexus/pwa
import * as pwa from "@wrnexus/pwa";