@molecule/api-push-notifications-web-push
v1.0.1
Published
Web Push provider for molecule.dev push notifications
Maintainers
Readme
@molecule/api-push-notifications-web-push
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Web Push provider for molecule.dev push notifications.
Provides push notification delivery using the Web Push protocol (VAPID)
via the web-push library.
Quick Start
import { setProvider } from '@molecule/api-push-notifications'
import { provider } from '@molecule/api-push-notifications-web-push'
setProvider(provider) // VAPID config is read from env on first sendType
provider
Installation
npm install @molecule/api-push-notifications-web-push @molecule/api-bond @molecule/api-push-notifications @molecule/api-secrets web-push
npm install -D @types/web-pushAPI
Functions
createProvider()
Creates a new WebPushProvider instance. VAPID credentials are configured lazily on first send.
function createProvider(): PushNotificationProviderReturns: A PushNotificationProvider backed by the web-push library.
Constants
provider
Lazily-initialized push notification provider using the web-push library.
Created on first property access via a Proxy so no work is done at import time.
The set trap is REQUIRED, not defensive: methods reached through the proxy
run with this bound to the proxy, so an instance-state write like
this.configured = true would otherwise land on the dummy {} target while
every read passes through to the real instance — configure() could then
never take effect and every send would throw "not configured".
const provider: PushNotificationProviderpushNotificationsWebPushSecretDefinitions
Secret definitions required by the Web Push notifications bond.
const pushNotificationsWebPushSecretDefinitions: SecretDefinition[]Core Interface
Implements @molecule/api-push-notifications interface.
Bond Wiring
Setup function to register this provider with the core interface:
import { setProvider } from '@molecule/api-push-notifications'
import { provider } from '@molecule/api-push-notifications-web-push'
export function setupPushNotificationsWebPush(): void {
setProvider(provider)
}Injection Notes
Requirements
Peer dependencies:
@molecule/api-bond^1.0.1@molecule/api-push-notifications^1.0.1@molecule/api-secrets^1.0.1
Environment Variables
VAPID_PUBLIC_KEY(required) — Web Push VAPID public key- Auto-generated at scaffold — no manual setup.
VAPID_PRIVATE_KEY(required) — Web Push VAPID private key- Auto-generated at scaffold — no manual setup.
VAPID_EMAIL(required) — Web Push contact email- Setup: Contact address sent to push services with each request (mailto: form).
- Example:
mailto:[email protected]
Runtime Dependencies
@molecule/api-bond@molecule/api-push-notifications@molecule/api-secretsweb-push
Configuration is lazy and env-driven: configure() — called automatically on
the first send() if you never call it — reads VAPID_EMAIL,
VAPID_PUBLIC_KEY, and VAPID_PRIVATE_KEY unless an explicit VapidConfig
is passed. With any of the three missing, wiring/boot does NOT fail:
configure() logs a warning ("Push notifications disabled: missing …") and
every subsequent send()/sendMany() THROWS "Push notifications not
configured" — so a missing env var surfaces at first send, not at startup.
VAPID_EMAIL accepts a bare address or the mailto:/https: form (a bare
address is normalized to mailto:… — don't prepend mailto: to a value that
already has it). getPublicKey() serves the key browsers need to subscribe
(configured key first, VAPID_PUBLIC_KEY fallback); generateVapidKeys()
mints a fresh pair — scaffolds auto-generate these secrets, so it's only
needed for manual provisioning or rotation. sendMany() uses
Promise.allSettled: one dead subscription never aborts the batch (check
each result's error).
E2E Tests
Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:
- [ ] The UI offers an enable-notifications control; activating it triggers the browser permission prompt and, once granted, the subscription is stored (the UI still shows "enabled" after a full reload).
- [ ] An event this app notifies about actually delivers a push to the
subscribed session, with a readable title/body (not raw JSON). The sandbox
CAPTURES outbound pushes instead of delivering — read the captured message
with the
read_activitytool (filter type 'push'); never mock the flow or modify production code to expose it. - [ ] Clicking the delivered notification opens/focuses the relevant screen (when the app claims deep-linking).
- [ ] Denying the permission leaves the app fully usable and truthful about the state (no crash, no false "enabled").
- [ ] Disabling/unsubscribing stops deliveries, and the disabled state persists across a reload.
