@vynelix/vynemit-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,400 @@
1
+ # @vynelix/vynemit-core
2
+
3
+ > A framework-agnostic notification system with unified dispatch, storage, and transport layers.
4
+
5
+ ## Features
6
+
7
+ ✨ **Unified Notification Model** - Single interface for in-app, push, email, SMS, and webhooks
8
+ **Event-Based Dispatch** - Reactive system with real-time subscriptions
9
+ πŸ“Š **Read/Unread Tracking** - Built-in state management
10
+ πŸŽ›οΈ **Channel Filters** - User preferences for notification channels
11
+ ⚑ **Queue Support** - Redis, BullMQ, or in-memory queues
12
+ πŸ”Œ **Pluggable Architecture** - Swap storage and transport adapters
13
+ 🎨 **Template System** - Reusable notification templates
14
+ πŸ”„ **Middleware Support** - Rate limiting, deduplication, analytics
15
+ **Zero Dependencies** - Lightweight core with optional adapters
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @vynelix/vynemit-core
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```typescript
26
+ import {
27
+ NotificationCenter,
28
+ MemoryStorageAdapter,
29
+ ConsoleTransportAdapter
30
+ } from '@vynelix/vynemit-core';
31
+
32
+ // Initialize
33
+ const center = new NotificationCenter({
34
+ storage: new MemoryStorageAdapter(),
35
+ transports: [
36
+ new ConsoleTransportAdapter('inapp'),
37
+ new ConsoleTransportAdapter('push')
38
+ ]
39
+ });
40
+
41
+ await center.start();
42
+
43
+ // Send notification
44
+ await center.send({
45
+ userId: 'user:123',
46
+ type: 'comment',
47
+ title: 'New Comment',
48
+ body: 'Someone replied to your post',
49
+ channels: ['inapp', 'push'],
50
+ priority: 'normal'
51
+ });
52
+
53
+ // Subscribe to real-time updates
54
+ center.subscribe('user:123', (notification) => {
55
+ console.log('New notification:', notification);
56
+ });
57
+
58
+ // Get notifications
59
+ const notifications = await center.getForUser('user:123', {
60
+ status: 'unread',
61
+ limit: 10
62
+ });
63
+
64
+ // Mark as read
65
+ await center.markAsRead(notifications[0].id);
66
+ ```
67
+
68
+ ## Core Concepts
69
+
70
+ ### 1. Notification Model
71
+
72
+ Every notification has a consistent structure:
73
+
74
+ ```typescript
75
+ interface Notification {
76
+ id: string;
77
+ type: string; // 'comment', 'like', 'system', etc.
78
+ title: string;
79
+ body: string;
80
+ data?: Record<string, unknown>;
81
+
82
+ userId: string; // Who receives it
83
+ groupId?: string; // Optional grouping
84
+
85
+ priority: 'low' | 'normal' | 'high' | 'urgent';
86
+ category?: string; // For filtering
87
+
88
+ status: 'pending' | 'sent' | 'delivered' | 'failed' | 'read';
89
+ channels: ChannelType[]; // ['inapp', 'push', 'email']
90
+
91
+ createdAt: Date;
92
+ readAt?: Date;
93
+ scheduledFor?: Date;
94
+ expiresAt?: Date;
95
+ }
96
+ ```
97
+
98
+ ### 2. Storage Adapters
99
+
100
+ Storage adapters handle persistence:
101
+
102
+ - `MemoryStorageAdapter` - In-memory (development/testing)
103
+ - `PostgresStorageAdapter` - PostgreSQL (production)
104
+ - `MongoStorageAdapter` - MongoDB
105
+ - `FirestoreStorageAdapter` - Google Firestore
106
+ - `RestStorageAdapter` - External API
107
+
108
+ ### 3. Transport Adapters
109
+
110
+ Transport adapters handle delivery:
111
+
112
+ - `ConsoleTransportAdapter` - Console logging (development)
113
+ - `EmailTransportAdapter` - Email via SMTP/SendGrid
114
+ - `PushTransportAdapter` - Push via Firebase/OneSignal
115
+ - `SmsTransportAdapter` - SMS via Twilio
116
+ - `WebhookTransportAdapter` - Custom webhooks
117
+
118
+ ### 4. Templates
119
+
120
+ Templates make notifications reusable:
121
+
122
+ ```typescript
123
+ center.registerTemplate({
124
+ id: 'new-comment',
125
+ type: 'comment',
126
+ defaults: {
127
+ title: (data) => `${data.author} commented on your post`,
128
+ body: (data) => data.text,
129
+ channels: ['inapp', 'push'],
130
+ priority: 'normal'
131
+ }
132
+ });
133
+
134
+ // Use template
135
+ await center.send({
136
+ template: 'new-comment',
137
+ userId: 'user:123',
138
+ data: { author: 'Alice', text: 'Great post!' }
139
+ });
140
+ ```
141
+
142
+ ### 5. User Preferences
143
+
144
+ Users control which notifications they receive:
145
+
146
+ ```typescript
147
+ await center.updatePreferences('user:123', {
148
+ userId: 'user:123',
149
+ channels: {
150
+ email: {
151
+ enabled: true,
152
+ categories: ['important', 'security'],
153
+ quietHours: {
154
+ start: '22:00',
155
+ end: '08:00'
156
+ }
157
+ },
158
+ push: {
159
+ enabled: true,
160
+ frequency: 'realtime'
161
+ }
162
+ },
163
+ globalMute: false
164
+ });
165
+ ```
166
+
167
+ ### 6. Middleware
168
+
169
+ Extend functionality with middleware:
170
+
171
+ ```typescript
172
+ center.use({
173
+ name: 'rate-limit',
174
+ async beforeSend(notification) {
175
+ // Check rate limits
176
+ const allowed = await checkRateLimit(notification.userId);
177
+ return allowed ? notification : null; // null = skip
178
+ },
179
+ async afterSend(notification) {
180
+ // Track analytics
181
+ await analytics.track('notification_sent', notification);
182
+ },
183
+ async onError(error, notification) {
184
+ // Log errors
185
+ console.error('Failed:', error);
186
+ }
187
+ });
188
+ ```
189
+
190
+ ## Advanced Usage
191
+
192
+ ### Scheduled Notifications
193
+
194
+ ```typescript
195
+ // Send in 1 hour
196
+ await center.schedule({
197
+ userId: 'user:123',
198
+ type: 'reminder',
199
+ title: 'Meeting Soon',
200
+ body: 'Your meeting starts in 15 minutes',
201
+ channels: ['push'],
202
+ priority: 'urgent'
203
+ }, new Date(Date.now() + 3600000));
204
+ ```
205
+
206
+ ### Batch Operations
207
+
208
+ ```typescript
209
+ await center.sendBatch([
210
+ { userId: 'user:1', type: 'update', title: 'A', body: 'B', channels: ['inapp'] },
211
+ { userId: 'user:2', type: 'update', title: 'C', body: 'D', channels: ['inapp'] }
212
+ ]);
213
+ ```
214
+
215
+ ### Real-time Subscriptions
216
+
217
+ ```typescript
218
+ // Subscribe to new notifications
219
+ const unsubscribe = center.subscribe('user:123', (notification) => {
220
+ console.log('New:', notification);
221
+ });
222
+
223
+ // Subscribe to unread count changes
224
+ center.onUnreadCountChange('user:123', (count) => {
225
+ updateBadge(count);
226
+ });
227
+
228
+ // Subscribe to all events
229
+ center.subscribeToEvents('user:123', (event) => {
230
+ console.log(event.type); // 'sent', 'delivered', 'read', 'failed'
231
+ });
232
+
233
+ // Cleanup
234
+ unsubscribe();
235
+ ```
236
+
237
+ ### Digest Mode
238
+
239
+ Batch notifications into digests:
240
+
241
+ ```typescript
242
+ await center.enableDigest('user:123', {
243
+ userId: 'user:123',
244
+ frequency: 'daily',
245
+ channels: ['email'],
246
+ categories: ['social', 'updates']
247
+ });
248
+ ```
249
+
250
+ ### Delivery Status
251
+
252
+ Track delivery across channels:
253
+
254
+ ```typescript
255
+ const receipts = await center.getDeliveryStatus('notif_123');
256
+ receipts.forEach(receipt => {
257
+ console.log(`${receipt.channel}: ${receipt.status}`);
258
+ // inapp: delivered
259
+ // push: delivered
260
+ // email: failed
261
+ });
262
+
263
+ // Retry failed
264
+ await center.retryFailed('notif_123', 'email');
265
+ ```
266
+
267
+ ## Architecture
268
+
269
+ ```
270
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
271
+ β”‚ NotificationCenter (Core) β”‚
272
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
273
+ β”‚ β€’ Event Dispatch β”‚
274
+ β”‚ β€’ Template Management β”‚
275
+ β”‚ β€’ Middleware Pipeline β”‚
276
+ β”‚ β€’ Subscription System β”‚
277
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
278
+ β”‚ β”‚ β”‚
279
+ β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”
280
+ β”‚ Storage β”‚ β”‚ Queue β”‚ β”‚Transportβ”‚
281
+ β”‚ Adapter β”‚ β”‚ Adapter β”‚ β”‚ Adapter β”‚
282
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
283
+ β”‚ β”‚ β”‚
284
+ β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”
285
+ β”‚Postgres β”‚ β”‚ Redis β”‚ β”‚ Firebaseβ”‚
286
+ β”‚ MongoDB β”‚ β”‚ BullMQ β”‚ β”‚ SendGridβ”‚
287
+ β”‚Firestoreβ”‚ β”‚ Memory β”‚ β”‚ Twilio β”‚
288
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
289
+ ```
290
+
291
+ ## Framework Bindings
292
+
293
+ Use framework-specific bindings for seamless integration:
294
+
295
+ ### React
296
+
297
+ ```bash
298
+ npm install @vynelix/vynemit-react
299
+ ```
300
+
301
+ ```tsx
302
+ import { NotificationProvider, useNotifications } from '@vynelix/vynemit-react';
303
+
304
+ function App() {
305
+ return (
306
+ <NotificationProvider apiUrl="/api/notifications" userId="user:123">
307
+ <NotificationBell />
308
+ </NotificationProvider>
309
+ );
310
+ }
311
+
312
+ function NotificationBell() {
313
+ const { notifications, unreadCount, markAsRead } = useNotifications();
314
+
315
+ return (
316
+ <Badge count={unreadCount}>
317
+ <Bell />
318
+ </Badge>
319
+ );
320
+ }
321
+ ```
322
+
323
+ ### NestJS
324
+
325
+ ```bash
326
+ npm install @vynelix/vynemit-nestjs
327
+ ```
328
+
329
+ ```typescript
330
+ import { NotificationsModule } from '@vynelix/vynemit-nestjs';
331
+
332
+ @Module({
333
+ imports: [
334
+ NotificationsModule.forRoot({
335
+ storage: new PostgresStorageAdapter(),
336
+ transports: [new EmailTransportAdapter(), new PushTransportAdapter()]
337
+ })
338
+ ]
339
+ })
340
+ export class AppModule {}
341
+
342
+ @Injectable()
343
+ export class UserService {
344
+ constructor(private notifications: NotificationCenter) {}
345
+
346
+ async welcomeUser(userId: string) {
347
+ await this.notifications.send({
348
+ userId,
349
+ type: 'welcome',
350
+ title: 'Welcome!',
351
+ body: 'Thanks for joining',
352
+ channels: ['inapp', 'email']
353
+ });
354
+ }
355
+ }
356
+ ```
357
+
358
+ ### Flutter
359
+
360
+ ```bash
361
+ flutter pub add synq_notifications
362
+ ```
363
+
364
+ ```dart
365
+ import 'package:synq_notifications/synq_notifications.dart';
366
+
367
+ final notificationCenter = NotificationCenter(
368
+ storage: MemoryStorageAdapter(),
369
+ transports: [ConsoleTransportAdapter()]
370
+ );
371
+
372
+ // Subscribe
373
+ notificationCenter.subscribe('user:123', (notification) {
374
+ print('New: ${notification.title}');
375
+ });
376
+
377
+ // Send
378
+ await notificationCenter.send(
379
+ userId: 'user:123',
380
+ type: 'comment',
381
+ title: 'New Comment',
382
+ body: 'Someone replied',
383
+ channels: ['inapp']
384
+ );
385
+ ```
386
+
387
+ ## License
388
+
389
+ MIT Β© [Your Name]
390
+
391
+ ## Contributing
392
+
393
+ Contributions welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
394
+
395
+ ## Support
396
+
397
+ - πŸ“§ Email: support@synq.dev
398
+ - πŸ’¬ Discord: [Join our community](https://discord.gg/synq)
399
+ - πŸ“– Docs: [docs.synq.dev](https://docs.synq.dev)
400
+ - πŸ› Issues: [GitHub Issues](https://github.com/yourusername/synq-notifications/issues)