@signaltree/events 7.3.6 → 7.4.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 (57) hide show
  1. package/dist/angular/handlers.cjs +38 -0
  2. package/dist/angular/handlers.js +35 -0
  3. package/dist/angular/index.cjs +15 -0
  4. package/dist/angular/index.js +3 -0
  5. package/dist/angular/optimistic-updates.cjs +161 -0
  6. package/dist/angular/optimistic-updates.js +159 -0
  7. package/{angular.cjs.js → dist/angular/websocket.service.cjs} +0 -194
  8. package/{angular.esm.js → dist/angular/websocket.service.js} +1 -191
  9. package/dist/core/error-classification.cjs +282 -0
  10. package/dist/core/error-classification.js +276 -0
  11. package/{factory.cjs.js → dist/core/factory.cjs} +3 -40
  12. package/{factory.esm.js → dist/core/factory.js} +2 -37
  13. package/dist/core/idempotency.cjs +252 -0
  14. package/dist/core/idempotency.js +247 -0
  15. package/dist/core/registry.cjs +183 -0
  16. package/dist/core/registry.js +180 -0
  17. package/dist/core/types.cjs +41 -0
  18. package/dist/core/types.js +38 -0
  19. package/{index.cjs.js → dist/core/validation.cjs} +1 -23
  20. package/{index.esm.js → dist/core/validation.js} +1 -4
  21. package/dist/index.cjs +43 -0
  22. package/dist/index.js +7 -0
  23. package/dist/nestjs/base.subscriber.cjs +287 -0
  24. package/dist/nestjs/base.subscriber.js +287 -0
  25. package/dist/nestjs/decorators.cjs +35 -0
  26. package/dist/nestjs/decorators.js +32 -0
  27. package/dist/nestjs/dlq.service.cjs +249 -0
  28. package/dist/nestjs/dlq.service.js +249 -0
  29. package/dist/nestjs/event-bus.module.cjs +152 -0
  30. package/dist/nestjs/event-bus.module.js +152 -0
  31. package/dist/nestjs/event-bus.service.cjs +243 -0
  32. package/dist/nestjs/event-bus.service.js +243 -0
  33. package/dist/nestjs/index.cjs +33 -0
  34. package/dist/nestjs/index.js +6 -0
  35. package/dist/nestjs/tokens.cjs +14 -0
  36. package/dist/nestjs/tokens.js +9 -0
  37. package/dist/testing/assertions.cjs +172 -0
  38. package/dist/testing/assertions.js +169 -0
  39. package/dist/testing/factories.cjs +122 -0
  40. package/dist/testing/factories.js +119 -0
  41. package/dist/testing/helpers.cjs +233 -0
  42. package/dist/testing/helpers.js +227 -0
  43. package/dist/testing/index.cjs +20 -0
  44. package/dist/testing/index.js +4 -0
  45. package/dist/testing/mock-event-bus.cjs +237 -0
  46. package/dist/testing/mock-event-bus.js +234 -0
  47. package/package.json +35 -23
  48. package/angular.d.ts +0 -1
  49. package/idempotency.cjs.js +0 -713
  50. package/idempotency.esm.js +0 -701
  51. package/index.d.ts +0 -1
  52. package/nestjs.cjs.js +0 -951
  53. package/nestjs.d.ts +0 -1
  54. package/nestjs.esm.js +0 -944
  55. package/testing.cjs.js +0 -755
  56. package/testing.d.ts +0 -1
  57. package/testing.esm.js +0 -743
@@ -0,0 +1,152 @@
1
+ import { __decorate } from 'tslib';
2
+ import { Module } from '@nestjs/common';
3
+ import { DlqService } from './dlq.service.js';
4
+ import { EventBusService } from './event-bus.service.js';
5
+ import { EVENT_BUS_CONFIG, EVENT_REGISTRY, IDEMPOTENCY_STORE, ERROR_CLASSIFIER } from './tokens.js';
6
+ import { createEventRegistry } from '../core/registry.js';
7
+ import { createInMemoryIdempotencyStore } from '../core/idempotency.js';
8
+ import { createErrorClassifier } from '../core/error-classification.js';
9
+
10
+ var EventBusModule_1;
11
+ /**
12
+ * Default queue configuration based on priorities
13
+ */
14
+ const DEFAULT_QUEUES = [{
15
+ name: 'events-critical',
16
+ priorities: ['critical'],
17
+ concurrency: 10
18
+ }, {
19
+ name: 'events-high',
20
+ priorities: ['high'],
21
+ concurrency: 8
22
+ }, {
23
+ name: 'events-normal',
24
+ priorities: ['normal'],
25
+ concurrency: 5
26
+ }, {
27
+ name: 'events-low',
28
+ priorities: ['low'],
29
+ concurrency: 3
30
+ }, {
31
+ name: 'events-bulk',
32
+ priorities: ['bulk'],
33
+ concurrency: 2,
34
+ rateLimit: {
35
+ max: 100,
36
+ duration: 1000
37
+ }
38
+ }];
39
+ let EventBusModule = EventBusModule_1 = class EventBusModule {
40
+ /**
41
+ * Register the EventBus module with configuration
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * @Module({
46
+ * imports: [
47
+ * EventBusModule.forRoot({
48
+ * redis: { host: 'localhost', port: 6379 },
49
+ * queues: [
50
+ * { name: 'critical', priorities: ['critical'], concurrency: 10 },
51
+ * { name: 'normal', priorities: ['high', 'normal'], concurrency: 5 },
52
+ * ],
53
+ * }),
54
+ * ],
55
+ * })
56
+ * export class AppModule {}
57
+ * ```
58
+ */
59
+ static forRoot(config) {
60
+ const providers = EventBusModule_1.createProviders(config);
61
+ return {
62
+ module: EventBusModule_1,
63
+ global: true,
64
+ providers,
65
+ exports: [EventBusService, DlqService, EVENT_BUS_CONFIG, EVENT_REGISTRY, IDEMPOTENCY_STORE, ERROR_CLASSIFIER]
66
+ };
67
+ }
68
+ /**
69
+ * Register the EventBus module with async configuration
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * @Module({
74
+ * imports: [
75
+ * EventBusModule.forRootAsync({
76
+ * imports: [ConfigModule],
77
+ * useFactory: (configService: ConfigService) => ({
78
+ * redis: {
79
+ * host: configService.get('REDIS_HOST'),
80
+ * port: configService.get('REDIS_PORT'),
81
+ * },
82
+ * }),
83
+ * inject: [ConfigService],
84
+ * }),
85
+ * ],
86
+ * })
87
+ * export class AppModule {}
88
+ * ```
89
+ */
90
+ static forRootAsync(asyncConfig) {
91
+ const configProvider = {
92
+ provide: EVENT_BUS_CONFIG,
93
+ useFactory: asyncConfig.useFactory,
94
+ inject: asyncConfig.inject ?? []
95
+ };
96
+ const registryProvider = {
97
+ provide: EVENT_REGISTRY,
98
+ useFactory: config => {
99
+ return createEventRegistry(config.registry);
100
+ },
101
+ inject: [EVENT_BUS_CONFIG]
102
+ };
103
+ const idempotencyProvider = {
104
+ provide: IDEMPOTENCY_STORE,
105
+ useFactory: config => {
106
+ return config.idempotencyStore ?? createInMemoryIdempotencyStore();
107
+ },
108
+ inject: [EVENT_BUS_CONFIG]
109
+ };
110
+ const errorClassifierProvider = {
111
+ provide: ERROR_CLASSIFIER,
112
+ useFactory: config => {
113
+ return createErrorClassifier(config.errorClassifier);
114
+ },
115
+ inject: [EVENT_BUS_CONFIG]
116
+ };
117
+ return {
118
+ module: EventBusModule_1,
119
+ global: true,
120
+ imports: asyncConfig.imports ?? [],
121
+ providers: [configProvider, registryProvider, idempotencyProvider, errorClassifierProvider, EventBusService, DlqService],
122
+ exports: [EventBusService, DlqService, EVENT_BUS_CONFIG, EVENT_REGISTRY, IDEMPOTENCY_STORE, ERROR_CLASSIFIER]
123
+ };
124
+ }
125
+ static createProviders(config) {
126
+ const queues = config.queues ?? DEFAULT_QUEUES;
127
+ const fullConfig = {
128
+ ...config,
129
+ queues,
130
+ enableDlq: config.enableDlq ?? true,
131
+ dlqQueueName: config.dlqQueueName ?? 'dead-letter',
132
+ enableMetrics: config.enableMetrics ?? true,
133
+ metricsPrefix: config.metricsPrefix ?? 'signaltree_events'
134
+ };
135
+ return [{
136
+ provide: EVENT_BUS_CONFIG,
137
+ useValue: fullConfig
138
+ }, {
139
+ provide: EVENT_REGISTRY,
140
+ useFactory: () => createEventRegistry(config.registry)
141
+ }, {
142
+ provide: IDEMPOTENCY_STORE,
143
+ useValue: config.idempotencyStore ?? createInMemoryIdempotencyStore()
144
+ }, {
145
+ provide: ERROR_CLASSIFIER,
146
+ useFactory: () => createErrorClassifier(config.errorClassifier)
147
+ }, EventBusService, DlqService];
148
+ }
149
+ };
150
+ EventBusModule = EventBusModule_1 = __decorate([Module({})], EventBusModule);
151
+
152
+ export { EventBusModule };
@@ -0,0 +1,243 @@
1
+ 'use strict';
2
+
3
+ var tslib = require('tslib');
4
+ var common = require('@nestjs/common');
5
+ var bullmq = require('bullmq');
6
+ var factory = require('../core/factory.cjs');
7
+ var registry = require('../core/registry.cjs');
8
+ var tokens = require('./tokens.cjs');
9
+
10
+ var EventBusService_1;
11
+ exports.EventBusService = EventBusService_1 = class EventBusService {
12
+ config;
13
+ registry;
14
+ logger = new common.Logger(EventBusService_1.name);
15
+ queues = new Map();
16
+ priorityToQueue = new Map();
17
+ connection;
18
+ isReady = false;
19
+ constructor(config, registry) {
20
+ this.config = config;
21
+ this.registry = registry;
22
+ this.connection = {
23
+ host: config.redis.host,
24
+ port: config.redis.port,
25
+ password: config.redis.password,
26
+ db: config.redis.db,
27
+ maxRetriesPerRequest: config.redis.maxRetriesPerRequest ?? 3
28
+ };
29
+ }
30
+ async onModuleInit() {
31
+ this.logger.log('Initializing EventBus queues...');
32
+ // Create queues
33
+ for (const queueConfig of this.config.queues ?? []) {
34
+ const queue = new bullmq.Queue(queueConfig.name, {
35
+ connection: this.connection,
36
+ defaultJobOptions: {
37
+ removeOnComplete: 1000,
38
+ // Keep last 1000 completed jobs
39
+ removeOnFail: 5000,
40
+ // Keep last 5000 failed jobs
41
+ attempts: 5,
42
+ backoff: {
43
+ type: 'exponential',
44
+ delay: 1000
45
+ }
46
+ }
47
+ });
48
+ // Map priorities to this queue
49
+ for (const priority of queueConfig.priorities) {
50
+ this.priorityToQueue.set(priority, queueConfig.name);
51
+ }
52
+ const instance = {
53
+ config: queueConfig,
54
+ queue
55
+ };
56
+ // Optionally create queue events listener for monitoring
57
+ if (this.config.enableMetrics) {
58
+ instance.events = new bullmq.QueueEvents(queueConfig.name, {
59
+ connection: this.connection
60
+ });
61
+ this.setupQueueEventListeners(instance);
62
+ }
63
+ this.queues.set(queueConfig.name, instance);
64
+ this.logger.log(`Queue "${queueConfig.name}" initialized for priorities: ${queueConfig.priorities.join(', ')}`);
65
+ }
66
+ this.isReady = true;
67
+ this.logger.log(`EventBus ready with ${this.queues.size} queues`);
68
+ }
69
+ async onModuleDestroy() {
70
+ this.logger.log('Shutting down EventBus...');
71
+ const closePromises = [];
72
+ for (const [name, instance] of this.queues) {
73
+ this.logger.debug(`Closing queue "${name}"...`);
74
+ closePromises.push(instance.queue.close());
75
+ if (instance.events) {
76
+ closePromises.push(instance.events.close());
77
+ }
78
+ }
79
+ await Promise.all(closePromises);
80
+ this.queues.clear();
81
+ this.isReady = false;
82
+ this.logger.log('EventBus shutdown complete');
83
+ }
84
+ /**
85
+ * Publish an event
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * await eventBus.publish({
90
+ * type: 'TradeProposalCreated',
91
+ * data: {
92
+ * tradeId: '123',
93
+ * initiatorId: 'user-1',
94
+ * recipientId: 'user-2',
95
+ * },
96
+ * });
97
+ * ```
98
+ */
99
+ async publish(event, options = {}) {
100
+ if (!this.isReady) {
101
+ throw new Error('EventBus is not ready. Wait for module initialization.');
102
+ }
103
+ // Build complete event
104
+ const eventId = options.id ?? event.id ?? factory.generateEventId();
105
+ const correlationId = options.correlationId ?? event.correlationId ?? factory.generateCorrelationId();
106
+ const timestamp = event.timestamp ?? new Date().toISOString();
107
+ const fullEvent = {
108
+ ...event,
109
+ id: eventId,
110
+ correlationId,
111
+ causationId: options.causationId ?? event.causationId,
112
+ timestamp,
113
+ priority: options.priority ?? event.priority ?? 'normal'
114
+ };
115
+ // Validate event against registry
116
+ const validated = this.registry.validate(fullEvent);
117
+ // Determine queue based on priority
118
+ const priority = validated.priority ?? 'normal';
119
+ const queueName = options.queue ?? this.getQueueForPriority(priority);
120
+ const instance = this.queues.get(queueName);
121
+ if (!instance) {
122
+ throw new Error(`Queue "${queueName}" not found. Available: ${Array.from(this.queues.keys()).join(', ')}`);
123
+ }
124
+ // Publish to BullMQ
125
+ const jobId = options.jobId ?? eventId;
126
+ const job = await instance.queue.add(validated.type,
127
+ // Job name = event type
128
+ validated, {
129
+ jobId,
130
+ delay: options.delay,
131
+ priority: this.getPriorityNumber(priority),
132
+ ...options.jobOptions
133
+ });
134
+ this.logger.debug(`Published event ${validated.type}:${eventId} to queue ${queueName} (job: ${job.id})`);
135
+ return {
136
+ eventId,
137
+ jobId: job.id ?? eventId,
138
+ queue: queueName,
139
+ correlationId
140
+ };
141
+ }
142
+ /**
143
+ * Publish multiple events in a batch
144
+ */
145
+ async publishBatch(events, options = {}) {
146
+ // Use same correlation ID for all events in batch
147
+ const correlationId = options.correlationId ?? factory.generateCorrelationId();
148
+ const results = await Promise.all(events.map((event, index) => this.publish(event, {
149
+ ...options,
150
+ correlationId,
151
+ causationId: index > 0 ? events[index - 1].id : options.causationId
152
+ })));
153
+ return results;
154
+ }
155
+ /**
156
+ * Get queue for a given priority
157
+ */
158
+ getQueueForPriority(priority) {
159
+ const queueName = this.priorityToQueue.get(priority);
160
+ if (!queueName) {
161
+ // Fall back to normal queue
162
+ return this.priorityToQueue.get('normal') ?? 'events-normal';
163
+ }
164
+ return queueName;
165
+ }
166
+ /**
167
+ * Get queue stats
168
+ */
169
+ async getQueueStats(queueName) {
170
+ const instance = this.queues.get(queueName);
171
+ if (!instance) {
172
+ throw new Error(`Queue "${queueName}" not found`);
173
+ }
174
+ const [waiting, active, completed, failed, delayed] = await Promise.all([instance.queue.getWaitingCount(), instance.queue.getActiveCount(), instance.queue.getCompletedCount(), instance.queue.getFailedCount(), instance.queue.getDelayedCount()]);
175
+ return {
176
+ waiting,
177
+ active,
178
+ completed,
179
+ failed,
180
+ delayed
181
+ };
182
+ }
183
+ /**
184
+ * Get all queue names
185
+ */
186
+ getQueueNames() {
187
+ return Array.from(this.queues.keys());
188
+ }
189
+ /**
190
+ * Get underlying BullMQ queue for advanced operations
191
+ */
192
+ getQueue(name) {
193
+ return this.queues.get(name)?.queue;
194
+ }
195
+ /**
196
+ * Check if service is ready
197
+ */
198
+ isServiceReady() {
199
+ return this.isReady;
200
+ }
201
+ /**
202
+ * Convert priority string to number for BullMQ (lower = higher priority)
203
+ */
204
+ getPriorityNumber(priority) {
205
+ switch (priority) {
206
+ case 'critical':
207
+ return 1;
208
+ case 'high':
209
+ return 2;
210
+ case 'normal':
211
+ return 3;
212
+ case 'low':
213
+ return 4;
214
+ case 'bulk':
215
+ return 5;
216
+ default:
217
+ return 3;
218
+ }
219
+ }
220
+ /**
221
+ * Setup event listeners for monitoring
222
+ */
223
+ setupQueueEventListeners(instance) {
224
+ if (!instance.events) return;
225
+ instance.events.on('completed', ({
226
+ jobId
227
+ }) => {
228
+ this.logger.debug(`Job ${jobId} completed in queue ${instance.config.name}`);
229
+ });
230
+ instance.events.on('failed', ({
231
+ jobId,
232
+ failedReason
233
+ }) => {
234
+ this.logger.warn(`Job ${jobId} failed in queue ${instance.config.name}: ${failedReason}`);
235
+ });
236
+ instance.events.on('stalled', ({
237
+ jobId
238
+ }) => {
239
+ this.logger.warn(`Job ${jobId} stalled in queue ${instance.config.name}`);
240
+ });
241
+ }
242
+ };
243
+ exports.EventBusService = EventBusService_1 = tslib.__decorate([common.Injectable(), tslib.__param(0, common.Inject(tokens.EVENT_BUS_CONFIG)), tslib.__param(1, common.Inject(tokens.EVENT_REGISTRY)), tslib.__metadata("design:paramtypes", [Object, registry.EventRegistry])], exports.EventBusService);
@@ -0,0 +1,243 @@
1
+ import { __decorate, __param, __metadata } from 'tslib';
2
+ import { Injectable, Inject, Logger } from '@nestjs/common';
3
+ import { Queue, QueueEvents } from 'bullmq';
4
+ import { generateEventId, generateCorrelationId } from '../core/factory.js';
5
+ import { EventRegistry } from '../core/registry.js';
6
+ import { EVENT_BUS_CONFIG, EVENT_REGISTRY } from './tokens.js';
7
+
8
+ var EventBusService_1;
9
+ let EventBusService = EventBusService_1 = class EventBusService {
10
+ config;
11
+ registry;
12
+ logger = new Logger(EventBusService_1.name);
13
+ queues = new Map();
14
+ priorityToQueue = new Map();
15
+ connection;
16
+ isReady = false;
17
+ constructor(config, registry) {
18
+ this.config = config;
19
+ this.registry = registry;
20
+ this.connection = {
21
+ host: config.redis.host,
22
+ port: config.redis.port,
23
+ password: config.redis.password,
24
+ db: config.redis.db,
25
+ maxRetriesPerRequest: config.redis.maxRetriesPerRequest ?? 3
26
+ };
27
+ }
28
+ async onModuleInit() {
29
+ this.logger.log('Initializing EventBus queues...');
30
+ // Create queues
31
+ for (const queueConfig of this.config.queues ?? []) {
32
+ const queue = new Queue(queueConfig.name, {
33
+ connection: this.connection,
34
+ defaultJobOptions: {
35
+ removeOnComplete: 1000,
36
+ // Keep last 1000 completed jobs
37
+ removeOnFail: 5000,
38
+ // Keep last 5000 failed jobs
39
+ attempts: 5,
40
+ backoff: {
41
+ type: 'exponential',
42
+ delay: 1000
43
+ }
44
+ }
45
+ });
46
+ // Map priorities to this queue
47
+ for (const priority of queueConfig.priorities) {
48
+ this.priorityToQueue.set(priority, queueConfig.name);
49
+ }
50
+ const instance = {
51
+ config: queueConfig,
52
+ queue
53
+ };
54
+ // Optionally create queue events listener for monitoring
55
+ if (this.config.enableMetrics) {
56
+ instance.events = new QueueEvents(queueConfig.name, {
57
+ connection: this.connection
58
+ });
59
+ this.setupQueueEventListeners(instance);
60
+ }
61
+ this.queues.set(queueConfig.name, instance);
62
+ this.logger.log(`Queue "${queueConfig.name}" initialized for priorities: ${queueConfig.priorities.join(', ')}`);
63
+ }
64
+ this.isReady = true;
65
+ this.logger.log(`EventBus ready with ${this.queues.size} queues`);
66
+ }
67
+ async onModuleDestroy() {
68
+ this.logger.log('Shutting down EventBus...');
69
+ const closePromises = [];
70
+ for (const [name, instance] of this.queues) {
71
+ this.logger.debug(`Closing queue "${name}"...`);
72
+ closePromises.push(instance.queue.close());
73
+ if (instance.events) {
74
+ closePromises.push(instance.events.close());
75
+ }
76
+ }
77
+ await Promise.all(closePromises);
78
+ this.queues.clear();
79
+ this.isReady = false;
80
+ this.logger.log('EventBus shutdown complete');
81
+ }
82
+ /**
83
+ * Publish an event
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * await eventBus.publish({
88
+ * type: 'TradeProposalCreated',
89
+ * data: {
90
+ * tradeId: '123',
91
+ * initiatorId: 'user-1',
92
+ * recipientId: 'user-2',
93
+ * },
94
+ * });
95
+ * ```
96
+ */
97
+ async publish(event, options = {}) {
98
+ if (!this.isReady) {
99
+ throw new Error('EventBus is not ready. Wait for module initialization.');
100
+ }
101
+ // Build complete event
102
+ const eventId = options.id ?? event.id ?? generateEventId();
103
+ const correlationId = options.correlationId ?? event.correlationId ?? generateCorrelationId();
104
+ const timestamp = event.timestamp ?? new Date().toISOString();
105
+ const fullEvent = {
106
+ ...event,
107
+ id: eventId,
108
+ correlationId,
109
+ causationId: options.causationId ?? event.causationId,
110
+ timestamp,
111
+ priority: options.priority ?? event.priority ?? 'normal'
112
+ };
113
+ // Validate event against registry
114
+ const validated = this.registry.validate(fullEvent);
115
+ // Determine queue based on priority
116
+ const priority = validated.priority ?? 'normal';
117
+ const queueName = options.queue ?? this.getQueueForPriority(priority);
118
+ const instance = this.queues.get(queueName);
119
+ if (!instance) {
120
+ throw new Error(`Queue "${queueName}" not found. Available: ${Array.from(this.queues.keys()).join(', ')}`);
121
+ }
122
+ // Publish to BullMQ
123
+ const jobId = options.jobId ?? eventId;
124
+ const job = await instance.queue.add(validated.type,
125
+ // Job name = event type
126
+ validated, {
127
+ jobId,
128
+ delay: options.delay,
129
+ priority: this.getPriorityNumber(priority),
130
+ ...options.jobOptions
131
+ });
132
+ this.logger.debug(`Published event ${validated.type}:${eventId} to queue ${queueName} (job: ${job.id})`);
133
+ return {
134
+ eventId,
135
+ jobId: job.id ?? eventId,
136
+ queue: queueName,
137
+ correlationId
138
+ };
139
+ }
140
+ /**
141
+ * Publish multiple events in a batch
142
+ */
143
+ async publishBatch(events, options = {}) {
144
+ // Use same correlation ID for all events in batch
145
+ const correlationId = options.correlationId ?? generateCorrelationId();
146
+ const results = await Promise.all(events.map((event, index) => this.publish(event, {
147
+ ...options,
148
+ correlationId,
149
+ causationId: index > 0 ? events[index - 1].id : options.causationId
150
+ })));
151
+ return results;
152
+ }
153
+ /**
154
+ * Get queue for a given priority
155
+ */
156
+ getQueueForPriority(priority) {
157
+ const queueName = this.priorityToQueue.get(priority);
158
+ if (!queueName) {
159
+ // Fall back to normal queue
160
+ return this.priorityToQueue.get('normal') ?? 'events-normal';
161
+ }
162
+ return queueName;
163
+ }
164
+ /**
165
+ * Get queue stats
166
+ */
167
+ async getQueueStats(queueName) {
168
+ const instance = this.queues.get(queueName);
169
+ if (!instance) {
170
+ throw new Error(`Queue "${queueName}" not found`);
171
+ }
172
+ const [waiting, active, completed, failed, delayed] = await Promise.all([instance.queue.getWaitingCount(), instance.queue.getActiveCount(), instance.queue.getCompletedCount(), instance.queue.getFailedCount(), instance.queue.getDelayedCount()]);
173
+ return {
174
+ waiting,
175
+ active,
176
+ completed,
177
+ failed,
178
+ delayed
179
+ };
180
+ }
181
+ /**
182
+ * Get all queue names
183
+ */
184
+ getQueueNames() {
185
+ return Array.from(this.queues.keys());
186
+ }
187
+ /**
188
+ * Get underlying BullMQ queue for advanced operations
189
+ */
190
+ getQueue(name) {
191
+ return this.queues.get(name)?.queue;
192
+ }
193
+ /**
194
+ * Check if service is ready
195
+ */
196
+ isServiceReady() {
197
+ return this.isReady;
198
+ }
199
+ /**
200
+ * Convert priority string to number for BullMQ (lower = higher priority)
201
+ */
202
+ getPriorityNumber(priority) {
203
+ switch (priority) {
204
+ case 'critical':
205
+ return 1;
206
+ case 'high':
207
+ return 2;
208
+ case 'normal':
209
+ return 3;
210
+ case 'low':
211
+ return 4;
212
+ case 'bulk':
213
+ return 5;
214
+ default:
215
+ return 3;
216
+ }
217
+ }
218
+ /**
219
+ * Setup event listeners for monitoring
220
+ */
221
+ setupQueueEventListeners(instance) {
222
+ if (!instance.events) return;
223
+ instance.events.on('completed', ({
224
+ jobId
225
+ }) => {
226
+ this.logger.debug(`Job ${jobId} completed in queue ${instance.config.name}`);
227
+ });
228
+ instance.events.on('failed', ({
229
+ jobId,
230
+ failedReason
231
+ }) => {
232
+ this.logger.warn(`Job ${jobId} failed in queue ${instance.config.name}: ${failedReason}`);
233
+ });
234
+ instance.events.on('stalled', ({
235
+ jobId
236
+ }) => {
237
+ this.logger.warn(`Job ${jobId} stalled in queue ${instance.config.name}`);
238
+ });
239
+ }
240
+ };
241
+ EventBusService = EventBusService_1 = __decorate([Injectable(), __param(0, Inject(EVENT_BUS_CONFIG)), __param(1, Inject(EVENT_REGISTRY)), __metadata("design:paramtypes", [Object, EventRegistry])], EventBusService);
242
+
243
+ export { EventBusService };
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ var eventBus_module = require('./event-bus.module.cjs');
4
+ var eventBus_service = require('./event-bus.service.cjs');
5
+ var base_subscriber = require('./base.subscriber.cjs');
6
+ var dlq_service = require('./dlq.service.cjs');
7
+ var decorators = require('./decorators.cjs');
8
+ var tokens = require('./tokens.cjs');
9
+
10
+
11
+
12
+ Object.defineProperty(exports, "EventBusModule", {
13
+ enumerable: true,
14
+ get: function () { return eventBus_module.EventBusModule; }
15
+ });
16
+ Object.defineProperty(exports, "EventBusService", {
17
+ enumerable: true,
18
+ get: function () { return eventBus_service.EventBusService; }
19
+ });
20
+ Object.defineProperty(exports, "BaseSubscriber", {
21
+ enumerable: true,
22
+ get: function () { return base_subscriber.BaseSubscriber; }
23
+ });
24
+ Object.defineProperty(exports, "DlqService", {
25
+ enumerable: true,
26
+ get: function () { return dlq_service.DlqService; }
27
+ });
28
+ exports.EVENT_HANDLER_METADATA = decorators.EVENT_HANDLER_METADATA;
29
+ exports.OnEvent = decorators.OnEvent;
30
+ exports.ERROR_CLASSIFIER = tokens.ERROR_CLASSIFIER;
31
+ exports.EVENT_BUS_CONFIG = tokens.EVENT_BUS_CONFIG;
32
+ exports.EVENT_REGISTRY = tokens.EVENT_REGISTRY;
33
+ exports.IDEMPOTENCY_STORE = tokens.IDEMPOTENCY_STORE;
@@ -0,0 +1,6 @@
1
+ export { EventBusModule } from './event-bus.module.js';
2
+ export { EventBusService } from './event-bus.service.js';
3
+ export { BaseSubscriber } from './base.subscriber.js';
4
+ export { DlqService } from './dlq.service.js';
5
+ export { EVENT_HANDLER_METADATA, OnEvent } from './decorators.js';
6
+ export { ERROR_CLASSIFIER, EVENT_BUS_CONFIG, EVENT_REGISTRY, IDEMPOTENCY_STORE } from './tokens.js';
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Injection tokens for the EventBus module
5
+ */
6
+ const EVENT_BUS_CONFIG = Symbol('EVENT_BUS_CONFIG');
7
+ const EVENT_REGISTRY = Symbol('EVENT_REGISTRY');
8
+ const IDEMPOTENCY_STORE = Symbol('IDEMPOTENCY_STORE');
9
+ const ERROR_CLASSIFIER = Symbol('ERROR_CLASSIFIER');
10
+
11
+ exports.ERROR_CLASSIFIER = ERROR_CLASSIFIER;
12
+ exports.EVENT_BUS_CONFIG = EVENT_BUS_CONFIG;
13
+ exports.EVENT_REGISTRY = EVENT_REGISTRY;
14
+ exports.IDEMPOTENCY_STORE = IDEMPOTENCY_STORE;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Injection tokens for the EventBus module
3
+ */
4
+ const EVENT_BUS_CONFIG = Symbol('EVENT_BUS_CONFIG');
5
+ const EVENT_REGISTRY = Symbol('EVENT_REGISTRY');
6
+ const IDEMPOTENCY_STORE = Symbol('IDEMPOTENCY_STORE');
7
+ const ERROR_CLASSIFIER = Symbol('ERROR_CLASSIFIER');
8
+
9
+ export { ERROR_CLASSIFIER, EVENT_BUS_CONFIG, EVENT_REGISTRY, IDEMPOTENCY_STORE };