{"_id":"@allmightypush/push","name":"@allmightypush/push","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@allmightypush/push","version":"1.0.0","description":"Modular TypeScript-first push notification library for Node.js","main":"dist/cjs/index.js","module":"dist/esm/index.js","types":"dist/types/index.d.ts","exports":{".":{"require":"./dist/cjs/index.js","import":"./dist/esm/index.js","types":"./dist/types/index.d.ts"}},"scripts":{"build":"npm run build:cjs && npm run build:esm && npm run build:types","build:cjs":"tsc -p tsconfig.cjs.json","build:esm":"tsc -p tsconfig.esm.json","build:types":"tsc -p tsconfig.types.json","test":"jest --passWithNoTests","test:watch":"jest --watch","test:coverage":"jest --coverage --passWithNoTests","clean":"rm -rf dist"},"keywords":["push","notification","webpush","vapid","typescript","nodejs"],"author":{"name":"Samtes64"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Samtes64/all-mighty-push.git","directory":"packages/push"},"bugs":{"url":"https://github.com/Samtes64/all-mighty-push/issues"},"homepage":"https://github.com/Samtes64/all-mighty-push/tree/main/packages/push#readme","dependencies":{"@allmightypush/push-core":"^1.0.0","@allmightypush/push-webpush":"^1.0.0","@allmightypush/push-storage-sqlite":"^1.0.0"},"engines":{"node":">=16.0.0"},"_id":"@allmightypush/push@1.0.0","gitHead":"8d7b012f519f95515344d9b5c96d4ba42039046b","_nodeVersion":"22.19.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-M+3KohhKCdyDN4DhmA5G2tNexWC1iRKaqJzcyvK27h1iK4QlfeLXeNCULs59hLwRY7jXUsolFctbHRyGMFa+hQ==","shasum":"412ea26b4fd535323838f253d3acb0040d8d9e66","tarball":"https://registry.npmjs.org/@allmightypush/push/-/push-1.0.0.tgz","fileCount":8,"unpackedSize":10156,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCID/TgVMtFf5cO0Nr7uUSmUvuEIn6MujH275ZAm4Jq4roAiB9Difas4BegXd6WCRwYwy6h8NNWeyXTxJmnCi+1S8hQw=="}]},"_npmUser":{"name":"samtes64","email":"samtes64@gmail.com"},"directories":{},"maintainers":[{"name":"samtes64","email":"samtes64@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/push_1.0.0_1768561655733_0.6512686543219988"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-16T11:07:35.631Z","1.0.0":"2026-01-16T11:07:35.909Z","modified":"2026-01-16T11:07:36.453Z"},"maintainers":[{"name":"samtes64","email":"samtes64@gmail.com"}],"description":"Modular TypeScript-first push notification library for Node.js","homepage":"https://github.com/Samtes64/all-mighty-push/tree/main/packages/push#readme","keywords":["push","notification","webpush","vapid","typescript","nodejs"],"repository":{"type":"git","url":"git+https://github.com/Samtes64/all-mighty-push.git","directory":"packages/push"},"author":{"name":"Samtes64"},"bugs":{"url":"https://github.com/Samtes64/all-mighty-push/issues"},"license":"MIT","readme":"# @allmightypush/push\n\n> Modular, TypeScript-first push notification library for Node.js with Web Push (VAPID) support\n\n## Features\n\n- 🚀 **Production-ready** - Comprehensive error handling and retry logic\n- 📦 **Modular** - Use only what you need with pluggable adapters\n- 🔒 **Type-safe** - Full TypeScript support with strict mode\n- ⚡ **Reliable** - Circuit breaker, rate limiting, and exponential backoff\n- 🔄 **Automatic retries** - Background worker for failed notifications\n- 🎯 **Batch sending** - Efficient bulk notification delivery\n- 📊 **Observable** - Lifecycle hooks and metrics integration\n- 🛡️ **Graceful shutdown** - No data loss on termination\n\n## Installation\n\n```bash\nnpm install @allmightypush/push\n```\n\nThis meta-package includes:\n- `@allmightypush/push-core` - Core runtime engine\n- `@allmightypush/push-webpush` - Web Push (VAPID) provider\n- `@allmightypush/push-storage-sqlite` - SQLite storage adapter\n\n## Quick Start\n\n```typescript\nimport { PushCore, RetryWorker, SQLiteStorageAdapter, WebPushProvider } from '@allmightypush/push';\n\n// 1. Configure the push system\nconst pushCore = new PushCore();\nconst storage = new SQLiteStorageAdapter({ filename: './push.db' });\n\npushCore.configure({\n  vapidKeys: {\n    publicKey: 'your-vapid-public-key',\n    privateKey: 'your-vapid-private-key',\n    subject: 'mailto:admin@example.com',\n  },\n  storageAdapter: storage,\n});\n\n// 2. Create a subscription\nconst subscription = await storage.createSubscription({\n  endpoint: 'https://fcm.googleapis.com/fcm/send/...',\n  keys: {\n    p256dh: 'user-public-key',\n    auth: 'user-auth-secret',\n  },\n  status: 'active',\n});\n\n// 3. Send a notification\nconst result = await pushCore.sendNotification(subscription, {\n  title: 'Hello!',\n  body: 'This is a push notification',\n  icon: '/icon.png',\n  data: { url: '/news/article-1' },\n});\n\nconsole.log('Notification sent:', result.success);\n\n// 4. Start worker for retry processing (optional)\nconst worker = new RetryWorker(\n  storage,\n  new WebPushProvider({\n    vapidPublicKey: 'your-vapid-public-key',\n    vapidPrivateKey: 'your-vapid-private-key',\n    vapidSubject: 'mailto:admin@example.com',\n  }),\n  {\n    maxRetries: 8,\n    baseDelay: 1000,\n    backoffFactor: 2,\n    maxDelay: 3600000,\n    jitter: true,\n  }\n);\n\nawait worker.start();\n\n// 5. Graceful shutdown\nprocess.on('SIGTERM', async () => {\n  await worker.stop();\n  await pushCore.shutdown();\n  process.exit(0);\n});\n```\n\n## Batch Sending\n\n```typescript\nconst subscriptions = await storage.findSubscriptions({ status: 'active' });\n\nconst result = await pushCore.batchSend(subscriptions, {\n  title: 'Breaking News',\n  body: 'Important update for all users',\n});\n\nconsole.log(`Sent to ${result.success}/${result.total} subscriptions`);\nconsole.log(`Failed: ${result.failed}, Retried: ${result.retried}`);\n```\n\n## Advanced Configuration\n\n```typescript\npushCore.configure({\n  vapidKeys: {\n    publicKey: process.env.VAPID_PUBLIC_KEY!,\n    privateKey: process.env.VAPID_PRIVATE_KEY!,\n    subject: 'mailto:admin@example.com',\n  },\n  storageAdapter: storage,\n  \n  // Retry policy\n  retryPolicy: {\n    maxRetries: 8,\n    baseDelay: 1000,\n    backoffFactor: 2,\n    maxDelay: 3600000,\n    jitter: true,\n  },\n  \n  // Circuit breaker\n  circuitBreaker: {\n    failureThreshold: 5,\n    resetTimeout: 60000,\n    halfOpenMaxAttempts: 3,\n  },\n  \n  // Batch configuration\n  batchConfig: {\n    batchSize: 50,\n    concurrency: 10,\n  },\n  \n  // Lifecycle hooks\n  lifecycleHooks: {\n    onSend: async (subscription, payload) => {\n      console.log('Sending to:', subscription.id);\n    },\n    onSuccess: async (subscription, result) => {\n      console.log('Success:', subscription.id);\n    },\n    onFailure: async (subscription, error) => {\n      console.error('Failed:', subscription.id, error);\n    },\n    onRetry: async (subscription, attempt) => {\n      console.log('Retry attempt:', attempt, 'for:', subscription.id);\n    },\n  },\n});\n```\n\n## Generating VAPID Keys\n\n```typescript\nimport { generateVapidKeys } from '@allmightypush/push';\n\nconst vapidKeys = generateVapidKeys();\nconsole.log('Public Key:', vapidKeys.publicKey);\nconsole.log('Private Key:', vapidKeys.privateKey);\n\n// Save these keys securely - you'll need them for all notifications\n```\n\n## Storage Adapters\n\n### SQLite (included)\n```typescript\nimport { SQLiteStorageAdapter } from '@allmightypush/push';\n\nconst storage = new SQLiteStorageAdapter({\n  filename: './push.db',\n});\n```\n\n### PostgreSQL (separate package)\n```bash\nnpm install @allmightypush/push-storage-postgres\n```\n\n### MongoDB (separate package)\n```bash\nnpm install @allmightypush/push-storage-mongo\n```\n\n## API Reference\n\n### PushCore\n\n#### `configure(options: PushConfiguration): void`\nConfigure the push notification system.\n\n#### `sendNotification(subscription: Subscription, payload: NotificationPayload, options?: SendOptions): Promise<SendResult>`\nSend a notification to a single subscription.\n\n#### `batchSend(subscriptions: Subscription[], payload: NotificationPayload, options?: SendOptions): Promise<BatchResult>`\nSend notifications to multiple subscriptions efficiently.\n\n#### `verifySubscription(subscription: Subscription): Promise<void>`\nVerify that a subscription is valid.\n\n#### `shutdown(timeout?: number): Promise<void>`\nGracefully shutdown the system.\n\n### RetryWorker\n\n#### `start(): Promise<void>`\nStart the worker polling loop.\n\n#### `stop(): Promise<void>`\nStop the worker gracefully.\n\n#### `isRunning(): boolean`\nCheck if the worker is running.\n\n## Error Handling\n\nThe library provides typed errors for different scenarios:\n\n```typescript\nimport { \n  ConfigurationError,\n  ValidationError,\n  ProviderError,\n  StorageError,\n  CircuitBreakerOpenError,\n  RateLimitError\n} from '@allmightypush/push';\n\ntry {\n  await pushCore.sendNotification(subscription, payload);\n} catch (error) {\n  if (error instanceof ValidationError) {\n    console.error('Invalid subscription:', error.message);\n  } else if (error instanceof CircuitBreakerOpenError) {\n    console.error('Circuit breaker is open, try again later');\n  } else if (error instanceof ProviderError) {\n    console.error('Provider error:', error.statusCode);\n  }\n}\n```\n\n## Testing\n\nThe library includes 230+ tests with ~90% coverage:\n\n```bash\nnpm test\n```\n\n## License\n\nMIT\n\n## Contributing\n\nContributions welcome! Please read our contributing guidelines first.\n\n## Support\n\n- 📖 [Documentation](https://github.com/samtes64/all-mighty-push)\n- 🐛 [Issue Tracker](https://github.com/samtes64/all-mighty-push/issues)\n- 💬 [Discussions](https://github.com/samtes64/all-mighty-push/discussions)\n","readmeFilename":"README.md","_rev":"1-56679e1ca9b13e4c0d61dc5d9d25948c"}