npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@molecule/app-push

v1.0.2

Published

Client-side push notifications interface for molecule.dev

Downloads

1,751

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.ts JSDoc, 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-i18n

API

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) => void

NotificationReceivedListener

Listener invoked when a push notification is received.

type NotificationReceivedListener = (event: NotificationReceivedEvent) => void

PermissionStatus

Push notification permission status.

type PermissionStatus = 'granted' | 'denied' | 'default' | 'prompt'

TokenChangeListener

Token Change Listener type.

type TokenChangeListener = (token: PushToken) => void

Functions

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): PushProvider
  • vapidPublicKey — 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(): PushProvider

Returns: 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(): boolean

Returns: Whether a push provider is currently registered.

onNotificationAction(listener)

Subscribes to notification action events (taps, button clicks).

function onNotificationAction(listener: NotificationActionListener): () => void
  • listener — 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): () => void
  • listener — 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): void
  • provider — 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-i18n

  • No 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) via setProvider() 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 via register({ vapidPublicKey })) matching your API's VAPID_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 scheduleLocal at a future time uses an in-page timer: it does NOT survive reload/close. Web cancelLocal/cancelAllLocal are no-ops, and getPendingLocal() is always empty — for reliable scheduled delivery send a real push from the server.

  • token.value on web is a JSON-serialized PushSubscription (not an FCM token) — store it opaquely; platform is in token.platform.

Translations

Translation strings are provided by @molecule/app-locales-push.