PushManager wrapper — VAPID subscribe/unsubscribe, current subscription, permission state.
Module push | Source packages/front/fw/src/dom/sw/push.js | Deps serviceWorker, b64 | Worker-safe no
Wrapper around PushManager (window side only). Manages server push notification subscriptions with a VAPID public key. Payload encryption (RFC 8291) is out of scope — delegated to Bun/Node libs on the SDE server side.
References: Web Push Protocol RFC 8030, VAPID RFC 8292.
Resolve
const push = runtime.resolve('push');
// Returns: { subscribe, unsubscribe, current, permission, support }
API
| Method | Signature | Returns |
|---|---|---|
subscribe |
(opts: SubscribeOpts) => Promise<PushSubResult> |
Serialized subscription |
unsubscribe |
() => Promise<boolean> |
true if unsubscribed |
current |
() => Promise<PushSubResult | null> |
Active subscription or null |
permission |
() => Promise<'granted' | 'denied' | 'prompt'> |
Push permission state |
support |
() => { available: boolean, sw: boolean } |
Available capabilities |
Options subscribe
| Option | Type | Default | Description |
|---|---|---|---|
applicationServerKey |
Uint8Array | string |
— | VAPID public key (Uint8Array or base64url). Required. |
userVisibleOnly |
boolean |
true |
Required true by Chrome (always). |
Type PushSubResult
{
endpoint: string, // push endpoint URL
expirationTime: number | null,
keys: {
p256dh: string | null, // DH public key (base64)
auth: string | null, // authentication secret (base64)
},
raw: PushSubscription, // original native object
}
Examples
Initial subscription
const push = runtime.resolve('push');
if (push.support().available) {
const vapidPublicKey = 'BEl62iUYgUivxIkv...'; // base64url VAPID
const sub = await push.subscribe({ applicationServerKey: vapidPublicKey });
// Send sub.endpoint + sub.keys to the server
await fetch('/api/push/subscribe', {
method: 'POST',
body: JSON.stringify({ endpoint: sub.endpoint, keys: sub.keys }),
headers: { 'Content-Type': 'application/json' },
});
}
Inspection and unsubscription
const push = runtime.resolve('push');
const current = await push.current();
if (current) {
console.log('Subscribed to:', current.endpoint);
const ok = await push.unsubscribe();
console.log('Unsubscribed:', ok);
}
Permission check
const push = runtime.resolve('push');
const state = await push.permission();
// 'granted' | 'denied' | 'prompt'
if (state === 'denied') {
console.warn('Push notifications blocked by the user');
}
Notes
- Payload encryption not managed client-side. Building the encrypted message (RFC 8291 / ECDH P-256 + AES-GCM) is delegated to server libs (
web-pushnpm,web_pushRust, etc.). PushManagerrequires HTTPS (orlocalhost) — the subscription will silently fail on HTTP.userVisibleOnly: trueis enforced by Chrome; settingfalsemay raise an exception on some browsers.- The
applicationServerKeyin base64url (RFC 4648 §5) is automatically converted viab64. - The
rawproperty ofPushSubResultcontains the nativePushSubscription— not cross-worker serializable.
See also
- serviceWorker — SW lifecycle (basis for
push.ready()) - cache — Cache API (often combined with SW push)
- notifications — Web Notifications API (displaying received notifications)