@swimmesberger/elarion-webpush
v0.3.2
Published
The browser half of Elarion Web Push: push availability detection (including the iOS Home Screen requirement), gesture-safe permission and subscribe/unsubscribe/refresh helpers over a pluggable server API, and a service-worker module for push, notificatio
Readme
@swimmesberger/elarion-webpush
The browser half of Elarion Web Push: reach a
user's browser or installed PWA while the app is closed. The server half is the Elarion.WebPush NuGet
package (IWebPushSender, VAPID keys, the subscription store).
pushAvailability()→'available' | 'install-first' | 'unsupported'.install-firstis iOS/iPadOS Safari outside a Home Screen app, wherePushManagerdoes not exist yet: show "Add to Home Screen first" instead of a switch that can never turn on.enablePush(api)— asks for permission inside the click handler (before anyawait, which Safari requires) and subscribes.subscribe,unsubscribe,isSubscribed, andrefreshOnStart(api)— call the last one on every app start to heal subscriptions the push service rotated or the server cleaned up. They subscribe through the page's active service-worker registration (or theregistrationoption) and wait at mostregistrationTimeoutMs(10 s) for a worker to activate, then throw aWebPushRegistrationError—navigator.serviceWorker.readyalone never settles when no worker is registered, for example on a dev server that does not serve one.@swimmesberger/elarion-webpush/sw—registerWebPushHandlers(self)for the service worker: shows the notification, focuses or opens the app at its URL on click, and re-subscribes onpushsubscriptionchange.
Page
import { enablePush, fetchWebPushApi, pushAvailability, refreshOnStart } from '@swimmesberger/elarion-webpush'
const api = fetchWebPushApi() // the endpoints app.MapElarionWebPush() maps under /webpush
await navigator.serviceWorker.register('/sw.js', { type: 'module' })
void refreshOnStart(api)
switch (pushAvailability()) {
case 'available':
button.onclick = async () => console.log(await enablePush(api)) // 'subscribed' | 'denied' | 'dismissed'
break
case 'install-first':
hint.textContent = 'Add this app to your Home Screen to turn on notifications.'
break
}When the application exposes its own webPush.* handlers instead of MapElarionWebPush, adapt the generated
JSON-RPC client:
const api: WebPushServerApi = {
getPublicKey: async () => (await rpc.webPush.publicKey({})).publicKey,
subscribe: async (subscription) => { await rpc.webPush.subscribe(subscription) },
unsubscribe: async (endpoint) => { await rpc.webPush.unsubscribe({ endpoint }) },
}Service worker
import { registerWebPushHandlers } from '@swimmesberger/elarion-webpush/sw'
registerWebPushHandlers(self, { icon: '/icons/192.png', badge: '/icons/badge.png' })The module is ESM: bundle the worker (e.g. vite-plugin-pwa injectManifest) or register it with
{ type: 'module' }.
