@gravito/flare 3.3.0 → 4.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 CHANGED
@@ -2,17 +2,20 @@
2
2
 
3
3
  > Lightweight, high-performance notifications for Gravito with multi-channel delivery (mail, database, broadcast, Slack, SMS).
4
4
 
5
- **Status**: v3.3.0 - Production ready with advanced features (Retries, Metrics, Batching).
5
+ **Status**: v3.4.0 - Production ready with advanced features (Retries, Metrics, Batching, Timeout, Rate Limiting, Preference Driver).
6
6
 
7
7
  ## Features
8
8
 
9
9
  - **Zero runtime overhead**: Pure type wrappers that delegate to channel drivers
10
10
  - **Multi-channel delivery**: Mail, database, broadcast, Slack, SMS (Twilio & AWS SNS)
11
11
  - **High Performance**: Parallel channel execution and batch sending capabilities
12
- - **Reliability**: Built-in retry mechanism with exponential backoff
12
+ - **Reliability**: Built-in retry mechanism with exponential backoff and timeout protection
13
13
  - **Observability**: Comprehensive metrics with Prometheus support
14
14
  - **Developer Experience**: Strong typing, lifecycle hooks, and template system
15
- - **Queue support**: Works with `@gravito/stream` for async delivery
15
+ - **Queue support**: Works with `@gravito/stream` for async delivery with Lazy Loading
16
+ - **Rate Limiting**: Channel-level rate limiting with Token Bucket algorithm
17
+ - **Preference Driver**: User notification preferences with automatic channel filtering
18
+ - **Middleware System**: Extensible middleware chain for custom notification processing
16
19
 
17
20
  ## Installation
18
21
 
@@ -144,6 +147,135 @@ class OrderShipped extends TemplatedNotification {
144
147
  }
145
148
  ```
146
149
 
150
+ ### Timeout Protection (v3.4.0)
151
+ All channels support timeout configuration to prevent slow responses from blocking notifications:
152
+
153
+ ```typescript
154
+ OrbitFlare.configure({
155
+ channels: {
156
+ slack: {
157
+ webhookUrl: process.env.SLACK_WEBHOOK_URL,
158
+ timeout: 5000, // 5 秒超時
159
+ onTimeout: (channel, notification) => {
160
+ console.error(`Timeout: ${channel}`)
161
+ }
162
+ }
163
+ }
164
+ })
165
+ ```
166
+
167
+ ### Rate Limiting (v3.4.0)
168
+ Protect downstream services with channel-level rate limiting:
169
+
170
+ ```typescript
171
+ import { RateLimitMiddleware } from '@gravito/flare'
172
+
173
+ const rateLimiter = new RateLimitMiddleware({
174
+ email: {
175
+ maxPerSecond: 10,
176
+ maxPerMinute: 100,
177
+ maxPerHour: 1000
178
+ },
179
+ sms: {
180
+ maxPerSecond: 5
181
+ }
182
+ })
183
+
184
+ notifications.use(rateLimiter)
185
+
186
+ // 檢查狀態
187
+ const status = rateLimiter.getStatus('email')
188
+ console.log(`剩餘: ${status.second}/10`)
189
+ ```
190
+
191
+ ### Lazy Loading for Queue (v3.4.0)
192
+ Optimize queue serialization with Lazy Loading pattern:
193
+
194
+ ```typescript
195
+ import { LazyNotification } from '@gravito/flare'
196
+
197
+ class OrderConfirmation extends LazyNotification<Order> {
198
+ constructor(private orderId: string) {
199
+ super()
200
+ }
201
+
202
+ protected async loadData(notifiable: Notifiable): Promise<Order> {
203
+ return await db.orders.find(this.orderId)
204
+ }
205
+
206
+ via(user: Notifiable): string[] {
207
+ return ['mail', 'database']
208
+ }
209
+
210
+ async toMail(user: Notifiable): Promise<MailMessage> {
211
+ const order = await this.ensureLoaded(user)
212
+ return {
213
+ subject: `訂單確認 #${order.id}`,
214
+ view: 'emails.order-confirmation',
215
+ data: { order },
216
+ to: user.email,
217
+ }
218
+ }
219
+ }
220
+ ```
221
+
222
+ ### User Preferences (v3.4.0)
223
+ Respect user notification preferences automatically:
224
+
225
+ ```typescript
226
+ import { PreferenceMiddleware } from '@gravito/flare'
227
+
228
+ // 方式 1: 在 OrbitFlare 配置中啟用
229
+ OrbitFlare.configure({
230
+ enablePreference: true
231
+ })
232
+
233
+ // 方式 2: 使用自定義偏好提供者
234
+ const preferenceMiddleware = new PreferenceMiddleware({
235
+ async getUserPreferences(notifiable) {
236
+ const prefs = await db.userPreferences.find(notifiable.id)
237
+ return {
238
+ enabledChannels: prefs.enabledChannels,
239
+ disabledChannels: prefs.disabledChannels,
240
+ disabledNotifications: prefs.disabledNotifications
241
+ }
242
+ }
243
+ })
244
+
245
+ notifications.use(preferenceMiddleware)
246
+
247
+ // 方式 3: 在 Notifiable 物件中實作
248
+ class User implements Notifiable {
249
+ async getNotificationPreferences() {
250
+ return {
251
+ enabledChannels: ['email', 'slack'],
252
+ disabledChannels: ['sms']
253
+ }
254
+ }
255
+ }
256
+ ```
257
+
258
+ ### Middleware Chain (v3.4.0)
259
+ Combine multiple middleware for powerful notification processing:
260
+
261
+ ```typescript
262
+ import { RateLimitMiddleware, PreferenceMiddleware } from '@gravito/flare'
263
+
264
+ // 建立中介層
265
+ const rateLimiter = new RateLimitMiddleware({ /* ... */ })
266
+ const preferenceFilter = new PreferenceMiddleware({ /* ... */ })
267
+
268
+ // 註冊中介層(執行順序:由內而外)
269
+ notifications
270
+ .use(rateLimiter) // 先限流
271
+ .use(preferenceFilter) // 後過濾
272
+
273
+ // 或在 OrbitFlare 配置中一次註冊
274
+ OrbitFlare.configure({
275
+ middleware: [rateLimiter, preferenceFilter]
276
+ })
277
+ ```
278
+
147
279
  ## API Reference
148
280
 
149
281
  ### NotificationManager