Skip to content

Releases: nkemtasoft/local-push

Release list

v0.2.0

Choose a tag to compare

@nkemtasoft nkemtasoft released this 25 Feb 18:56

Changelog

[0.2.0] — 2026-02-25

Bug fixes

Container stops instantly now.
The server previously had no signal handlers. When docker stop (or any process manager) sent SIGTERM, Node ignored it, forcing Docker to wait out its full timeout before issuing SIGKILL. The fix adds SIGTERM and SIGINT handlers that close all open SSE connections first (which were the main blocker — they are long-lived keep-alive HTTP responses), then drain remaining connections via server.close(), with a 5-second forced-exit safety net.

New features

Full real-time dashboard sync

The dashboard previously only received new push notifications over SSE. Deletes and subscription changes required a page refresh or waited for the 10-second poll. The dashboard now stays fully in sync with the server for all state changes via six new SSE event types:

Event When it fires
message:deleted A single message is deleted
messages:cleared All messages are deleted
subscription:created A new subscription is created
subscription:deleted A subscription is deleted
subscriptions:cleared All subscriptions are deleted

The 10-second subscription polling interval has been removed.

Subscriptions tab

The dashboard now has a dedicated Subscriptions tab alongside the Messages tab. It shows all active subscriptions with their message count and creation time. Selecting a subscription shows its full details in the right panel — endpoint URL, p256dh key, auth secret, and the complete subscription JSON object ready to paste directly into a web-push sendNotification() call. A + New Subscription button creates one without leaving the dashboard.

Delete from the dashboard

  • Every message row and subscription row now has a × delete button (appears on hover) that removes it immediately via the API. The SSE event updates the list in real time — no optimistic UI needed.
  • The detail panel for both messages and subscriptions also includes a delete button.

SSE auto-reconnect

If the SSE connection drops (e.g. server restart), the dashboard detects the disconnect, shows a "Reconnecting…" status, and re-fetches all messages and subscriptions once the connection is restored so no state is lost.

Toast notifications

A non-blocking toast slides in at the top-right whenever a new push notification arrives, showing a preview of the message content. Toasts also appear for reconnect events and other actions.

Copy buttons

The message and subscription detail panels now have Copy buttons next to every field worth copying — message ID, subscription ID, endpoint URL, p256dh, auth, payload JSON, raw payload, and the full subscription JSON. Clicking shows a brief "Copied!" confirmation.

Relative timestamps

Message and subscription rows now show human-friendly relative times ("just now", "5m ago", "2h ago") instead of raw ISO strings. They refresh every 30 seconds automatically.

Internal changes

  • Extracted SSE state and broadcast logic into a dedicated src/server/services/sse.ts module so both message-store.ts and subscription-manager.ts can broadcast events without circular dependencies.
  • Added 6 new integration tests covering every SSE event type, using a fetch-streaming helper that correctly races SSE connection setup with the triggering action.

[0.1.0] — 2026-02-24

Initial release.

v0.1.0

Choose a tag to compare

@nkemtasoft nkemtasoft released this 24 Feb 16:15

v0.1.0 — Initial Release

Local Web Push notification testing service — like Mailpit, but for VAPID web push.

What is local-push?

A drop-in local replacement for browser push services (FCM, Mozilla, etc.) that lets you send, receive, and inspect web push notifications without a browser or third-party service. Zero changes to your backend code.

Features

  • Push endpoint — receives encrypted payloads from the web-push npm library and decrypts them automatically (AES-128-GCM / aesgcm)
  • Dashboard — built-in web UI with real-time updates (SSE), JSON syntax highlighting, dark/light mode
  • REST API — full CRUD for subscriptions and messages, SSE event stream, health check
  • Client SDK — @nkemtasoft/local-push/client with waitForMessage() for integration tests
  • Docker ready — single image, single port, no external dependencies
  • Self-signed TLS — generated on startup (web-push requires HTTPS)

Quick Start

# Docker
docker run -p 4078:4078 ghcr.io/nkemtasoft/local-push

# npx
npx @nkemtasoft/local-push

# SDK
yarn add -D @nkemtasoft/local-push

Example

import { LocalWebPushClient } from "@nkemtasoft/local-push/client";

const client = new LocalWebPushClient({ url: "https://localhost:4078" });
const { subscription } = await client.createSubscription();

// Use subscription in your DB, send a push from your backend, then:
const msg = await client.waitForMessage({ timeout: 5000 });
console.log(msg.payload);

See the README for full documentation.