alepha 0.13.0 → 0.13.1

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 (195) hide show
  1. package/dist/api-jobs/index.d.ts +26 -26
  2. package/dist/api-users/index.d.ts +1 -1
  3. package/dist/cli/{dist-Sz2EXvQX.cjs → dist-Dl9Vl7Ur.js} +17 -13
  4. package/dist/cli/{dist-BBPjuQ56.js.map → dist-Dl9Vl7Ur.js.map} +1 -1
  5. package/dist/cli/index.d.ts +3 -11
  6. package/dist/cli/index.js +106 -74
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/email/index.js +71 -73
  9. package/dist/email/index.js.map +1 -1
  10. package/dist/orm/index.d.ts +1 -1
  11. package/dist/orm/index.js.map +1 -1
  12. package/dist/queue/index.d.ts +4 -4
  13. package/dist/retry/index.d.ts +1 -1
  14. package/dist/retry/index.js +2 -2
  15. package/dist/retry/index.js.map +1 -1
  16. package/dist/scheduler/index.d.ts +6 -6
  17. package/dist/security/index.d.ts +28 -28
  18. package/dist/server/index.js +1 -1
  19. package/dist/server/index.js.map +1 -1
  20. package/dist/server-health/index.d.ts +17 -17
  21. package/dist/server-metrics/index.js +170 -174
  22. package/dist/server-metrics/index.js.map +1 -1
  23. package/dist/server-security/index.d.ts +9 -9
  24. package/dist/vite/index.js +4 -5
  25. package/dist/vite/index.js.map +1 -1
  26. package/dist/websocket/index.d.ts +7 -7
  27. package/package.json +52 -103
  28. package/src/cli/apps/AlephaPackageBuilderCli.ts +7 -2
  29. package/src/cli/assets/appRouterTs.ts +9 -0
  30. package/src/cli/assets/indexHtml.ts +2 -1
  31. package/src/cli/assets/mainBrowserTs.ts +10 -0
  32. package/src/cli/commands/CoreCommands.ts +6 -5
  33. package/src/cli/commands/DrizzleCommands.ts +65 -57
  34. package/src/cli/commands/VerifyCommands.ts +1 -1
  35. package/src/cli/services/ProjectUtils.ts +44 -38
  36. package/src/orm/providers/DrizzleKitProvider.ts +1 -1
  37. package/src/retry/descriptors/$retry.ts +5 -3
  38. package/src/server/providers/NodeHttpServerProvider.ts +1 -1
  39. package/src/vite/helpers/boot.ts +3 -3
  40. package/dist/api-files/index.cjs +0 -1293
  41. package/dist/api-files/index.cjs.map +0 -1
  42. package/dist/api-files/index.d.cts +0 -829
  43. package/dist/api-jobs/index.cjs +0 -274
  44. package/dist/api-jobs/index.cjs.map +0 -1
  45. package/dist/api-jobs/index.d.cts +0 -654
  46. package/dist/api-notifications/index.cjs +0 -380
  47. package/dist/api-notifications/index.cjs.map +0 -1
  48. package/dist/api-notifications/index.d.cts +0 -289
  49. package/dist/api-parameters/index.cjs +0 -66
  50. package/dist/api-parameters/index.cjs.map +0 -1
  51. package/dist/api-parameters/index.d.cts +0 -84
  52. package/dist/api-users/index.cjs +0 -6009
  53. package/dist/api-users/index.cjs.map +0 -1
  54. package/dist/api-users/index.d.cts +0 -4740
  55. package/dist/api-verifications/index.cjs +0 -407
  56. package/dist/api-verifications/index.cjs.map +0 -1
  57. package/dist/api-verifications/index.d.cts +0 -207
  58. package/dist/batch/index.cjs +0 -408
  59. package/dist/batch/index.cjs.map +0 -1
  60. package/dist/batch/index.d.cts +0 -330
  61. package/dist/bin/index.cjs +0 -17
  62. package/dist/bin/index.cjs.map +0 -1
  63. package/dist/bin/index.d.cts +0 -1
  64. package/dist/bucket/index.cjs +0 -303
  65. package/dist/bucket/index.cjs.map +0 -1
  66. package/dist/bucket/index.d.cts +0 -355
  67. package/dist/cache/index.cjs +0 -241
  68. package/dist/cache/index.cjs.map +0 -1
  69. package/dist/cache/index.d.cts +0 -202
  70. package/dist/cache-redis/index.cjs +0 -84
  71. package/dist/cache-redis/index.cjs.map +0 -1
  72. package/dist/cache-redis/index.d.cts +0 -40
  73. package/dist/cli/chunk-DSlc6foC.cjs +0 -43
  74. package/dist/cli/dist-BBPjuQ56.js +0 -2778
  75. package/dist/cli/dist-Sz2EXvQX.cjs.map +0 -1
  76. package/dist/cli/index.cjs +0 -1241
  77. package/dist/cli/index.cjs.map +0 -1
  78. package/dist/cli/index.d.cts +0 -422
  79. package/dist/command/index.cjs +0 -693
  80. package/dist/command/index.cjs.map +0 -1
  81. package/dist/command/index.d.cts +0 -340
  82. package/dist/core/index.cjs +0 -2264
  83. package/dist/core/index.cjs.map +0 -1
  84. package/dist/core/index.d.cts +0 -1927
  85. package/dist/datetime/index.cjs +0 -318
  86. package/dist/datetime/index.cjs.map +0 -1
  87. package/dist/datetime/index.d.cts +0 -145
  88. package/dist/email/index.cjs +0 -10874
  89. package/dist/email/index.cjs.map +0 -1
  90. package/dist/email/index.d.cts +0 -186
  91. package/dist/fake/index.cjs +0 -34641
  92. package/dist/fake/index.cjs.map +0 -1
  93. package/dist/fake/index.d.cts +0 -74
  94. package/dist/file/index.cjs +0 -1212
  95. package/dist/file/index.cjs.map +0 -1
  96. package/dist/file/index.d.cts +0 -698
  97. package/dist/lock/index.cjs +0 -226
  98. package/dist/lock/index.cjs.map +0 -1
  99. package/dist/lock/index.d.cts +0 -361
  100. package/dist/lock-redis/index.cjs +0 -113
  101. package/dist/lock-redis/index.cjs.map +0 -1
  102. package/dist/lock-redis/index.d.cts +0 -24
  103. package/dist/logger/index.cjs +0 -521
  104. package/dist/logger/index.cjs.map +0 -1
  105. package/dist/logger/index.d.cts +0 -281
  106. package/dist/orm/index.cjs +0 -2986
  107. package/dist/orm/index.cjs.map +0 -1
  108. package/dist/orm/index.d.cts +0 -2213
  109. package/dist/queue/index.cjs +0 -1044
  110. package/dist/queue/index.cjs.map +0 -1
  111. package/dist/queue/index.d.cts +0 -1265
  112. package/dist/queue-redis/index.cjs +0 -873
  113. package/dist/queue-redis/index.cjs.map +0 -1
  114. package/dist/queue-redis/index.d.cts +0 -82
  115. package/dist/redis/index.cjs +0 -153
  116. package/dist/redis/index.cjs.map +0 -1
  117. package/dist/redis/index.d.cts +0 -82
  118. package/dist/retry/index.cjs +0 -146
  119. package/dist/retry/index.cjs.map +0 -1
  120. package/dist/retry/index.d.cts +0 -172
  121. package/dist/router/index.cjs +0 -111
  122. package/dist/router/index.cjs.map +0 -1
  123. package/dist/router/index.d.cts +0 -46
  124. package/dist/scheduler/index.cjs +0 -576
  125. package/dist/scheduler/index.cjs.map +0 -1
  126. package/dist/scheduler/index.d.cts +0 -145
  127. package/dist/security/index.cjs +0 -2402
  128. package/dist/security/index.cjs.map +0 -1
  129. package/dist/security/index.d.cts +0 -598
  130. package/dist/server/index.cjs +0 -1680
  131. package/dist/server/index.cjs.map +0 -1
  132. package/dist/server/index.d.cts +0 -810
  133. package/dist/server-auth/index.cjs +0 -3146
  134. package/dist/server-auth/index.cjs.map +0 -1
  135. package/dist/server-auth/index.d.cts +0 -1164
  136. package/dist/server-cache/index.cjs +0 -252
  137. package/dist/server-cache/index.cjs.map +0 -1
  138. package/dist/server-cache/index.d.cts +0 -164
  139. package/dist/server-compress/index.cjs +0 -141
  140. package/dist/server-compress/index.cjs.map +0 -1
  141. package/dist/server-compress/index.d.cts +0 -38
  142. package/dist/server-cookies/index.cjs +0 -234
  143. package/dist/server-cookies/index.cjs.map +0 -1
  144. package/dist/server-cookies/index.d.cts +0 -144
  145. package/dist/server-cors/index.cjs +0 -201
  146. package/dist/server-cors/index.cjs.map +0 -1
  147. package/dist/server-cors/index.d.cts +0 -140
  148. package/dist/server-health/index.cjs +0 -62
  149. package/dist/server-health/index.cjs.map +0 -1
  150. package/dist/server-health/index.d.cts +0 -58
  151. package/dist/server-helmet/index.cjs +0 -131
  152. package/dist/server-helmet/index.cjs.map +0 -1
  153. package/dist/server-helmet/index.d.cts +0 -97
  154. package/dist/server-links/index.cjs +0 -992
  155. package/dist/server-links/index.cjs.map +0 -1
  156. package/dist/server-links/index.d.cts +0 -513
  157. package/dist/server-metrics/index.cjs +0 -4535
  158. package/dist/server-metrics/index.cjs.map +0 -1
  159. package/dist/server-metrics/index.d.cts +0 -35
  160. package/dist/server-multipart/index.cjs +0 -237
  161. package/dist/server-multipart/index.cjs.map +0 -1
  162. package/dist/server-multipart/index.d.cts +0 -50
  163. package/dist/server-proxy/index.cjs +0 -186
  164. package/dist/server-proxy/index.cjs.map +0 -1
  165. package/dist/server-proxy/index.d.cts +0 -234
  166. package/dist/server-rate-limit/index.cjs +0 -241
  167. package/dist/server-rate-limit/index.cjs.map +0 -1
  168. package/dist/server-rate-limit/index.d.cts +0 -183
  169. package/dist/server-security/index.cjs +0 -316
  170. package/dist/server-security/index.cjs.map +0 -1
  171. package/dist/server-security/index.d.cts +0 -173
  172. package/dist/server-static/index.cjs +0 -170
  173. package/dist/server-static/index.cjs.map +0 -1
  174. package/dist/server-static/index.d.cts +0 -121
  175. package/dist/server-swagger/index.cjs +0 -1021
  176. package/dist/server-swagger/index.cjs.map +0 -1
  177. package/dist/server-swagger/index.d.cts +0 -382
  178. package/dist/sms/index.cjs +0 -221
  179. package/dist/sms/index.cjs.map +0 -1
  180. package/dist/sms/index.d.cts +0 -130
  181. package/dist/thread/index.cjs +0 -350
  182. package/dist/thread/index.cjs.map +0 -1
  183. package/dist/thread/index.d.cts +0 -260
  184. package/dist/topic/index.cjs +0 -282
  185. package/dist/topic/index.cjs.map +0 -1
  186. package/dist/topic/index.d.cts +0 -523
  187. package/dist/topic-redis/index.cjs +0 -71
  188. package/dist/topic-redis/index.cjs.map +0 -1
  189. package/dist/topic-redis/index.d.cts +0 -42
  190. package/dist/vite/index.cjs +0 -1077
  191. package/dist/vite/index.cjs.map +0 -1
  192. package/dist/vite/index.d.cts +0 -542
  193. package/dist/websocket/index.cjs +0 -1117
  194. package/dist/websocket/index.cjs.map +0 -1
  195. package/dist/websocket/index.d.cts +0 -861
@@ -1,282 +0,0 @@
1
- let alepha = require("alepha");
2
- let alepha_datetime = require("alepha/datetime");
3
- let alepha_logger = require("alepha/logger");
4
-
5
- //#region src/topic/descriptors/$subscriber.ts
6
- /**
7
- * Creates a subscriber descriptor to listen for messages from a specific topic.
8
- *
9
- * Provides a dedicated message subscriber that connects to a topic and processes messages
10
- * with custom handler logic, enabling scalable pub/sub architectures where multiple
11
- * subscribers can react to the same events independently.
12
- *
13
- * **Key Features**
14
- * - Seamless integration with any $topic descriptor
15
- * - Full type safety inherited from topic schema
16
- * - Real-time message delivery when events are published
17
- * - Error isolation between subscribers
18
- * - Support for multiple independent subscribers per topic
19
- *
20
- * **Common Use Cases**
21
- * - Notification services and audit logging
22
- * - Analytics and metrics collection
23
- * - Data synchronization and real-time UI updates
24
- *
25
- * @example
26
- * ```ts
27
- * class UserActivityService {
28
- * userEvents = $topic({
29
- * name: "user-activity",
30
- * schema: {
31
- * payload: t.object({
32
- * userId: t.text(),
33
- * action: t.enum(["login", "logout", "purchase"]),
34
- * timestamp: t.number()
35
- * })
36
- * }
37
- * });
38
- *
39
- * activityLogger = $subscriber({
40
- * topic: this.userEvents,
41
- * handler: async (message) => {
42
- * const { userId, action, timestamp } = message.payload;
43
- * await this.auditLogger.log({
44
- * userId,
45
- * action,
46
- * timestamp
47
- * });
48
- * }
49
- * });
50
- *
51
- * async trackUserLogin(userId: string) {
52
- * await this.userEvents.publish({
53
- * userId,
54
- * action: "login",
55
- * timestamp: Date.now()
56
- * });
57
- * }
58
- * }
59
- * ```
60
- */
61
- const $subscriber = (options) => {
62
- return (0, alepha.createDescriptor)(SubscriberDescriptor, options);
63
- };
64
- var SubscriberDescriptor = class extends alepha.Descriptor {};
65
- $subscriber[alepha.KIND] = SubscriberDescriptor;
66
-
67
- //#endregion
68
- //#region src/topic/errors/TopicTimeoutError.ts
69
- var TopicTimeoutError = class extends Error {
70
- topic;
71
- timeout;
72
- constructor(topic, timeout) {
73
- super(`Timeout of ${timeout}ms exceeded for topic ${topic}`);
74
- this.timeout = timeout;
75
- this.topic = topic;
76
- }
77
- };
78
-
79
- //#endregion
80
- //#region src/topic/providers/TopicProvider.ts
81
- /**
82
- * Base class for topic providers.
83
- */
84
- var TopicProvider = class {
85
- alepha = (0, alepha.$inject)(alepha.Alepha);
86
- /**
87
- * Returns the list of $subscribers for this provider.
88
- */
89
- subscribers() {
90
- const handlers = [];
91
- const topics = this.alepha.descriptors($topic);
92
- for (const topic of topics) {
93
- if (topic.provider !== this) continue;
94
- const handler = topic.options.handler;
95
- if (handler && topic.provider === this) handlers.push(() => topic.subscribe(handler));
96
- }
97
- const subscribers = this.alepha.descriptors($subscriber);
98
- for (const subscriber of subscribers) {
99
- if (subscriber.options.topic.provider !== this) continue;
100
- handlers.push(() => subscriber.options.topic.subscribe(subscriber.options.handler));
101
- }
102
- return handlers;
103
- }
104
- };
105
-
106
- //#endregion
107
- //#region src/topic/providers/MemoryTopicProvider.ts
108
- var MemoryTopicProvider = class extends TopicProvider {
109
- log = (0, alepha_logger.$logger)();
110
- subscriptions = {};
111
- start = (0, alepha.$hook)({
112
- on: "start",
113
- handler: async () => {
114
- const subscribers = this.subscribers();
115
- if (subscribers.length) {
116
- await Promise.all(subscribers.map((fn) => fn()));
117
- for (const subscriber of subscribers) this.log.debug(`Subscribed to topic '${subscriber.name}'`);
118
- }
119
- }
120
- });
121
- /**
122
- * Publish a message to a topic.
123
- *
124
- * @param topic
125
- * @param message
126
- */
127
- async publish(topic, message) {
128
- if (!this.subscriptions[topic]) return;
129
- for (const callback of this.subscriptions[topic]) await callback(message);
130
- }
131
- /**
132
- * Subscribe to a topic.
133
- *
134
- * @param topic - The topic to subscribe to.
135
- * @param callback
136
- */
137
- async subscribe(topic, callback) {
138
- if (!this.subscriptions[topic]) this.subscriptions[topic] = [];
139
- this.subscriptions[topic].push(callback);
140
- return async () => {
141
- const callbacks = this.subscriptions[topic];
142
- if (!callbacks) return;
143
- this.subscriptions[topic] = callbacks.filter((cb) => cb !== callback);
144
- if (this.subscriptions[topic].length === 0) delete this.subscriptions[topic];
145
- };
146
- }
147
- /**
148
- * Unsubscribe from a topic.
149
- *
150
- * @param topic - The topic to unsubscribe from.
151
- */
152
- async unsubscribe(topic) {
153
- delete this.subscriptions[topic];
154
- }
155
- };
156
-
157
- //#endregion
158
- //#region src/topic/descriptors/$topic.ts
159
- /**
160
- * Creates a topic descriptor for publish/subscribe messaging and event-driven architecture.
161
- *
162
- * Enables decoupled communication through a pub/sub pattern where publishers send messages
163
- * and multiple subscribers receive them. Supports type-safe messages, real-time delivery,
164
- * event filtering, and pluggable backends (memory, Redis, custom providers).
165
- *
166
- * **Use Cases**: User notifications, real-time chat, event broadcasting, microservice communication
167
- *
168
- * @example
169
- * ```ts
170
- * class NotificationService {
171
- * userActivity = $topic({
172
- * name: "user-activity",
173
- * schema: {
174
- * payload: t.object({
175
- * userId: t.text(),
176
- * action: t.enum(["login", "logout", "purchase"]),
177
- * timestamp: t.number()
178
- * })
179
- * },
180
- * handler: async (message) => {
181
- * console.log(`User ${message.payload.userId}: ${message.payload.action}`);
182
- * }
183
- * });
184
- *
185
- * async trackLogin(userId: string) {
186
- * await this.userActivity.publish({ userId, action: "login", timestamp: Date.now() });
187
- * }
188
- *
189
- * async subscribeToEvents() {
190
- * await this.userActivity.subscribe(async (message) => {
191
- * // Additional subscriber logic
192
- * });
193
- * }
194
- * }
195
- * ```
196
- */
197
- const $topic = (options) => {
198
- return (0, alepha.createDescriptor)(TopicDescriptor, options);
199
- };
200
- var TopicDescriptor = class extends alepha.Descriptor {
201
- log = (0, alepha_logger.$logger)();
202
- dateTimeProvider = (0, alepha.$inject)(alepha_datetime.DateTimeProvider);
203
- provider = this.$provider();
204
- get name() {
205
- return this.options.name || this.config.propertyKey;
206
- }
207
- async publish(payload) {
208
- await this.provider.publish(this.name, JSON.stringify({ payload: this.alepha.codec.encode(this.options.schema.payload, payload) }));
209
- }
210
- async subscribe(handler) {
211
- return this.provider.subscribe(this.name, async (message) => {
212
- try {
213
- await handler(this.parseMessage(message));
214
- } catch (error) {
215
- this.log.error("Message processing has failed", error);
216
- }
217
- });
218
- }
219
- async wait(options = {}) {
220
- const filter = options.filter ?? (() => true);
221
- return new Promise((resolve, reject) => {
222
- const ref = {};
223
- (async () => {
224
- const clear = await this.provider.subscribe(this.name, (raw) => {
225
- const message = this.parseMessage(raw);
226
- if (!filter(message)) return;
227
- ref.timeout?.clear();
228
- clear();
229
- resolve(message);
230
- });
231
- const timeoutDuration = options.timeout ?? [10, "seconds"];
232
- ref.timeout = this.dateTimeProvider.createTimeout(() => {
233
- clear();
234
- reject(new TopicTimeoutError(this.name, this.dateTimeProvider.duration(timeoutDuration).asMilliseconds()));
235
- }, timeoutDuration);
236
- })();
237
- });
238
- }
239
- $provider() {
240
- if (!this.options.provider) return this.alepha.inject(TopicProvider);
241
- if (this.options.provider === "memory") return this.alepha.inject(MemoryTopicProvider);
242
- return this.alepha.inject(this.options.provider);
243
- }
244
- parseMessage(message) {
245
- const { payload } = JSON.parse(message);
246
- return { payload: this.alepha.codec.decode(this.options.schema.payload, payload) };
247
- }
248
- };
249
- $topic[alepha.KIND] = TopicDescriptor;
250
-
251
- //#endregion
252
- //#region src/topic/index.ts
253
- /**
254
- * Generic interface for pub/sub messaging.
255
- * Gives you the ability to create topics and subscribers.
256
- * This module provides only a memory implementation of the topic provider.
257
- *
258
- * @see {@link $topic}
259
- * @see {@link $subscriber}
260
- * @module alepha.topic
261
- */
262
- const AlephaTopic = (0, alepha.$module)({
263
- name: "alepha.topic",
264
- descriptors: [$topic, $subscriber],
265
- services: [TopicProvider, MemoryTopicProvider],
266
- register: (alepha$1) => alepha$1.with({
267
- optional: true,
268
- provide: TopicProvider,
269
- use: MemoryTopicProvider
270
- })
271
- });
272
-
273
- //#endregion
274
- exports.$subscriber = $subscriber;
275
- exports.$topic = $topic;
276
- exports.AlephaTopic = AlephaTopic;
277
- exports.MemoryTopicProvider = MemoryTopicProvider;
278
- exports.SubscriberDescriptor = SubscriberDescriptor;
279
- exports.TopicDescriptor = TopicDescriptor;
280
- exports.TopicProvider = TopicProvider;
281
- exports.TopicTimeoutError = TopicTimeoutError;
282
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":["Descriptor","KIND","Alepha","handlers: Array<() => Promise<unknown>>","Descriptor","DateTimeProvider","ref: { timeout?: Timeout }","KIND","alepha"],"sources":["../../src/topic/descriptors/$subscriber.ts","../../src/topic/errors/TopicTimeoutError.ts","../../src/topic/providers/TopicProvider.ts","../../src/topic/providers/MemoryTopicProvider.ts","../../src/topic/descriptors/$topic.ts","../../src/topic/index.ts"],"sourcesContent":["import { createDescriptor, Descriptor, KIND } from \"alepha\";\nimport type {\n TopicDescriptor,\n TopicHandler,\n TopicMessageSchema,\n} from \"./$topic.ts\";\n\n/**\n * Creates a subscriber descriptor to listen for messages from a specific topic.\n *\n * Provides a dedicated message subscriber that connects to a topic and processes messages\n * with custom handler logic, enabling scalable pub/sub architectures where multiple\n * subscribers can react to the same events independently.\n *\n * **Key Features**\n * - Seamless integration with any $topic descriptor\n * - Full type safety inherited from topic schema\n * - Real-time message delivery when events are published\n * - Error isolation between subscribers\n * - Support for multiple independent subscribers per topic\n *\n * **Common Use Cases**\n * - Notification services and audit logging\n * - Analytics and metrics collection\n * - Data synchronization and real-time UI updates\n *\n * @example\n * ```ts\n * class UserActivityService {\n * userEvents = $topic({\n * name: \"user-activity\",\n * schema: {\n * payload: t.object({\n * userId: t.text(),\n * action: t.enum([\"login\", \"logout\", \"purchase\"]),\n * timestamp: t.number()\n * })\n * }\n * });\n *\n * activityLogger = $subscriber({\n * topic: this.userEvents,\n * handler: async (message) => {\n * const { userId, action, timestamp } = message.payload;\n * await this.auditLogger.log({\n * userId,\n * action,\n * timestamp\n * });\n * }\n * });\n *\n * async trackUserLogin(userId: string) {\n * await this.userEvents.publish({\n * userId,\n * action: \"login\",\n * timestamp: Date.now()\n * });\n * }\n * }\n * ```\n */\nexport const $subscriber = <T extends TopicMessageSchema>(\n options: SubscriberDescriptorOptions<T>,\n): SubscriberDescriptor<T> => {\n return createDescriptor(SubscriberDescriptor<T>, options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface SubscriberDescriptorOptions<T extends TopicMessageSchema> {\n /**\n * The topic descriptor that this subscriber will listen to for messages.\n *\n * This establishes the connection between the subscriber and its source topic:\n * - The subscriber inherits the topic's message schema for type safety\n * - Messages published to the topic will be automatically delivered to this subscriber\n * - Multiple subscribers can listen to the same topic independently\n * - The subscriber will use the topic's provider and configuration settings\n *\n * **Topic Integration Benefits**:\n * - Type safety: Subscriber handler gets fully typed message payloads\n * - Schema validation: Messages are validated before reaching the subscriber\n * - Real-time delivery: Messages are delivered immediately upon publication\n * - Error isolation: Subscriber errors don't affect the topic or other subscribers\n * - Monitoring: Topic metrics include subscriber processing statistics\n *\n * @example\n * ```ts\n * // First, define a topic\n * userEvents = $topic({\n * name: \"user-activity\",\n * schema: {\n * payload: t.object({ userId: t.text(), action: t.text() })\n * }\n * });\n *\n * // Then, create a subscriber for that topic\n * activitySubscriber = $subscriber({\n * topic: this.userEvents, // Reference the topic descriptor\n * handler: async (message) => { } // Process messages here\n * });\n * ```\n */\n topic: TopicDescriptor<T>;\n\n /**\n * Message handler function that processes individual messages from the topic.\n *\n * This function:\n * - Receives fully typed and validated message payloads from the connected topic\n * - Executes immediately when messages are published to the topic\n * - Should implement the core business logic for reacting to these events\n * - Runs independently of other subscribers to the same topic\n * - Should handle errors gracefully to avoid affecting other subscribers\n * - Has access to the full Alepha dependency injection container\n *\n * **Handler Design Guidelines**:\n * - Keep handlers focused on a single responsibility\n * - Use proper error handling and logging\n * - Consider performance impact for high-frequency topics\n * - Make handlers idempotent when possible for reliability\n * - Validate business rules within the handler logic\n * - Log important processing steps for debugging and monitoring\n *\n * **Error Handling Strategy**:\n * - Log errors but don't re-throw to avoid affecting other subscribers\n * - Use try-catch blocks for external service calls\n * - Implement circuit breakers for resilience with external systems\n * - Monitor error rates and patterns for system health\n * - Consider implementing retry logic for temporary failures\n *\n * **Performance Considerations**:\n * - Keep handler execution time minimal for high-throughput topics\n * - Use background queues for heavy processing triggered by events\n * - Implement batching for efficiency when processing many similar events\n * - Consider async processing patterns for non-critical operations\n *\n * @param message - The topic message with validated payload and optional headers\n * @param message.payload - The typed message data based on the topic's schema\n * @returns Promise that resolves when processing is complete\n *\n * @example\n * ```ts\n * handler: async (message) => {\n * const { userId, eventType, timestamp } = message.payload;\n *\n * try {\n * // Log event receipt\n * this.logger.info(`Processing ${eventType} event for user ${userId}`, {\n * timestamp,\n * userId,\n * eventType\n * });\n *\n * // Perform event-specific processing\n * switch (eventType) {\n * case 'user.login':\n * await this.updateLastLogin(userId, timestamp);\n * await this.sendWelcomeNotification(userId);\n * break;\n * case 'user.logout':\n * await this.updateSessionDuration(userId, timestamp);\n * break;\n * case 'user.purchase':\n * await this.updateRewardsPoints(userId, message.payload.purchaseAmount);\n * await this.triggerRecommendations(userId);\n * break;\n * default:\n * this.logger.warn(`Unknown event type: ${eventType}`);\n * }\n *\n * // Update analytics\n * await this.analytics.track(eventType, {\n * userId,\n * timestamp,\n * source: 'topic-subscriber'\n * });\n *\n * this.logger.info(`Successfully processed ${eventType} for user ${userId}`);\n *\n * } catch (error) {\n * // Log error but don't re-throw to avoid affecting other subscribers\n * this.logger.error(`Failed to process ${eventType} for user ${userId}`, {\n * error: error.message,\n * stack: error.stack,\n * userId,\n * eventType,\n * timestamp\n * });\n *\n * // Optionally send to error tracking service\n * await this.errorTracker.captureException(error, {\n * context: { userId, eventType, timestamp },\n * tags: { component: 'topic-subscriber' }\n * });\n * }\n * }\n * ```\n */\n handler: TopicHandler<T>;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class SubscriberDescriptor<\n T extends TopicMessageSchema,\n> extends Descriptor<SubscriberDescriptorOptions<T>> {}\n\n$subscriber[KIND] = SubscriberDescriptor;\n","export class TopicTimeoutError extends Error {\n public readonly topic: string;\n public readonly timeout: number;\n\n constructor(topic: string, timeout: number) {\n super(`Timeout of ${timeout}ms exceeded for topic ${topic}`);\n this.timeout = timeout;\n this.topic = topic;\n }\n}\n","import { $inject, Alepha } from \"alepha\";\nimport { $subscriber } from \"../descriptors/$subscriber.ts\";\nimport { $topic } from \"../descriptors/$topic.ts\";\n\n/**\n * Base class for topic providers.\n */\nexport abstract class TopicProvider {\n protected readonly alepha = $inject(Alepha);\n\n /**\n * Publish a message to a topic.\n *\n * @param topic - The topic to publish to.\n * @param message - The message to publish.\n */\n public abstract publish(topic: string, message: string): Promise<void>;\n\n /**\n * Subscribe to a topic.\n *\n * @param topic - The topic to subscribe to.\n * @param callback - The callback to call when a message is received.\n */\n public abstract subscribe(\n topic: string,\n callback: SubscribeCallback,\n ): Promise<UnSubscribeFn>;\n\n /**\n * Unsubscribe from a topic.\n *\n * @param topic - The topic to unsubscribe from.\n */\n public abstract unsubscribe(topic: string): Promise<void>;\n\n /**\n * Returns the list of $subscribers for this provider.\n */\n protected subscribers(): Array<() => Promise<unknown>> {\n const handlers: Array<() => Promise<unknown>> = [];\n\n const topics = this.alepha.descriptors($topic);\n\n for (const topic of topics) {\n if (topic.provider !== this) {\n continue;\n }\n\n const handler = topic.options.handler;\n if (handler && topic.provider === this) {\n handlers.push(() => topic.subscribe(handler));\n }\n }\n\n const subscribers = this.alepha.descriptors($subscriber);\n for (const subscriber of subscribers) {\n if (subscriber.options.topic.provider !== this) {\n continue;\n }\n\n handlers.push(() =>\n subscriber.options.topic.subscribe(subscriber.options.handler),\n );\n }\n\n return handlers;\n }\n}\n\nexport type SubscribeCallback = (message: string) => Promise<void> | void;\n\nexport type UnSubscribeFn = () => Promise<void>;\n","import { $hook } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport {\n type SubscribeCallback,\n TopicProvider,\n type UnSubscribeFn,\n} from \"./TopicProvider.ts\";\n\nexport class MemoryTopicProvider extends TopicProvider {\n protected readonly log = $logger();\n protected readonly subscriptions: Record<string, SubscribeCallback[]> = {};\n\n protected readonly start = $hook({\n on: \"start\",\n handler: async () => {\n const subscribers = this.subscribers();\n if (subscribers.length) {\n await Promise.all(subscribers.map((fn) => fn()));\n for (const subscriber of subscribers) {\n this.log.debug(`Subscribed to topic '${subscriber.name}'`);\n }\n }\n },\n });\n\n /**\n * Publish a message to a topic.\n *\n * @param topic\n * @param message\n */\n public async publish(topic: string, message: string): Promise<void> {\n if (!this.subscriptions[topic]) {\n return;\n }\n\n for (const callback of this.subscriptions[topic]) {\n await callback(message);\n }\n }\n\n /**\n * Subscribe to a topic.\n *\n * @param topic - The topic to subscribe to.\n * @param callback\n */\n\n public async subscribe(\n topic: string,\n callback: SubscribeCallback,\n ): Promise<UnSubscribeFn> {\n if (!this.subscriptions[topic]) {\n this.subscriptions[topic] = [];\n }\n\n this.subscriptions[topic].push(callback);\n\n return async () => {\n const callbacks = this.subscriptions[topic];\n if (!callbacks) {\n return;\n }\n\n this.subscriptions[topic] = callbacks.filter((cb) => cb !== callback);\n if (this.subscriptions[topic].length === 0) {\n delete this.subscriptions[topic];\n }\n };\n }\n\n /**\n * Unsubscribe from a topic.\n *\n * @param topic - The topic to unsubscribe from.\n */\n public async unsubscribe(topic: string): Promise<void> {\n delete this.subscriptions[topic];\n }\n}\n","import {\n $inject,\n createDescriptor,\n Descriptor,\n KIND,\n type Service,\n type Static,\n type TSchema,\n} from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n type Timeout,\n} from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { TopicTimeoutError } from \"../errors/TopicTimeoutError.ts\";\nimport { MemoryTopicProvider } from \"../providers/MemoryTopicProvider.ts\";\nimport {\n TopicProvider,\n type UnSubscribeFn,\n} from \"../providers/TopicProvider.ts\";\n\n/**\n * Creates a topic descriptor for publish/subscribe messaging and event-driven architecture.\n *\n * Enables decoupled communication through a pub/sub pattern where publishers send messages\n * and multiple subscribers receive them. Supports type-safe messages, real-time delivery,\n * event filtering, and pluggable backends (memory, Redis, custom providers).\n *\n * **Use Cases**: User notifications, real-time chat, event broadcasting, microservice communication\n *\n * @example\n * ```ts\n * class NotificationService {\n * userActivity = $topic({\n * name: \"user-activity\",\n * schema: {\n * payload: t.object({\n * userId: t.text(),\n * action: t.enum([\"login\", \"logout\", \"purchase\"]),\n * timestamp: t.number()\n * })\n * },\n * handler: async (message) => {\n * console.log(`User ${message.payload.userId}: ${message.payload.action}`);\n * }\n * });\n *\n * async trackLogin(userId: string) {\n * await this.userActivity.publish({ userId, action: \"login\", timestamp: Date.now() });\n * }\n *\n * async subscribeToEvents() {\n * await this.userActivity.subscribe(async (message) => {\n * // Additional subscriber logic\n * });\n * }\n * }\n * ```\n */\nexport const $topic = <T extends TopicMessageSchema>(\n options: TopicDescriptorOptions<T>,\n): TopicDescriptor<T> => {\n return createDescriptor(TopicDescriptor<T>, options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface TopicDescriptorOptions<T extends TopicMessageSchema> {\n /**\n * Unique name identifier for the topic.\n *\n * This name is used for:\n * - Topic identification across the pub/sub system\n * - Message routing between publishers and subscribers\n * - Logging and debugging topic-related operations\n * - Provider-specific topic management (channels, keys, etc.)\n *\n * If not provided, defaults to the property key where the topic is declared.\n *\n * **Naming Conventions**:\n * - Use descriptive, hierarchical names: \"user.activity\", \"order.events\"\n * - Avoid spaces and special characters\n * - Consider using dot notation for categorization\n * - Keep names concise but meaningful\n *\n * @example \"user-activity\"\n * @example \"chat.messages\"\n * @example \"system.health.checks\"\n * @example \"payment.webhooks\"\n */\n name?: string;\n\n /**\n * Human-readable description of the topic's purpose and usage.\n *\n * Used for:\n * - Documentation generation and API references\n * - Developer onboarding and understanding\n * - Monitoring dashboards and admin interfaces\n * - Team communication about system architecture\n *\n * **Description Best Practices**:\n * - Explain what events/messages this topic handles\n * - Mention key use cases and subscribers\n * - Include any important timing or ordering guarantees\n * - Note any special processing requirements\n *\n * @example \"Real-time user activity events for analytics and notifications\"\n * @example \"Order lifecycle events from creation to delivery\"\n * @example \"Chat messages broadcast to all room participants\"\n * @example \"System health checks and service status updates\"\n */\n description?: string;\n\n /**\n * Topic provider configuration for message storage and delivery.\n *\n * Options:\n * - **\"memory\"**: In-memory provider (default for development, lost on restart)\n * - **Service<TopicProvider>**: Custom provider class (e.g., RedisTopicProvider)\n * - **undefined**: Uses the default topic provider from dependency injection\n *\n * **Provider Selection Guidelines**:\n * - **Development**: Use \"memory\" for fast, simple testing without external dependencies\n * - **Production**: Use Redis or message brokers for persistence and scalability\n * - **Distributed systems**: Use Redis/RabbitMQ for cross-service communication\n * - **High-throughput**: Use specialized providers with connection pooling\n * - **Real-time**: Ensure provider supports low-latency message delivery\n *\n * **Provider Capabilities**:\n * - Message persistence and durability\n * - Subscriber management and connection handling\n * - Message ordering and delivery guarantees\n * - Horizontal scaling and load distribution\n *\n * @default Uses injected TopicProvider\n * @example \"memory\"\n * @example RedisTopicProvider\n * @example RabbitMQTopicProvider\n */\n provider?: \"memory\" | Service<TopicProvider>;\n\n /**\n * TypeBox schema defining the structure of messages published to this topic.\n *\n * The schema must include:\n * - **payload**: Required schema for the main message data\n * - **headers**: Optional schema for message metadata\n *\n * This schema:\n * - Validates all messages published to the topic\n * - Provides full TypeScript type inference for subscribers\n * - Ensures type safety between publishers and subscribers\n * - Enables automatic serialization/deserialization\n *\n * **Schema Design Best Practices**:\n * - Keep payload schemas focused and cohesive\n * - Use optional fields for data that might not always be present\n * - Include timestamp fields for event ordering\n * - Consider versioning for schema evolution\n * - Use union types for different event types in the same topic\n *\n * @example\n * ```ts\n * {\n * payload: t.object({\n * eventId: t.text(),\n * eventType: t.enum([\"created\", \"updated\"]),\n * data: t.record(t.text(), t.any()),\n * timestamp: t.number(),\n * userId: t.optional(t.text())\n * }),\n * headers: t.optional(t.object({\n * source: t.text(),\n * correlationId: t.text()\n * }))\n * }\n * ```\n */\n schema: T;\n\n /**\n * Default subscriber handler function that processes messages published to this topic.\n *\n * This handler:\n * - Automatically subscribes when the topic is initialized\n * - Receives all messages published to the topic\n * - Runs for every message without additional subscription setup\n * - Can be supplemented with additional subscribers via `subscribe()` method\n * - Should handle errors gracefully to avoid breaking other subscribers\n *\n * **Handler Design Guidelines**:\n * - Keep handlers focused on a single responsibility\n * - Use proper error handling and logging\n * - Consider performance impact for high-frequency topics\n * - Make handlers idempotent when possible\n * - Validate business rules within the handler logic\n * - Log important processing steps for debugging\n *\n * **Error Handling Strategy**:\n * - Log errors but don't re-throw to avoid affecting other subscribers\n * - Use try-catch blocks for external service calls\n * - Consider implementing circuit breakers for resilience\n * - Monitor error rates and patterns for system health\n *\n * @param message - The topic message with validated payload and headers\n * @param message.payload - The typed message data based on the schema\n * @returns Promise that resolves when processing is complete\n *\n * @example\n * ```ts\n * handler: async (message) => {\n * const { eventType, data, timestamp } = message.payload;\n *\n * try {\n * // Log message receipt\n * this.logger.info(`Processing ${eventType} event`, { timestamp, data });\n *\n * // Process based on event type\n * switch (eventType) {\n * case \"created\":\n * await this.handleCreation(data);\n * break;\n * case \"updated\":\n * await this.handleUpdate(data);\n * break;\n * default:\n * this.logger.warn(`Unknown event type: ${eventType}`);\n * }\n *\n * this.logger.info(`Successfully processed ${eventType} event`);\n *\n * } catch (error) {\n * // Log error but don't re-throw to avoid affecting other subscribers\n * this.logger.error(`Failed to process ${eventType} event`, {\n * error: error.message,\n * eventType,\n * timestamp,\n * data\n * });\n * }\n * }\n * ```\n */\n handler?: TopicHandler<T>;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class TopicDescriptor<T extends TopicMessageSchema> extends Descriptor<\n TopicDescriptorOptions<T>\n> {\n protected readonly log = $logger();\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n public readonly provider = this.$provider();\n\n public get name(): string {\n return this.options.name || this.config.propertyKey;\n }\n\n public async publish(payload: TopicMessage<T>[\"payload\"]): Promise<void> {\n await this.provider.publish(\n this.name,\n JSON.stringify({\n payload: this.alepha.codec.encode(this.options.schema.payload, payload),\n }),\n );\n }\n\n public async subscribe(handler: TopicHandler<T>): Promise<UnSubscribeFn> {\n return this.provider.subscribe(this.name, async (message) => {\n try {\n await handler(this.parseMessage(message));\n } catch (error) {\n this.log.error(\"Message processing has failed\", error);\n }\n });\n }\n\n public async wait(\n options: TopicWaitOptions<T> = {},\n ): Promise<TopicMessage<T>> {\n const filter = options.filter ?? (() => true);\n\n return new Promise((resolve, reject) => {\n const ref: { timeout?: Timeout } = {};\n\n (async () => {\n const clear = await this.provider.subscribe(this.name, (raw) => {\n const message = this.parseMessage(raw);\n if (!filter(message)) {\n return;\n }\n\n ref.timeout?.clear();\n clear();\n resolve(message);\n });\n\n const timeoutDuration = options.timeout ?? [10, \"seconds\"];\n\n ref.timeout = this.dateTimeProvider.createTimeout(() => {\n clear();\n reject(\n new TopicTimeoutError(\n this.name,\n this.dateTimeProvider.duration(timeoutDuration).asMilliseconds(),\n ),\n );\n }, timeoutDuration);\n })();\n });\n }\n\n protected $provider(): TopicProvider {\n if (!this.options.provider) {\n return this.alepha.inject(TopicProvider);\n }\n\n if (this.options.provider === \"memory\") {\n return this.alepha.inject(MemoryTopicProvider);\n }\n\n return this.alepha.inject(this.options.provider);\n }\n\n protected parseMessage(message: string): TopicMessage<T> {\n const { payload } = JSON.parse(message);\n return {\n payload: this.alepha.codec.decode(\n this.options.schema.payload,\n payload,\n ) as TopicMessage<T>[\"payload\"],\n };\n }\n}\n\n$topic[KIND] = TopicDescriptor;\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface TopicMessage<T extends TopicMessageSchema> {\n payload: Static<T[\"payload\"]>;\n}\n\nexport interface TopicWaitOptions<T extends TopicMessageSchema> {\n timeout?: DurationLike;\n filter?: (message: { payload: Static<T[\"payload\"]> }) => boolean;\n}\n\nexport interface TopicMessageSchema {\n payload: TSchema;\n}\n\nexport type TopicHandler<T extends TopicMessageSchema = TopicMessageSchema> = (\n message: TopicMessage<T>,\n) => unknown;\n","import { $module, type Alepha } from \"alepha\";\nimport { $subscriber } from \"./descriptors/$subscriber.ts\";\nimport { $topic } from \"./descriptors/$topic.ts\";\nimport { MemoryTopicProvider } from \"./providers/MemoryTopicProvider.ts\";\nimport { TopicProvider } from \"./providers/TopicProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./descriptors/$subscriber.ts\";\nexport * from \"./descriptors/$topic.ts\";\nexport * from \"./errors/TopicTimeoutError.ts\";\nexport * from \"./providers/MemoryTopicProvider.ts\";\nexport * from \"./providers/TopicProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Generic interface for pub/sub messaging.\n * Gives you the ability to create topics and subscribers.\n * This module provides only a memory implementation of the topic provider.\n *\n * @see {@link $topic}\n * @see {@link $subscriber}\n * @module alepha.topic\n */\nexport const AlephaTopic = $module({\n name: \"alepha.topic\",\n descriptors: [$topic, $subscriber],\n services: [TopicProvider, MemoryTopicProvider],\n register: (alepha: Alepha) =>\n alepha.with({\n optional: true,\n provide: TopicProvider,\n use: MemoryTopicProvider,\n }),\n});\n"],"mappings":"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"}