alepha 0.11.7 → 0.11.10

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.
Files changed (169) hide show
  1. package/README.md +55 -17
  2. package/dist/index.cjs +15805 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +1 -0
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.js +15804 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +36 -372
  9. package/src/assets/biomeJson.ts +33 -0
  10. package/src/assets/tsconfigJson.ts +17 -0
  11. package/src/assets/viteConfigTs.ts +14 -0
  12. package/src/commands/BiomeCommands.ts +60 -0
  13. package/src/commands/CoreCommands.ts +266 -0
  14. package/src/commands/DrizzleCommands.ts +403 -0
  15. package/src/commands/VerifyCommands.ts +48 -0
  16. package/src/commands/ViteCommands.ts +152 -0
  17. package/src/index.ts +35 -0
  18. package/src/services/ProcessRunner.ts +89 -0
  19. package/src/version.ts +7 -0
  20. package/api/files.cjs +0 -8
  21. package/api/files.d.ts +0 -438
  22. package/api/files.js +0 -1
  23. package/api/jobs.cjs +0 -8
  24. package/api/jobs.d.ts +0 -327
  25. package/api/jobs.js +0 -1
  26. package/api/notifications.cjs +0 -8
  27. package/api/notifications.d.ts +0 -263
  28. package/api/notifications.js +0 -1
  29. package/api/users.cjs +0 -8
  30. package/api/users.d.ts +0 -923
  31. package/api/users.js +0 -1
  32. package/api/verifications.cjs +0 -8
  33. package/api/verifications.d.ts +0 -1
  34. package/api/verifications.js +0 -1
  35. package/batch.cjs +0 -8
  36. package/batch.d.ts +0 -154
  37. package/batch.js +0 -1
  38. package/bucket.cjs +0 -8
  39. package/bucket.d.ts +0 -520
  40. package/bucket.js +0 -1
  41. package/cache/redis.cjs +0 -8
  42. package/cache/redis.d.ts +0 -40
  43. package/cache/redis.js +0 -1
  44. package/cache.cjs +0 -8
  45. package/cache.d.ts +0 -288
  46. package/cache.js +0 -1
  47. package/command.cjs +0 -8
  48. package/command.d.ts +0 -269
  49. package/command.js +0 -1
  50. package/core.cjs +0 -8
  51. package/core.d.ts +0 -1904
  52. package/core.js +0 -1
  53. package/datetime.cjs +0 -8
  54. package/datetime.d.ts +0 -144
  55. package/datetime.js +0 -1
  56. package/devtools.cjs +0 -8
  57. package/devtools.d.ts +0 -252
  58. package/devtools.js +0 -1
  59. package/email.cjs +0 -8
  60. package/email.d.ts +0 -187
  61. package/email.js +0 -1
  62. package/fake.cjs +0 -8
  63. package/fake.d.ts +0 -73
  64. package/fake.js +0 -1
  65. package/file.cjs +0 -8
  66. package/file.d.ts +0 -528
  67. package/file.js +0 -1
  68. package/lock/redis.cjs +0 -8
  69. package/lock/redis.d.ts +0 -24
  70. package/lock/redis.js +0 -1
  71. package/lock.cjs +0 -8
  72. package/lock.d.ts +0 -552
  73. package/lock.js +0 -1
  74. package/logger.cjs +0 -8
  75. package/logger.d.ts +0 -287
  76. package/logger.js +0 -1
  77. package/postgres.cjs +0 -8
  78. package/postgres.d.ts +0 -2143
  79. package/postgres.js +0 -1
  80. package/queue/redis.cjs +0 -8
  81. package/queue/redis.d.ts +0 -29
  82. package/queue/redis.js +0 -1
  83. package/queue.cjs +0 -8
  84. package/queue.d.ts +0 -760
  85. package/queue.js +0 -1
  86. package/react/auth.cjs +0 -8
  87. package/react/auth.d.ts +0 -504
  88. package/react/auth.js +0 -1
  89. package/react/form.cjs +0 -8
  90. package/react/form.d.ts +0 -211
  91. package/react/form.js +0 -1
  92. package/react/head.cjs +0 -8
  93. package/react/head.d.ts +0 -120
  94. package/react/head.js +0 -1
  95. package/react/i18n.cjs +0 -8
  96. package/react/i18n.d.ts +0 -168
  97. package/react/i18n.js +0 -1
  98. package/react.cjs +0 -8
  99. package/react.d.ts +0 -1263
  100. package/react.js +0 -1
  101. package/redis.cjs +0 -8
  102. package/redis.d.ts +0 -82
  103. package/redis.js +0 -1
  104. package/retry.cjs +0 -8
  105. package/retry.d.ts +0 -162
  106. package/retry.js +0 -1
  107. package/router.cjs +0 -8
  108. package/router.d.ts +0 -45
  109. package/router.js +0 -1
  110. package/scheduler.cjs +0 -8
  111. package/scheduler.d.ts +0 -145
  112. package/scheduler.js +0 -1
  113. package/security.cjs +0 -8
  114. package/security.d.ts +0 -586
  115. package/security.js +0 -1
  116. package/server/cache.cjs +0 -8
  117. package/server/cache.d.ts +0 -163
  118. package/server/cache.js +0 -1
  119. package/server/compress.cjs +0 -8
  120. package/server/compress.d.ts +0 -38
  121. package/server/compress.js +0 -1
  122. package/server/cookies.cjs +0 -8
  123. package/server/cookies.d.ts +0 -144
  124. package/server/cookies.js +0 -1
  125. package/server/cors.cjs +0 -8
  126. package/server/cors.d.ts +0 -45
  127. package/server/cors.js +0 -1
  128. package/server/health.cjs +0 -8
  129. package/server/health.d.ts +0 -58
  130. package/server/health.js +0 -1
  131. package/server/helmet.cjs +0 -8
  132. package/server/helmet.d.ts +0 -98
  133. package/server/helmet.js +0 -1
  134. package/server/links.cjs +0 -8
  135. package/server/links.d.ts +0 -322
  136. package/server/links.js +0 -1
  137. package/server/metrics.cjs +0 -8
  138. package/server/metrics.d.ts +0 -35
  139. package/server/metrics.js +0 -1
  140. package/server/multipart.cjs +0 -8
  141. package/server/multipart.d.ts +0 -42
  142. package/server/multipart.js +0 -1
  143. package/server/proxy.cjs +0 -8
  144. package/server/proxy.d.ts +0 -234
  145. package/server/proxy.js +0 -1
  146. package/server/security.cjs +0 -8
  147. package/server/security.d.ts +0 -92
  148. package/server/security.js +0 -1
  149. package/server/static.cjs +0 -8
  150. package/server/static.d.ts +0 -119
  151. package/server/static.js +0 -1
  152. package/server/swagger.cjs +0 -8
  153. package/server/swagger.d.ts +0 -161
  154. package/server/swagger.js +0 -1
  155. package/server.cjs +0 -8
  156. package/server.d.ts +0 -849
  157. package/server.js +0 -1
  158. package/topic/redis.cjs +0 -8
  159. package/topic/redis.d.ts +0 -42
  160. package/topic/redis.js +0 -1
  161. package/topic.cjs +0 -8
  162. package/topic.d.ts +0 -819
  163. package/topic.js +0 -1
  164. package/ui.cjs +0 -8
  165. package/ui.d.ts +0 -813
  166. package/ui.js +0 -1
  167. package/vite.cjs +0 -8
  168. package/vite.d.ts +0 -186
  169. package/vite.js +0 -1
package/topic.d.ts DELETED
@@ -1,819 +0,0 @@
1
- import * as _alepha_core1 from "alepha";
2
- import { Alepha, Descriptor, KIND, Service, Static, TSchema } from "alepha";
3
- import { DateTimeProvider, DurationLike } from "alepha/datetime";
4
- import * as _alepha_logger0 from "alepha/logger";
5
-
6
- //#region src/providers/TopicProvider.d.ts
7
- /**
8
- * Base class for topic providers.
9
- */
10
- declare abstract class TopicProvider {
11
- protected readonly alepha: Alepha;
12
- /**
13
- * Publish a message to a topic.
14
- *
15
- * @param topic - The topic to publish to.
16
- * @param message - The message to publish.
17
- */
18
- abstract publish(topic: string, message: string): Promise<void>;
19
- /**
20
- * Subscribe to a topic.
21
- *
22
- * @param topic - The topic to subscribe to.
23
- * @param callback - The callback to call when a message is received.
24
- */
25
- abstract subscribe(topic: string, callback: SubscribeCallback): Promise<UnSubscribeFn>;
26
- /**
27
- * Unsubscribe from a topic.
28
- *
29
- * @param topic - The topic to unsubscribe from.
30
- */
31
- abstract unsubscribe(topic: string): Promise<void>;
32
- /**
33
- * Returns the list of $subscribers for this provider.
34
- */
35
- protected subscribers(): Array<() => Promise<unknown>>;
36
- }
37
- type SubscribeCallback = (message: string) => Promise<void> | void;
38
- type UnSubscribeFn = () => Promise<void>;
39
- //#endregion
40
- //#region src/descriptors/$topic.d.ts
41
- /**
42
- * Creates a topic descriptor for pub/sub messaging and event-driven architecture.
43
- *
44
- * This descriptor provides a powerful publish/subscribe system that enables decoupled communication
45
- * between different parts of your application. Topics allow multiple publishers to send messages
46
- * and multiple subscribers to receive them, creating flexible event-driven architectures with
47
- * support for real-time messaging and asynchronous event processing.
48
- *
49
- * **Key Features**
50
- *
51
- * - **Publish/Subscribe Pattern**: Decoupled communication between publishers and subscribers
52
- * - **Multiple Subscribers**: One-to-many message distribution with automatic fan-out
53
- * - **Type-Safe Messages**: Full TypeScript support with schema validation using TypeBox
54
- * - **Real-time Processing**: Immediate message delivery to active subscribers
55
- * - **Event Filtering**: Subscribe to specific message types using filter functions
56
- * - **Timeout Support**: Wait for specific messages with configurable timeouts
57
- * - **Multiple Backends**: Support for in-memory, Redis, and custom topic providers
58
- * - **Error Resilience**: Built-in error handling and message processing recovery
59
- *
60
- * **Use Cases**
61
- *
62
- * Perfect for event-driven architectures and real-time communication:
63
- * - User activity notifications
64
- * - Real-time chat and messaging systems
65
- * - System event broadcasting
66
- * - Microservice communication
67
- * - Live data updates and synchronization
68
- * - Application state change notifications
69
- * - Webhook and external API event handling
70
- *
71
- * @example
72
- * **Basic topic with publish/subscribe:**
73
- * ```ts
74
- * import { $topic } from "alepha/topic";
75
- * import { t } from "alepha";
76
- *
77
- * class NotificationService {
78
- * userActivity = $topic({
79
- * name: "user-activity",
80
- * schema: {
81
- * payload: t.object({
82
- * userId: t.text(),
83
- * action: t.enum(["login", "logout", "purchase"]),
84
- * timestamp: t.number(),
85
- * metadata: t.optional(t.record(t.text(), t.any()))
86
- * })
87
- * },
88
- * handler: async (message) => {
89
- * // This subscriber runs automatically for all messages
90
- * console.log(`User ${message.payload.userId} performed ${message.payload.action}`);
91
- * }
92
- * });
93
- *
94
- * async trackUserLogin(userId: string) {
95
- * // Publish event - all subscribers will receive it
96
- * await this.userActivity.publish({
97
- * userId,
98
- * action: "login",
99
- * timestamp: Date.now(),
100
- * metadata: { source: "web", ip: "192.168.1.1" }
101
- * });
102
- * }
103
- *
104
- * async setupAdditionalSubscriber() {
105
- * // Add another subscriber dynamically
106
- * await this.userActivity.subscribe(async (message) => {
107
- * if (message.payload.action === "purchase") {
108
- * await this.sendPurchaseConfirmation(message.payload.userId);
109
- * }
110
- * });
111
- * }
112
- * }
113
- * ```
114
- *
115
- * @example
116
- * **Real-time chat system with multiple subscribers:**
117
- * ```ts
118
- * class ChatService {
119
- * messagesTopic = $topic({
120
- * name: "chat-messages",
121
- * description: "Real-time chat messages for all rooms",
122
- * schema: {
123
- * payload: t.object({
124
- * messageId: t.text(),
125
- * roomId: t.text(),
126
- * userId: t.text(),
127
- * content: t.text(),
128
- * timestamp: t.number(),
129
- * messageType: t.enum(["text", "image", "file"])
130
- * })
131
- * }
132
- * });
133
- *
134
- * async sendMessage(roomId: string, userId: string, content: string) {
135
- * await this.messagesTopic.publish({
136
- * messageId: generateId(),
137
- * roomId,
138
- * userId,
139
- * content,
140
- * timestamp: Date.now(),
141
- * messageType: "text"
142
- * });
143
- * }
144
- *
145
- * // Different services can subscribe to the same topic
146
- * async setupMessageLogging() {
147
- * await this.messagesTopic.subscribe(async (message) => {
148
- * // Log all messages for compliance
149
- * await this.auditLogger.log({
150
- * action: "message_sent",
151
- * roomId: message.payload.roomId,
152
- * userId: message.payload.userId,
153
- * timestamp: message.payload.timestamp
154
- * });
155
- * });
156
- * }
157
- *
158
- * async setupNotificationService() {
159
- * await this.messagesTopic.subscribe(async (message) => {
160
- * // Send push notifications to offline users
161
- * const offlineUsers = await this.getOfflineUsersInRoom(message.payload.roomId);
162
- * await this.sendPushNotifications(offlineUsers, {
163
- * title: `New message in ${message.payload.roomId}`,
164
- * body: message.payload.content
165
- * });
166
- * });
167
- * }
168
- * }
169
- * ```
170
- *
171
- * @example
172
- * **Redis-backed topic for distributed systems:**
173
- * ```ts
174
- * class DistributedEventSystem {
175
- * systemEvents = $topic({
176
- * name: "system-events",
177
- * provider: RedisTopicProvider, // Use Redis for cross-service communication
178
- * schema: {
179
- * payload: t.object({
180
- * eventType: t.text(),
181
- * serviceId: t.text(),
182
- * data: t.record(t.text(), t.any()),
183
- * timestamp: t.number(),
184
- * correlationId: t.optional(t.text())
185
- * })
186
- * },
187
- * handler: async (message) => {
188
- * // Central event handler for all system events
189
- * await this.processSystemEvent(message.payload);
190
- * }
191
- * });
192
- *
193
- * async publishServiceHealth(serviceId: string, healthy: boolean) {
194
- * await this.systemEvents.publish({
195
- * eventType: "service.health",
196
- * serviceId,
197
- * data: { healthy, checkedAt: new Date().toISOString() },
198
- * timestamp: Date.now()
199
- * });
200
- * }
201
- *
202
- * async setupHealthMonitoring() {
203
- * await this.systemEvents.subscribe(async (message) => {
204
- * if (message.payload.eventType === "service.health") {
205
- * await this.updateServiceStatus(
206
- * message.payload.serviceId,
207
- * message.payload.data.healthy
208
- * );
209
- *
210
- * if (!message.payload.data.healthy) {
211
- * await this.alertOnCall(`Service ${message.payload.serviceId} is down`);
212
- * }
213
- * }
214
- * });
215
- * }
216
- * }
217
- * ```
218
- */
219
- declare const $topic: {
220
- <T extends TopicMessageSchema>(options: TopicDescriptorOptions<T>): TopicDescriptor<T>;
221
- [KIND]: typeof TopicDescriptor;
222
- };
223
- interface TopicDescriptorOptions<T extends TopicMessageSchema> {
224
- /**
225
- * Unique name identifier for the topic.
226
- *
227
- * This name is used for:
228
- * - Topic identification across the pub/sub system
229
- * - Message routing between publishers and subscribers
230
- * - Logging and debugging topic-related operations
231
- * - Provider-specific topic management (channels, keys, etc.)
232
- *
233
- * If not provided, defaults to the property key where the topic is declared.
234
- *
235
- * **Naming Conventions**:
236
- * - Use descriptive, hierarchical names: "user.activity", "order.events"
237
- * - Avoid spaces and special characters
238
- * - Consider using dot notation for categorization
239
- * - Keep names concise but meaningful
240
- *
241
- * @example "user-activity"
242
- * @example "chat.messages"
243
- * @example "system.health.checks"
244
- * @example "payment.webhooks"
245
- */
246
- name?: string;
247
- /**
248
- * Human-readable description of the topic's purpose and usage.
249
- *
250
- * Used for:
251
- * - Documentation generation and API references
252
- * - Developer onboarding and understanding
253
- * - Monitoring dashboards and admin interfaces
254
- * - Team communication about system architecture
255
- *
256
- * **Description Best Practices**:
257
- * - Explain what events/messages this topic handles
258
- * - Mention key use cases and subscribers
259
- * - Include any important timing or ordering guarantees
260
- * - Note any special processing requirements
261
- *
262
- * @example "Real-time user activity events for analytics and notifications"
263
- * @example "Order lifecycle events from creation to delivery"
264
- * @example "Chat messages broadcast to all room participants"
265
- * @example "System health checks and service status updates"
266
- */
267
- description?: string;
268
- /**
269
- * Topic provider configuration for message storage and delivery.
270
- *
271
- * Options:
272
- * - **"memory"**: In-memory provider (default for development, lost on restart)
273
- * - **Service<TopicProvider>**: Custom provider class (e.g., RedisTopicProvider)
274
- * - **undefined**: Uses the default topic provider from dependency injection
275
- *
276
- * **Provider Selection Guidelines**:
277
- * - **Development**: Use "memory" for fast, simple testing without external dependencies
278
- * - **Production**: Use Redis or message brokers for persistence and scalability
279
- * - **Distributed systems**: Use Redis/RabbitMQ for cross-service communication
280
- * - **High-throughput**: Use specialized providers with connection pooling
281
- * - **Real-time**: Ensure provider supports low-latency message delivery
282
- *
283
- * **Provider Capabilities**:
284
- * - Message persistence and durability
285
- * - Subscriber management and connection handling
286
- * - Message ordering and delivery guarantees
287
- * - Horizontal scaling and load distribution
288
- *
289
- * @default Uses injected TopicProvider
290
- * @example "memory"
291
- * @example RedisTopicProvider
292
- * @example RabbitMQTopicProvider
293
- */
294
- provider?: "memory" | Service<TopicProvider>;
295
- /**
296
- * TypeBox schema defining the structure of messages published to this topic.
297
- *
298
- * The schema must include:
299
- * - **payload**: Required schema for the main message data
300
- * - **headers**: Optional schema for message metadata
301
- *
302
- * This schema:
303
- * - Validates all messages published to the topic
304
- * - Provides full TypeScript type inference for subscribers
305
- * - Ensures type safety between publishers and subscribers
306
- * - Enables automatic serialization/deserialization
307
- *
308
- * **Schema Design Best Practices**:
309
- * - Keep payload schemas focused and cohesive
310
- * - Use optional fields for data that might not always be present
311
- * - Include timestamp fields for event ordering
312
- * - Consider versioning for schema evolution
313
- * - Use union types for different event types in the same topic
314
- *
315
- * @example
316
- * ```ts
317
- * {
318
- * payload: t.object({
319
- * eventId: t.text(),
320
- * eventType: t.enum(["created", "updated"]),
321
- * data: t.record(t.text(), t.any()),
322
- * timestamp: t.number(),
323
- * userId: t.optional(t.text())
324
- * }),
325
- * headers: t.optional(t.object({
326
- * source: t.text(),
327
- * correlationId: t.text()
328
- * }))
329
- * }
330
- * ```
331
- */
332
- schema: T;
333
- /**
334
- * Default subscriber handler function that processes messages published to this topic.
335
- *
336
- * This handler:
337
- * - Automatically subscribes when the topic is initialized
338
- * - Receives all messages published to the topic
339
- * - Runs for every message without additional subscription setup
340
- * - Can be supplemented with additional subscribers via `subscribe()` method
341
- * - Should handle errors gracefully to avoid breaking other subscribers
342
- *
343
- * **Handler Design Guidelines**:
344
- * - Keep handlers focused on a single responsibility
345
- * - Use proper error handling and logging
346
- * - Consider performance impact for high-frequency topics
347
- * - Make handlers idempotent when possible
348
- * - Validate business rules within the handler logic
349
- * - Log important processing steps for debugging
350
- *
351
- * **Error Handling Strategy**:
352
- * - Log errors but don't re-throw to avoid affecting other subscribers
353
- * - Use try-catch blocks for external service calls
354
- * - Consider implementing circuit breakers for resilience
355
- * - Monitor error rates and patterns for system health
356
- *
357
- * @param message - The topic message with validated payload and headers
358
- * @param message.payload - The typed message data based on the schema
359
- * @returns Promise that resolves when processing is complete
360
- *
361
- * @example
362
- * ```ts
363
- * handler: async (message) => {
364
- * const { eventType, data, timestamp } = message.payload;
365
- *
366
- * try {
367
- * // Log message receipt
368
- * this.logger.info(`Processing ${eventType} event`, { timestamp, data });
369
- *
370
- * // Process based on event type
371
- * switch (eventType) {
372
- * case "created":
373
- * await this.handleCreation(data);
374
- * break;
375
- * case "updated":
376
- * await this.handleUpdate(data);
377
- * break;
378
- * default:
379
- * this.logger.warn(`Unknown event type: ${eventType}`);
380
- * }
381
- *
382
- * this.logger.info(`Successfully processed ${eventType} event`);
383
- *
384
- * } catch (error) {
385
- * // Log error but don't re-throw to avoid affecting other subscribers
386
- * this.logger.error(`Failed to process ${eventType} event`, {
387
- * error: error.message,
388
- * eventType,
389
- * timestamp,
390
- * data
391
- * });
392
- * }
393
- * }
394
- * ```
395
- */
396
- handler?: TopicHandler<T>;
397
- }
398
- declare class TopicDescriptor<T extends TopicMessageSchema> extends Descriptor<TopicDescriptorOptions<T>> {
399
- protected readonly log: _alepha_logger0.Logger;
400
- protected readonly dateTimeProvider: DateTimeProvider;
401
- readonly provider: TopicProvider;
402
- get name(): string;
403
- publish(payload: TopicMessage<T>["payload"]): Promise<void>;
404
- subscribe(handler: TopicHandler<T>): Promise<UnSubscribeFn>;
405
- wait(options?: TopicWaitOptions<T>): Promise<TopicMessage<T>>;
406
- protected $provider(): TopicProvider;
407
- protected parseMessage(message: string): TopicMessage<T>;
408
- }
409
- interface TopicMessage<T extends TopicMessageSchema> {
410
- payload: Static<T["payload"]>;
411
- }
412
- interface TopicWaitOptions<T extends TopicMessageSchema> {
413
- timeout?: DurationLike;
414
- filter?: (message: {
415
- payload: Static<T["payload"]>;
416
- }) => boolean;
417
- }
418
- interface TopicMessageSchema {
419
- payload: TSchema;
420
- }
421
- type TopicHandler<T extends TopicMessageSchema = TopicMessageSchema> = (message: TopicMessage<T>) => unknown;
422
- //#endregion
423
- //#region src/descriptors/$subscriber.d.ts
424
- /**
425
- * Creates a subscriber descriptor to listen for messages from a specific topic.
426
- *
427
- * This descriptor creates a dedicated message subscriber that connects to a topic and processes
428
- * its messages using a custom handler function. Subscribers provide a clean way to separate
429
- * message publishing from consumption, enabling scalable pub/sub architectures where multiple
430
- * subscribers can react to the same events independently.
431
- *
432
- * ## Key Features
433
- *
434
- * - **Topic Integration**: Seamlessly connects to any $topic descriptor
435
- * - **Type Safety**: Full TypeScript support inherited from the connected topic's schema
436
- * - **Dedicated Processing**: Isolated message processing logic separate from the topic
437
- * - **Real-time Processing**: Immediate message delivery when events are published
438
- * - **Error Isolation**: Subscriber errors don't affect other subscribers or the topic
439
- * - **Scalability**: Multiple subscribers can listen to the same topic independently
440
- *
441
- * ## Use Cases
442
- *
443
- * Perfect for creating specialized event handlers:
444
- * - Notification services for user events
445
- * - Analytics and logging systems
446
- * - Data synchronization between services
447
- * - Real-time UI updates
448
- * - Event-driven workflow triggers
449
- * - Audit and compliance logging
450
- *
451
- * @example
452
- * **Basic subscriber setup:**
453
- * ```ts
454
- * import { $topic, $subscriber } from "alepha/topic";
455
- * import { t } from "alepha";
456
- *
457
- * class UserActivityService {
458
- * // Define the topic
459
- * userEvents = $topic({
460
- * name: "user-activity",
461
- * schema: {
462
- * payload: t.object({
463
- * userId: t.text(),
464
- * action: t.enum(["login", "logout", "purchase"]),
465
- * timestamp: t.number(),
466
- * metadata: t.optional(t.record(t.text(), t.any()))
467
- * })
468
- * }
469
- * });
470
- *
471
- * // Create a dedicated subscriber for this topic
472
- * activityLogger = $subscriber({
473
- * topic: this.userEvents,
474
- * handler: async (message) => {
475
- * const { userId, action, timestamp } = message.payload;
476
- *
477
- * await this.auditLogger.log({
478
- * event: 'user_activity',
479
- * userId,
480
- * action,
481
- * timestamp,
482
- * source: 'user-activity-topic'
483
- * });
484
- *
485
- * this.log.info(`User ${userId} performed ${action} at ${new Date(timestamp).toISOString()}`);
486
- * }
487
- * });
488
- *
489
- * async trackUserLogin(userId: string, metadata: Record<string, any>) {
490
- * // Publish to topic - subscriber will automatically process it
491
- * await this.userEvents.publish({
492
- * userId,
493
- * action: "login",
494
- * timestamp: Date.now(),
495
- * metadata
496
- * });
497
- * }
498
- * }
499
- * ```
500
- *
501
- * @example
502
- * **Subscriber with advanced error handling and filtering:**
503
- * ```ts
504
- * class NotificationSubscriber {
505
- * systemEvents = $topic({
506
- * name: "system-events",
507
- * schema: {
508
- * payload: t.object({
509
- * eventType: t.text(),
510
- * severity: t.enum(["info", "warning", "error"]),
511
- * serviceId: t.text(),
512
- * message: t.text(),
513
- * data: t.optional(t.record(t.text(), t.any()))
514
- * })
515
- * }
516
- * });
517
- *
518
- * alertSubscriber = $subscriber({
519
- * topic: this.systemEvents,
520
- * handler: async (message) => {
521
- * const { eventType, severity, serviceId, message: eventMessage, data } = message.payload;
522
- *
523
- * try {
524
- * // Only process error events for alerting
525
- * if (severity !== 'error') {
526
- * return;
527
- * }
528
- *
529
- * // Log the event
530
- * this.logger.error(`System alert from ${serviceId}`, {
531
- * eventType,
532
- * message: eventMessage,
533
- * data
534
- * });
535
- *
536
- * // Send alerts based on service criticality
537
- * const criticalServices = ['payment', 'auth', 'database'];
538
- * const isCritical = criticalServices.includes(serviceId);
539
- *
540
- * if (isCritical) {
541
- * // Immediate alert for critical services
542
- * await this.alertService.sendImmediate({
543
- * title: `Critical Error in ${serviceId}`,
544
- * message: eventMessage,
545
- * severity: 'critical',
546
- * metadata: { eventType, serviceId, data }
547
- * });
548
- * } else {
549
- * // Queue non-critical alerts for batching
550
- * await this.alertService.queueAlert({
551
- * title: `Error in ${serviceId}`,
552
- * message: eventMessage,
553
- * severity: 'error',
554
- * metadata: { eventType, serviceId, data }
555
- * });
556
- * }
557
- *
558
- * // Update service health status
559
- * await this.healthMonitor.recordError(serviceId, eventType);
560
- *
561
- * } catch (error) {
562
- * // Log subscriber errors but don't re-throw
563
- * // This prevents one failing subscriber from affecting others
564
- * this.log.error(`Alert subscriber failed`, {
565
- * originalEvent: { eventType, serviceId, severity },
566
- * subscriberError: error.message
567
- * });
568
- * }
569
- * }
570
- * });
571
- * }
572
- * ```
573
- *
574
- * @example
575
- * **Subscriber for real-time data aggregation:**
576
- * ```ts
577
- * class MetricsAggregator {
578
- * userActivityTopic = $topic({
579
- * name: "user-metrics",
580
- * schema: {
581
- * payload: t.object({
582
- * userId: t.text(),
583
- * sessionId: t.text(),
584
- * eventType: t.text(),
585
- * timestamp: t.number(),
586
- * duration: t.optional(t.number()),
587
- * metadata: t.optional(t.record(t.text(), t.any()))
588
- * })
589
- * }
590
- * });
591
- *
592
- * metricsSubscriber = $subscriber({
593
- * topic: this.userActivityTopic,
594
- * handler: async (message) => {
595
- * const { userId, sessionId, eventType, timestamp, duration, metadata } = message.payload;
596
- *
597
- * // Update real-time metrics
598
- * await Promise.all([
599
- * // Update user activity counters
600
- * this.metricsStore.increment(`user:${userId}:events:${eventType}`, 1),
601
- * this.metricsStore.increment(`global:events:${eventType}`, 1),
602
- *
603
- * // Track session activity
604
- * this.sessionStore.updateActivity(sessionId, timestamp),
605
- *
606
- * // Record duration metrics if provided
607
- * duration ? this.metricsStore.recordDuration(`events:${eventType}:duration`, duration) : Promise.resolve(),
608
- *
609
- * // Update time-based aggregations
610
- * this.timeSeriesStore.addPoint({
611
- * metric: `user_activity.${eventType}`,
612
- * timestamp,
613
- * value: 1,
614
- * tags: { userId, sessionId }
615
- * })
616
- * ]);
617
- *
618
- * // Trigger real-time dashboard updates
619
- * await this.dashboardService.updateRealTimeStats({
620
- * eventType,
621
- * userId,
622
- * timestamp
623
- * });
624
- *
625
- * this.logger.debug(`Processed metrics for ${eventType}`, {
626
- * userId,
627
- * eventType,
628
- * timestamp
629
- * });
630
- * }
631
- * });
632
- * }
633
- * ```
634
- */
635
- declare const $subscriber: {
636
- <T extends TopicMessageSchema>(options: SubscriberDescriptorOptions<T>): SubscriberDescriptor<T>;
637
- [KIND]: typeof SubscriberDescriptor;
638
- };
639
- interface SubscriberDescriptorOptions<T extends TopicMessageSchema> {
640
- /**
641
- * The topic descriptor that this subscriber will listen to for messages.
642
- *
643
- * This establishes the connection between the subscriber and its source topic:
644
- * - The subscriber inherits the topic's message schema for type safety
645
- * - Messages published to the topic will be automatically delivered to this subscriber
646
- * - Multiple subscribers can listen to the same topic independently
647
- * - The subscriber will use the topic's provider and configuration settings
648
- *
649
- * **Topic Integration Benefits**:
650
- * - Type safety: Subscriber handler gets fully typed message payloads
651
- * - Schema validation: Messages are validated before reaching the subscriber
652
- * - Real-time delivery: Messages are delivered immediately upon publication
653
- * - Error isolation: Subscriber errors don't affect the topic or other subscribers
654
- * - Monitoring: Topic metrics include subscriber processing statistics
655
- *
656
- * @example
657
- * ```ts
658
- * // First, define a topic
659
- * userEvents = $topic({
660
- * name: "user-activity",
661
- * schema: {
662
- * payload: t.object({ userId: t.text(), action: t.text() })
663
- * }
664
- * });
665
- *
666
- * // Then, create a subscriber for that topic
667
- * activitySubscriber = $subscriber({
668
- * topic: this.userEvents, // Reference the topic descriptor
669
- * handler: async (message) => { } // Process messages here
670
- * });
671
- * ```
672
- */
673
- topic: TopicDescriptor<T>;
674
- /**
675
- * Message handler function that processes individual messages from the topic.
676
- *
677
- * This function:
678
- * - Receives fully typed and validated message payloads from the connected topic
679
- * - Executes immediately when messages are published to the topic
680
- * - Should implement the core business logic for reacting to these events
681
- * - Runs independently of other subscribers to the same topic
682
- * - Should handle errors gracefully to avoid affecting other subscribers
683
- * - Has access to the full Alepha dependency injection container
684
- *
685
- * **Handler Design Guidelines**:
686
- * - Keep handlers focused on a single responsibility
687
- * - Use proper error handling and logging
688
- * - Consider performance impact for high-frequency topics
689
- * - Make handlers idempotent when possible for reliability
690
- * - Validate business rules within the handler logic
691
- * - Log important processing steps for debugging and monitoring
692
- *
693
- * **Error Handling Strategy**:
694
- * - Log errors but don't re-throw to avoid affecting other subscribers
695
- * - Use try-catch blocks for external service calls
696
- * - Implement circuit breakers for resilience with external systems
697
- * - Monitor error rates and patterns for system health
698
- * - Consider implementing retry logic for temporary failures
699
- *
700
- * **Performance Considerations**:
701
- * - Keep handler execution time minimal for high-throughput topics
702
- * - Use background queues for heavy processing triggered by events
703
- * - Implement batching for efficiency when processing many similar events
704
- * - Consider async processing patterns for non-critical operations
705
- *
706
- * @param message - The topic message with validated payload and optional headers
707
- * @param message.payload - The typed message data based on the topic's schema
708
- * @returns Promise that resolves when processing is complete
709
- *
710
- * @example
711
- * ```ts
712
- * handler: async (message) => {
713
- * const { userId, eventType, timestamp } = message.payload;
714
- *
715
- * try {
716
- * // Log event receipt
717
- * this.logger.info(`Processing ${eventType} event for user ${userId}`, {
718
- * timestamp,
719
- * userId,
720
- * eventType
721
- * });
722
- *
723
- * // Perform event-specific processing
724
- * switch (eventType) {
725
- * case 'user.login':
726
- * await this.updateLastLogin(userId, timestamp);
727
- * await this.sendWelcomeNotification(userId);
728
- * break;
729
- * case 'user.logout':
730
- * await this.updateSessionDuration(userId, timestamp);
731
- * break;
732
- * case 'user.purchase':
733
- * await this.updateRewardsPoints(userId, message.payload.purchaseAmount);
734
- * await this.triggerRecommendations(userId);
735
- * break;
736
- * default:
737
- * this.logger.warn(`Unknown event type: ${eventType}`);
738
- * }
739
- *
740
- * // Update analytics
741
- * await this.analytics.track(eventType, {
742
- * userId,
743
- * timestamp,
744
- * source: 'topic-subscriber'
745
- * });
746
- *
747
- * this.logger.info(`Successfully processed ${eventType} for user ${userId}`);
748
- *
749
- * } catch (error) {
750
- * // Log error but don't re-throw to avoid affecting other subscribers
751
- * this.logger.error(`Failed to process ${eventType} for user ${userId}`, {
752
- * error: error.message,
753
- * stack: error.stack,
754
- * userId,
755
- * eventType,
756
- * timestamp
757
- * });
758
- *
759
- * // Optionally send to error tracking service
760
- * await this.errorTracker.captureException(error, {
761
- * context: { userId, eventType, timestamp },
762
- * tags: { component: 'topic-subscriber' }
763
- * });
764
- * }
765
- * }
766
- * ```
767
- */
768
- handler: TopicHandler<T>;
769
- }
770
- declare class SubscriberDescriptor<T extends TopicMessageSchema> extends Descriptor<SubscriberDescriptorOptions<T>> {}
771
- //#endregion
772
- //#region src/errors/TopicTimeoutError.d.ts
773
- declare class TopicTimeoutError extends Error {
774
- readonly topic: string;
775
- readonly timeout: number;
776
- constructor(topic: string, timeout: number);
777
- }
778
- //#endregion
779
- //#region src/providers/MemoryTopicProvider.d.ts
780
- declare class MemoryTopicProvider extends TopicProvider {
781
- protected readonly log: _alepha_logger0.Logger;
782
- protected readonly subscriptions: Record<string, SubscribeCallback[]>;
783
- protected readonly start: _alepha_core1.HookDescriptor<"start">;
784
- /**
785
- * Publish a message to a topic.
786
- *
787
- * @param topic
788
- * @param message
789
- */
790
- publish(topic: string, message: string): Promise<void>;
791
- /**
792
- * Subscribe to a topic.
793
- *
794
- * @param topic - The topic to subscribe to.
795
- * @param callback
796
- */
797
- subscribe(topic: string, callback: SubscribeCallback): Promise<UnSubscribeFn>;
798
- /**
799
- * Unsubscribe from a topic.
800
- *
801
- * @param topic - The topic to unsubscribe from.
802
- */
803
- unsubscribe(topic: string): Promise<void>;
804
- }
805
- //#endregion
806
- //#region src/index.d.ts
807
- /**
808
- * Generic interface for pub/sub messaging.
809
- * Gives you the ability to create topics and subscribers.
810
- * This module provides only a memory implementation of the topic provider.
811
- *
812
- * @see {@link $topic}
813
- * @see {@link $subscriber}
814
- * @module alepha.topic
815
- */
816
- declare const AlephaTopic: _alepha_core1.Service<_alepha_core1.Module>;
817
- //#endregion
818
- export { $subscriber, $topic, AlephaTopic, MemoryTopicProvider, SubscribeCallback, SubscriberDescriptor, SubscriberDescriptorOptions, TopicDescriptor, TopicDescriptorOptions, TopicHandler, TopicMessage, TopicMessageSchema, TopicProvider, TopicTimeoutError, TopicWaitOptions, UnSubscribeFn };
819
- //# sourceMappingURL=index.d.ts.map