Production-ready, modular push notification system for Node.js with TypeScript support
A comprehensive push notification library built with TypeScript that provides:
- 🚀 Production-ready core runtime with 230+ tests
- 📦 Modular architecture with pluggable adapters
- 🔒 Type-safe with full TypeScript support
- ⚡ Reliable with circuit breaker, rate limiting, and retry logic
- 🔄 Automatic retries via background worker
- 🎯 Batch sending with concurrency control
- 📊 Observable with lifecycle hooks and metrics
- 🛡️ Graceful shutdown support
npm install @allmightypush/pushimport { PushCore, SQLiteStorageAdapter } from '@allmightypush/push';
const pushCore = new PushCore();
const storage = new SQLiteStorageAdapter({ filename: './push.db' });
pushCore.configure({
vapidKeys: {
publicKey: 'your-vapid-public-key',
privateKey: 'your-vapid-private-key',
subject: 'mailto:admin@example.com',
},
storageAdapter: storage,
});
// Send notification
const result = await pushCore.sendNotification(subscription, {
title: 'Hello!',
body: 'This is a push notification',
});┌─────────────────────────────────────────────────────────────┐
│ Application Code │
└────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ PushCore │
│ • Configuration Management │
│ • Notification Sending (Single & Batch) │
│ • Retry Enqueuing │
│ • Lifecycle Hooks │
└─────┬──────────┬──────────┬──────────┬─────────────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌──────────┐ ┌────────┐ ┌────────┐ ┌──────────┐
│ Storage │ │Provider│ │Circuit │ │ Rate │
│ Adapter │ │Adapter │ │Breaker │ │ Limiter │
└──────────┘ └────────┘ └────────┘ └──────────┘
│ │
▼ ▼
┌──────────┐ ┌────────┐
│ SQLite/ │ │ Web │
│Postgres/ │ │ Push │
│ MongoDB │ │ (VAPID)│
└──────────┘ └────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ RetryWorker │
│ • Background Polling │
│ • Retry Processing │
│ • Concurrency Control │
└─────────────────────────────────────────────────────────────┘
This monorepo contains the following packages:
- @allmightypush/push - Meta-package with all core functionality
- @allmightypush/push-core - Core runtime engine (128 tests)
- @allmightypush/push-webpush - Web Push (VAPID) provider (21 tests)
- @allmightypush/push-storage-sqlite - SQLite adapter (67 tests)
- @allmightypush/push-storage-postgres - PostgreSQL adapter
- @allmightypush/push-storage-mongo - MongoDB adapter
- @allmightypush/push-cli - Command-line interface
- Configuration Management - Flexible configuration with sensible defaults
- Single & Batch Sending - Send to one or thousands of subscribers
- Subscription Verification - Validate subscription structure
- Graceful Shutdown - Clean termination without data loss
- Exponential Backoff - Automatic retry with jitter (±25%)
- Circuit Breaker - Prevent cascading failures
- Rate Limiting - Token bucket algorithm
- Max Retries - Configurable retry limits
- Retry-After - Respect server backoff headers
- Background Processing - Async retry queue processing
- Concurrency Control - Configurable parallel operations
- Graceful Shutdown - Wait for in-flight operations
- Error Handling - Automatic backoff on errors
- Lifecycle Hooks - onSend, onSuccess, onFailure, onRetry
- Metrics Integration - Pluggable metrics adapter
- Queue Statistics - Monitor retry queue health
- Detailed Errors - Typed error classes with context
- Node.js >= 16.0.0
- npm >= 7.0.0
# Install dependencies
npm install
# Build all packages
npm run build
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Lint code
npm run lint
# Format code
npm run format.
├── packages/
│ ├── push/ # Meta-package
│ ├── push-core/ # Core runtime (2000+ lines, 128 tests)
│ │ ├── src/
│ │ │ ├── core/ # PushCore class
│ │ │ ├── worker/ # RetryWorker class
│ │ │ ├── circuit-breaker/
│ │ │ ├── rate-limiter/
│ │ │ ├── retry/ # Retry logic
│ │ │ ├── vapid/ # VAPID key management
│ │ │ └── types/ # TypeScript types
│ │ └── __tests__/ # Test suites
│ ├── push-webpush/ # Web Push provider (200+ lines, 21 tests)
│ ├── push-storage-sqlite/ # SQLite adapter (400+ lines, 67 tests)
│ ├── push-storage-postgres/ # PostgreSQL adapter
│ ├── push-storage-mongo/ # MongoDB adapter
│ └── push-cli/ # CLI tool
documents
│ └── all-mighty-push/
│ ├── requirements.md # 20 requirements, 100 acceptance criteria
│ ├── design.md # Architecture & design patterns
│ └── tasks.md # 24 implementation tasks
└── README.md
The library has comprehensive test coverage:
# Run all tests
npm test
# Run tests for specific package
npm test --workspace=@allmightypush/push-core
# Run with coverage
npm run test:coverage
# Watch mode
npm run test:watch- Total Tests: 230+
- Coverage: ~90%
- Test Suites: 9
- Test Types: Unit, Integration, End-to-End
- API Reference - Complete API documentation
import { PushCore, SQLiteStorageAdapter } from '@allmightypush/push';
const pushCore = new PushCore();
pushCore.configure({
vapidKeys: {
publicKey: process.env.VAPID_PUBLIC_KEY!,
privateKey: process.env.VAPID_PRIVATE_KEY!,
},
storageAdapter: new SQLiteStorageAdapter({ filename: './push.db' }),
});
await pushCore.sendNotification(subscription, {
title: 'Hello!',
body: 'This is a notification',
});import { RetryWorker, WebPushProvider } from '@allmightypush/push';
const worker = new RetryWorker(
storage,
new WebPushProvider({ /* config */ }),
{ maxRetries: 8, baseDelay: 1000 }
);
await worker.start();const subscriptions = await storage.findSubscriptions({ status: 'active' });
const result = await pushCore.batchSend(subscriptions, {
title: 'Breaking News',
body: 'Important update',
});
console.log(`Success: ${result.success}/${result.total}`);pushCore.configure({
// ... other config
lifecycleHooks: {
onSend: async (sub, payload) => console.log('Sending...'),
onSuccess: async (sub, result) => console.log('Success!'),
onFailure: async (sub, error) => console.error('Failed:', error),
onRetry: async (sub, attempt) => console.log(`Retry ${attempt}`),
},
});- Batch Processing: 50 notifications per batch (configurable)
- Concurrency: 10 concurrent operations (configurable)
- Rate Limiting: Token bucket with configurable refill rate
- Memory: Efficient in-memory tracking of in-flight operations
- Database: Indexed queries for fast subscription lookup
VAPID_PUBLIC_KEY=your-public-key
VAPID_PRIVATE_KEY=your-private-key
VAPID_SUBJECT=mailto:admin@example.com
DATABASE_URL=./push.dbFROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]process.on('SIGTERM', async () => {
console.log('Shutting down gracefully...');
await worker.stop();
await pushCore.shutdown(30000); // 30 second timeout
process.exit(0);
});- Core runtime engine
- SQLite storage adapter
- Web Push provider
- Retry logic with exponential backoff
- Circuit breaker
- Rate limiter
- Worker process
- Graceful shutdown
- Comprehensive testing (230+ tests)
- Express middleware
- PostgreSQL adapter
- MongoDB adapter
- CLI tool
- Documentation site
- Demo application
Contributions are welcome! Please read our Contributing Guide first.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT © samtes64
- Built with TypeScript
- Uses web-push for VAPID
- Tested with Jest
- Inspired by best practices from production push notification systems
- 📖 Documentation
- 🐛 Issue Tracker
- 💬 Discussions
- 📧 Email: samtes64@gmail.com
Made with ❤️ by Samuel