@molecule/app-push
v1.0.2
Published
Client-side push notifications interface for molecule.dev
Downloads
1,751
Maintainers
Readme
@molecule/app-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.
Client-side push notifications interface for molecule.dev.
Provides a unified API for push notifications across platforms (web,
native containers, etc.): permission flow (checkPermission,
requestPermission), registration (register, getToken), incoming
events (onNotificationReceived, onNotificationAction), local
notifications (scheduleLocal), and badges (setBadge, clearBadge).
The device token is what your API's @molecule/api-push-notifications
bond sends to.
Quick Start
import { getToken, onNotificationAction, register, requestPermission } from '@molecule/app-push'
async function enablePush(vapidPublicKey: string): Promise<string | null> {
const permission = await requestPermission() // from a user gesture
if (permission !== 'granted') return null
const token = await register({ vapidPublicKey })
// POST token.value to your API so api-push-notifications can target it
return token.value
}
function handleTaps(open: (data: unknown) => void): () => void {
return onNotificationAction((event) => open(event.notification.data))
}Type
native
Installation
npm install @molecule/app-push @molecule/app-bond @molecule/app-i18nAPI
Interfaces
LocalNotificationOptions
Options for scheduling a local notification.
interface LocalNotificationOptions {
/**
* Notification ID.
*/
id?: string
/**
* Notification title.
*/
title: string
/**
* Notification body.
*/
body?: string
/**
* Schedule at a specific time.
*/
at?: Date
/**
* Repeat interval.
*/
repeat?: 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year'
/**
* Extra data.
*/
extra?: Record<string, unknown>
/**
* Sound to play.
*/
sound?: string
/**
* Badge count.
*/
badge?: number
/**
* Notification channel (Android).
*/
channelId?: string
/**
* Actions/buttons.
*/
actions?: PushNotificationAction[]
}NotificationActionEvent
Notification action event.
interface NotificationActionEvent {
/**
* The notification.
*/
notification: PushNotification
/**
* Action that was triggered.
*/
actionId?: string
}NotificationReceivedEvent
Notification received event.
interface NotificationReceivedEvent {
/**
* The notification.
*/
notification: PushNotification
/**
* Whether the app was in foreground.
*/
foreground: boolean
}PushNotification
Push notification payload.
interface PushNotification {
/**
* Notification ID.
*/
id: string
/**
* Notification title.
*/
title: string
/**
* Notification body/message.
*/
body?: string
/**
* Notification data payload.
*/
data?: Record<string, unknown>
/**
* Badge count.
*/
badge?: number
/**
* Sound to play.
*/
sound?: string
/**
* Icon URL.
*/
icon?: string
/**
* Image URL.
*/
image?: string
/**
* Click action/URL.
*/
clickAction?: string
/**
* Notification tag (for grouping).
*/
tag?: string
/**
* Whether the notification requires interaction.
*/
requireInteraction?: boolean
/**
* Notification timestamp.
*/
timestamp?: number
/**
* Notification actions (buttons).
*/
actions?: PushNotificationAction[]
}PushNotificationAction
Notification action button.
interface PushNotificationAction {
/**
* Action ID.
*/
id: string
/**
* Action title.
*/
title: string
/**
* Action icon.
*/
icon?: string
}PushProvider
Push notifications provider interface.
All push providers must implement this interface.
interface PushProvider {
/**
* Checks the current permission status.
*/
checkPermission(): Promise<PermissionStatus>
/**
* Requests notification permission.
*/
requestPermission(): Promise<PermissionStatus>
/**
* Registers for push notifications and gets a token.
*
* @param options - Optional registration options (e.g. a runtime VAPID
* public key for web subscriptions).
*/
register(options?: PushRegisterOptions): Promise<PushToken>
/**
* Unregisters from push notifications.
*/
unregister(): Promise<void>
/**
* Gets the current push token.
* @returns The current token, or `null` if not registered.
*/
getToken(): Promise<PushToken | null>
/**
* Subscribes to notification received events.
*/
onNotificationReceived(listener: NotificationReceivedListener): () => void
/**
* Subscribes to notification action events (taps, button clicks).
*/
onNotificationAction(listener: NotificationActionListener): () => void
/**
* Subscribes to token changes.
*/
onTokenChange(listener: TokenChangeListener): () => void
/**
* Schedules a local notification.
*/
scheduleLocal(options: LocalNotificationOptions): Promise<string>
/**
* Cancels a local notification.
*/
cancelLocal(id: string): Promise<void>
/**
* Cancels all local notifications.
*/
cancelAllLocal(): Promise<void>
/**
* Gets pending local notifications.
*/
getPendingLocal(): Promise<LocalNotificationOptions[]>
/**
* Gets delivered notifications.
*/
getDelivered(): Promise<PushNotification[]>
/**
* Removes delivered notifications.
*/
removeDelivered(ids: string[]): Promise<void>
/**
* Removes all delivered notifications.
*/
removeAllDelivered(): Promise<void>
/**
* Sets the badge count.
*/
setBadge(count: number): Promise<void>
/**
* Gets the badge count.
*/
getBadge(): Promise<number>
/**
* Clears the badge.
*/
clearBadge(): Promise<void>
/**
* Destroys the provider.
*/
destroy(): void
}PushRegisterOptions
Options for {@link PushProvider.register}.
interface PushRegisterOptions {
/**
* VAPID public key (URL-safe base64) used as the `applicationServerKey`
* when subscribing on the web. Chromium rejects keyless subscriptions, so
* web apps should deliver the server's key at runtime (e.g. from
* `GET /api/devices/push/public-key`) and pass it here. Takes precedence
* over any key the provider was constructed with. Ignored by providers
* whose platform does not use VAPID (e.g. FCM/APNs native providers).
*/
vapidPublicKey?: string
}PushToken
Push token info.
interface PushToken {
/**
* Token value.
*/
value: string
/**
* Platform the token is for.
*/
platform: 'web' | 'ios' | 'android'
/**
* When the token was obtained.
*/
timestamp: number
}Types
NotificationActionListener
Notification Action Listener type.
type NotificationActionListener = (event: NotificationActionEvent) => voidNotificationReceivedListener
Listener invoked when a push notification is received.
type NotificationReceivedListener = (event: NotificationReceivedEvent) => voidPermissionStatus
Push notification permission status.
type PermissionStatus = 'granted' | 'denied' | 'default' | 'prompt'TokenChangeListener
Token Change Listener type.
type TokenChangeListener = (token: PushToken) => voidFunctions
checkPermission()
Checks the current notification permission status.
function checkPermission(): Promise<PermissionStatus>Returns: The current permission status (granted, denied, default, or prompt).
clearBadge()
Clears the app icon badge count.
function clearBadge(): Promise<void>Returns: A promise that resolves when the badge count is cleared.
createWebPushProvider(vapidPublicKey)
Creates a web push provider using the browser Push API and Notification API.
function createWebPushProvider(vapidPublicKey?: string): PushProvidervapidPublicKey— Optional VAPID public key for server-authenticated subscriptions.
Returns: A {@link PushProvider} backed by the Web Push API.
getProvider()
Gets the current push provider, creating a default web provider if none is bonded.
function getProvider(): PushProviderReturns: The active push provider instance.
getToken()
Gets the current push token.
function getToken(): Promise<PushToken | null>Returns: The current token, or null if not registered.
hasProvider()
Checks if a push provider has been bonded.
function hasProvider(): booleanReturns: Whether a push provider is currently registered.
onNotificationAction(listener)
Subscribes to notification action events (taps, button clicks).
function onNotificationAction(listener: NotificationActionListener): () => voidlistener— Callback invoked when a notification action is triggered.
Returns: An unsubscribe function to remove the listener.
onNotificationReceived(listener)
Subscribes to notification received events.
function onNotificationReceived(listener: NotificationReceivedListener): () => voidlistener— Callback invoked when a notification is received.
Returns: An unsubscribe function to remove the listener.
register(options)
Registers for push notifications and obtains a device token.
function register(options?: PushRegisterOptions): Promise<PushToken>options— Optional registration options (e.g. a runtime VAPID public key).
Returns: The push token for this device.
requestPermission()
Requests notification permission from the user.
function requestPermission(): Promise<PermissionStatus>Returns: The resulting permission status after the user responds.
scheduleLocal(options)
Schedules a local notification.
function scheduleLocal(options: LocalNotificationOptions): Promise<string>options— Configuration for the notification (title, body, schedule time, etc.).
Returns: The notification ID that can be used to cancel it later.
setBadge(count)
Sets the app icon badge count.
function setBadge(count: number): Promise<void>count— The badge number to display on the app icon.
Returns: A promise that resolves when the badge count is set.
setProvider(provider)
Sets the push provider implementation.
function setProvider(provider: PushProvider): voidprovider— The push provider to bond as the active implementation.
Injection Notes
Requirements
Peer dependencies:
@molecule/app-bond^1.0.1@molecule/app-i18n^1.0.1
Runtime Dependencies
@molecule/app-bond@molecule/app-i18nNo wiring is needed on web: the first accessor call silently bonds the built-in Web Push provider. In a native app wire
@molecule/app-push-react-native(the one prebuilt bond) viasetProvider()BEFORE any push call — otherwise the web fallback gets bonded and native registration never happens.Web
register()has three hard prerequisites: (1) HTTPS (secure context), (2) a registered SERVICE WORKER — dev builds typically don't ship one, so register() throws "requires the production app build" (it fails fast instead of hanging), and (3) a VAPID public key (pass viaregister({ vapidPublicKey })) matching your API'sVAPID_PRIVATE_KEY— without it Chrome may register but delivery fails.Request permission from a user gesture at the point of value, never on load — a denied browser prompt is remembered forever (no re-prompt).
Web
scheduleLocalat a future time uses an in-page timer: it does NOT survive reload/close. WebcancelLocal/cancelAllLocalare no-ops, andgetPendingLocal()is always empty — for reliable scheduled delivery send a real push from the server.token.valueon web is a JSON-serialized PushSubscription (not an FCM token) — store it opaquely; platform is intoken.platform.
Translations
Translation strings are provided by @molecule/app-locales-push.
