@signaltree/events 7.3.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.
@@ -0,0 +1,169 @@
1
+ import { Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
2
+ import { ClassificationResult } from '../core/error-classification';
3
+ import { IdempotencyStore } from '../core/idempotency';
4
+ import { BaseEvent, EventPriority } from '../core/types';
5
+ import { DlqService } from './dlq.service';
6
+ import { EventBusModuleConfig } from './event-bus.module';
7
+ /**
8
+ * Base Subscriber - Abstract class for event subscribers
9
+ *
10
+ * Provides:
11
+ * - Automatic idempotency checking
12
+ * - Retry with exponential backoff
13
+ * - Error classification and DLQ routing
14
+ * - Metrics collection
15
+ * - Graceful shutdown
16
+ */
17
+ /**
18
+ * Subscriber configuration
19
+ */
20
+ export interface SubscriberConfig {
21
+ /** Unique subscriber name */
22
+ name: string;
23
+ /** Event types to subscribe to */
24
+ eventTypes: string[];
25
+ /** Queue to process from (or use priority to auto-select) */
26
+ queue?: string;
27
+ /** Priority level (used to select queue if queue not specified) */
28
+ priority?: EventPriority;
29
+ /** Number of concurrent jobs to process */
30
+ concurrency?: number;
31
+ /** Lock duration in ms (how long a job is locked while processing) */
32
+ lockDuration?: number;
33
+ /** Stalled check interval in ms */
34
+ stalledInterval?: number;
35
+ /** Enable idempotency checking (default: true) */
36
+ idempotency?: boolean;
37
+ /** Skip DLQ for this subscriber */
38
+ skipDlq?: boolean;
39
+ }
40
+ /**
41
+ * Result of processing an event
42
+ */
43
+ export interface ProcessingResult {
44
+ /** Whether processing succeeded */
45
+ success: boolean;
46
+ /** Optional result data (stored for idempotent responses) */
47
+ result?: unknown;
48
+ /** Error if failed */
49
+ error?: Error;
50
+ /** Whether to skip DLQ (useful for expected failures) */
51
+ skipDlq?: boolean;
52
+ /** Custom retry delay override */
53
+ retryDelay?: number;
54
+ }
55
+ /**
56
+ * Subscriber metrics
57
+ */
58
+ export interface SubscriberMetrics {
59
+ processed: number;
60
+ succeeded: number;
61
+ failed: number;
62
+ retried: number;
63
+ dlqSent: number;
64
+ duplicatesSkipped: number;
65
+ avgProcessingTimeMs: number;
66
+ lastProcessedAt?: Date;
67
+ }
68
+ /**
69
+ * Base class for event subscribers
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * @Injectable()
74
+ * export class TradeSubscriber extends BaseSubscriber {
75
+ * protected readonly config: SubscriberConfig = {
76
+ * name: 'trade-subscriber',
77
+ * eventTypes: ['TradeProposalCreated', 'TradeAccepted'],
78
+ * priority: 'high',
79
+ * concurrency: 5,
80
+ * };
81
+ *
82
+ * async handle(event: TradeProposalCreated | TradeAccepted): Promise<ProcessingResult> {
83
+ * switch (event.type) {
84
+ * case 'TradeProposalCreated':
85
+ * await this.handleTradeCreated(event);
86
+ * break;
87
+ * case 'TradeAccepted':
88
+ * await this.handleTradeAccepted(event);
89
+ * break;
90
+ * }
91
+ * return { success: true };
92
+ * }
93
+ * }
94
+ * ```
95
+ */
96
+ export declare abstract class BaseSubscriber<TEvent extends BaseEvent = BaseEvent> implements OnModuleInit, OnModuleDestroy {
97
+ protected readonly busConfig: EventBusModuleConfig;
98
+ protected readonly idempotencyStore: IdempotencyStore;
99
+ protected readonly errorClassifier: {
100
+ classify: (e: unknown) => ClassificationResult;
101
+ };
102
+ protected readonly dlqService: DlqService;
103
+ protected readonly logger: Logger;
104
+ protected abstract readonly config: SubscriberConfig;
105
+ private worker?;
106
+ private connection;
107
+ private metrics;
108
+ constructor(busConfig: EventBusModuleConfig, idempotencyStore: IdempotencyStore, errorClassifier: {
109
+ classify: (e: unknown) => ClassificationResult;
110
+ }, dlqService: DlqService);
111
+ /**
112
+ * Handle the event - implement in subclass
113
+ */
114
+ protected abstract handle(event: TEvent): Promise<ProcessingResult>;
115
+ /**
116
+ * Called before processing starts (for setup/validation)
117
+ */
118
+ protected beforeProcess(_event: TEvent): Promise<void>;
119
+ /**
120
+ * Called after processing completes (for cleanup)
121
+ */
122
+ protected afterProcess(_event: TEvent, _result: ProcessingResult): Promise<void>;
123
+ onModuleInit(): Promise<void>;
124
+ onModuleDestroy(): Promise<void>;
125
+ /**
126
+ * Get queue name based on config
127
+ */
128
+ protected getQueueName(): string;
129
+ /**
130
+ * Process a job with idempotency and error handling
131
+ */
132
+ private processJob;
133
+ /**
134
+ * Handle processing error
135
+ */
136
+ private handleError;
137
+ /**
138
+ * Check idempotency
139
+ */
140
+ private checkIdempotency;
141
+ /**
142
+ * Send failed event to DLQ
143
+ */
144
+ private sendToDlq;
145
+ /**
146
+ * Update metrics
147
+ */
148
+ private updateMetrics;
149
+ /**
150
+ * Setup worker event listeners
151
+ */
152
+ private setupWorkerListeners;
153
+ /**
154
+ * Get current metrics
155
+ */
156
+ getMetrics(): SubscriberMetrics;
157
+ /**
158
+ * Pause processing
159
+ */
160
+ pause(): Promise<void>;
161
+ /**
162
+ * Resume processing
163
+ */
164
+ resume(): Promise<void>;
165
+ /**
166
+ * Check if worker is running
167
+ */
168
+ isRunning(): boolean;
169
+ }
@@ -0,0 +1,37 @@
1
+ import 'reflect-metadata';
2
+ import { EventPriority } from '../core/types';
3
+ /**
4
+ * Decorators for event handling
5
+ */
6
+ /**
7
+ * Metadata key for event handlers
8
+ */
9
+ export declare const EVENT_HANDLER_METADATA = "EVENT_HANDLER_METADATA";
10
+ /**
11
+ * Event handler metadata
12
+ */
13
+ export interface EventHandlerMetadata {
14
+ /** Event type to handle */
15
+ eventType: string;
16
+ /** Queue to listen on (derived from priority if not specified) */
17
+ queue?: string;
18
+ /** Priority level */
19
+ priority?: EventPriority;
20
+ /** Consumer group name */
21
+ consumerGroup?: string;
22
+ }
23
+ /**
24
+ * Decorator to mark a method as an event handler
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * @Injectable()
29
+ * export class TradeSubscriber extends BaseSubscriber {
30
+ * @OnEvent('TradeProposalCreated', { priority: 'high' })
31
+ * async handleTradeCreated(event: TradeProposalCreated) {
32
+ * // Handle the event
33
+ * }
34
+ * }
35
+ * ```
36
+ */
37
+ export declare function OnEvent(eventType: string, options?: Omit<EventHandlerMetadata, 'eventType'>): MethodDecorator;
@@ -0,0 +1,117 @@
1
+ import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
2
+ import { ErrorClassification } from '../core/error-classification';
3
+ import { BaseEvent } from '../core/types';
4
+ import { EventBusModuleConfig } from './event-bus.module';
5
+ /**
6
+ * DLQ Service - Dead Letter Queue management
7
+ *
8
+ * Provides:
9
+ * - Send failed events to DLQ
10
+ * - Query and inspect DLQ entries
11
+ * - Replay events from DLQ
12
+ * - Purge old entries
13
+ */
14
+ /**
15
+ * Entry in the Dead Letter Queue
16
+ */
17
+ export interface DlqEntry<TEvent extends BaseEvent = BaseEvent> {
18
+ /** The failed event */
19
+ event: TEvent;
20
+ /** Error information */
21
+ error: {
22
+ message: string;
23
+ stack?: string;
24
+ classification: ErrorClassification;
25
+ reason: string;
26
+ };
27
+ /** Subscriber that failed */
28
+ subscriber: string;
29
+ /** Number of attempts before giving up */
30
+ attempts: number;
31
+ /** When the event was sent to DLQ */
32
+ failedAt: string;
33
+ /** Original queue the event was in */
34
+ originalQueue?: string;
35
+ /** Additional context */
36
+ context?: Record<string, unknown>;
37
+ }
38
+ /**
39
+ * Options for querying DLQ
40
+ */
41
+ export interface DlqQueryOptions {
42
+ /** Filter by event type */
43
+ eventType?: string;
44
+ /** Filter by subscriber */
45
+ subscriber?: string;
46
+ /** Filter by error classification */
47
+ classification?: ErrorClassification;
48
+ /** Filter by date range */
49
+ from?: Date;
50
+ to?: Date;
51
+ /** Pagination */
52
+ start?: number;
53
+ end?: number;
54
+ }
55
+ /**
56
+ * DLQ statistics
57
+ */
58
+ export interface DlqStats {
59
+ total: number;
60
+ byEventType: Record<string, number>;
61
+ bySubscriber: Record<string, number>;
62
+ byClassification: Record<ErrorClassification, number>;
63
+ oldestEntry?: Date;
64
+ newestEntry?: Date;
65
+ }
66
+ export declare class DlqService implements OnModuleInit, OnModuleDestroy {
67
+ private readonly config;
68
+ private readonly logger;
69
+ private queue?;
70
+ private queueName;
71
+ constructor(config: EventBusModuleConfig);
72
+ onModuleInit(): Promise<void>;
73
+ onModuleDestroy(): Promise<void>;
74
+ /**
75
+ * Send an event to the DLQ
76
+ */
77
+ send(entry: DlqEntry): Promise<string>;
78
+ /**
79
+ * Get entries from DLQ
80
+ */
81
+ getEntries(options?: DlqQueryOptions): Promise<DlqEntry[]>;
82
+ /**
83
+ * Get a specific entry by event ID
84
+ */
85
+ getEntry(eventId: string, subscriber?: string): Promise<DlqEntry | null>;
86
+ /**
87
+ * Get DLQ statistics
88
+ */
89
+ getStats(): Promise<DlqStats>;
90
+ /**
91
+ * Replay an event from DLQ
92
+ *
93
+ * This removes the event from DLQ and republishes to original queue
94
+ */
95
+ replay(eventId: string, subscriber: string, targetQueue: string): Promise<boolean>;
96
+ /**
97
+ * Replay all events matching criteria
98
+ */
99
+ replayBatch(options: DlqQueryOptions & {
100
+ targetQueue: string;
101
+ }): Promise<{
102
+ replayed: number;
103
+ failed: number;
104
+ }>;
105
+ /**
106
+ * Remove an entry from DLQ
107
+ */
108
+ remove(eventId: string, subscriber: string): Promise<boolean>;
109
+ /**
110
+ * Purge old entries from DLQ
111
+ */
112
+ purge(olderThan: Date): Promise<number>;
113
+ /**
114
+ * Clear all entries from DLQ
115
+ */
116
+ clear(): Promise<number>;
117
+ }
@@ -0,0 +1,117 @@
1
+ import { DynamicModule, InjectionToken, OptionalFactoryDependency, Type } from '@nestjs/common';
2
+ import { ErrorClassifierConfig, EventRegistryConfig, IdempotencyStore } from '..';
3
+ /**
4
+ * EventBus Module - NestJS module for event-driven architecture
5
+ *
6
+ * Provides:
7
+ * - BullMQ queue integration
8
+ * - Event publishing with priority routing
9
+ * - Idempotency and retry handling
10
+ * - DLQ management
11
+ */
12
+ /**
13
+ * Redis connection configuration
14
+ */
15
+ export interface RedisConfig {
16
+ host: string;
17
+ port: number;
18
+ password?: string;
19
+ db?: number;
20
+ tls?: boolean;
21
+ maxRetriesPerRequest?: number;
22
+ }
23
+ /**
24
+ * Queue configuration
25
+ */
26
+ export interface QueueConfig {
27
+ /** Queue name */
28
+ name: string;
29
+ /** Priority levels routed to this queue */
30
+ priorities: string[];
31
+ /** Concurrency for this queue */
32
+ concurrency?: number;
33
+ /** Rate limit per interval */
34
+ rateLimit?: {
35
+ max: number;
36
+ duration: number;
37
+ };
38
+ }
39
+ /**
40
+ * EventBus module configuration
41
+ */
42
+ export interface EventBusModuleConfig {
43
+ /** Redis connection config */
44
+ redis: RedisConfig;
45
+ /** Queue configuration (defaults to priority-based queues) */
46
+ queues?: QueueConfig[];
47
+ /** Event registry configuration */
48
+ registry?: EventRegistryConfig;
49
+ /** Custom idempotency store (defaults to in-memory) */
50
+ idempotencyStore?: IdempotencyStore;
51
+ /** Error classifier configuration */
52
+ errorClassifier?: ErrorClassifierConfig;
53
+ /** Enable DLQ (default: true) */
54
+ enableDlq?: boolean;
55
+ /** DLQ queue name (default: 'dead-letter') */
56
+ dlqQueueName?: string;
57
+ /** Global concurrency limit */
58
+ globalConcurrency?: number;
59
+ /** Enable metrics (default: true) */
60
+ enableMetrics?: boolean;
61
+ /** Metrics prefix */
62
+ metricsPrefix?: string;
63
+ }
64
+ /**
65
+ * Async configuration options
66
+ */
67
+ export interface EventBusModuleAsyncConfig {
68
+ imports?: Type<unknown>[];
69
+ useFactory: (...args: unknown[]) => Promise<EventBusModuleConfig> | EventBusModuleConfig;
70
+ inject?: (InjectionToken | OptionalFactoryDependency)[];
71
+ }
72
+ export declare class EventBusModule {
73
+ /**
74
+ * Register the EventBus module with configuration
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * @Module({
79
+ * imports: [
80
+ * EventBusModule.forRoot({
81
+ * redis: { host: 'localhost', port: 6379 },
82
+ * queues: [
83
+ * { name: 'critical', priorities: ['critical'], concurrency: 10 },
84
+ * { name: 'normal', priorities: ['high', 'normal'], concurrency: 5 },
85
+ * ],
86
+ * }),
87
+ * ],
88
+ * })
89
+ * export class AppModule {}
90
+ * ```
91
+ */
92
+ static forRoot(config: EventBusModuleConfig): DynamicModule;
93
+ /**
94
+ * Register the EventBus module with async configuration
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * @Module({
99
+ * imports: [
100
+ * EventBusModule.forRootAsync({
101
+ * imports: [ConfigModule],
102
+ * useFactory: (configService: ConfigService) => ({
103
+ * redis: {
104
+ * host: configService.get('REDIS_HOST'),
105
+ * port: configService.get('REDIS_PORT'),
106
+ * },
107
+ * }),
108
+ * inject: [ConfigService],
109
+ * }),
110
+ * ],
111
+ * })
112
+ * export class AppModule {}
113
+ * ```
114
+ */
115
+ static forRootAsync(asyncConfig: EventBusModuleAsyncConfig): DynamicModule;
116
+ private static createProviders;
117
+ }
@@ -0,0 +1,114 @@
1
+ import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
2
+ import { Queue } from 'bullmq';
3
+ import { EventRegistry } from '../core/registry';
4
+ import { BaseEvent, EventPriority } from '../core/types';
5
+ import { EventBusModuleConfig } from './event-bus.module';
6
+ /**
7
+ * EventBus Service - Publish events to BullMQ queues
8
+ *
9
+ * Provides:
10
+ * - Event publishing with validation
11
+ * - Priority-based routing
12
+ * - Correlation ID propagation
13
+ * - Metrics collection
14
+ */
15
+ /**
16
+ * Options for publishing an event
17
+ */
18
+ export interface PublishOptions {
19
+ /** Override event ID */
20
+ id?: string;
21
+ /** Correlation ID for request tracing */
22
+ correlationId?: string;
23
+ /** Causation ID (parent event) */
24
+ causationId?: string;
25
+ /** Delay before processing (ms) */
26
+ delay?: number;
27
+ /** Override priority */
28
+ priority?: EventPriority;
29
+ /** Specific queue to publish to */
30
+ queue?: string;
31
+ /** Job ID for deduplication */
32
+ jobId?: string;
33
+ /** Custom job options */
34
+ jobOptions?: Record<string, unknown>;
35
+ }
36
+ /**
37
+ * Result of publishing an event
38
+ */
39
+ export interface PublishResult {
40
+ /** Event ID */
41
+ eventId: string;
42
+ /** BullMQ Job ID */
43
+ jobId: string;
44
+ /** Queue the event was published to */
45
+ queue: string;
46
+ /** Correlation ID */
47
+ correlationId: string;
48
+ }
49
+ export declare class EventBusService implements OnModuleInit, OnModuleDestroy {
50
+ private readonly config;
51
+ private readonly registry;
52
+ private readonly logger;
53
+ private queues;
54
+ private priorityToQueue;
55
+ private connection;
56
+ private isReady;
57
+ constructor(config: EventBusModuleConfig, registry: EventRegistry);
58
+ onModuleInit(): Promise<void>;
59
+ onModuleDestroy(): Promise<void>;
60
+ /**
61
+ * Publish an event
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * await eventBus.publish({
66
+ * type: 'TradeProposalCreated',
67
+ * data: {
68
+ * tradeId: '123',
69
+ * initiatorId: 'user-1',
70
+ * recipientId: 'user-2',
71
+ * },
72
+ * });
73
+ * ```
74
+ */
75
+ publish<T extends BaseEvent>(event: Omit<T, 'id' | 'timestamp'> & Partial<Pick<T, 'id' | 'timestamp'>>, options?: PublishOptions): Promise<PublishResult>;
76
+ /**
77
+ * Publish multiple events in a batch
78
+ */
79
+ publishBatch<T extends BaseEvent>(events: Array<Omit<T, 'id' | 'timestamp'> & Partial<Pick<T, 'id' | 'timestamp'>>>, options?: Omit<PublishOptions, 'id' | 'jobId'>): Promise<PublishResult[]>;
80
+ /**
81
+ * Get queue for a given priority
82
+ */
83
+ getQueueForPriority(priority: EventPriority): string;
84
+ /**
85
+ * Get queue stats
86
+ */
87
+ getQueueStats(queueName: string): Promise<{
88
+ waiting: number;
89
+ active: number;
90
+ completed: number;
91
+ failed: number;
92
+ delayed: number;
93
+ }>;
94
+ /**
95
+ * Get all queue names
96
+ */
97
+ getQueueNames(): string[];
98
+ /**
99
+ * Get underlying BullMQ queue for advanced operations
100
+ */
101
+ getQueue(name: string): Queue | undefined;
102
+ /**
103
+ * Check if service is ready
104
+ */
105
+ isServiceReady(): boolean;
106
+ /**
107
+ * Convert priority string to number for BullMQ (lower = higher priority)
108
+ */
109
+ private getPriorityNumber;
110
+ /**
111
+ * Setup event listeners for monitoring
112
+ */
113
+ private setupQueueEventListeners;
114
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @signaltree/events/nestjs
3
+ *
4
+ * NestJS integration for event-driven architecture.
5
+ * Provides EventBusModule, BaseSubscriber, and DLQ handling.
6
+ */
7
+ export { EventBusModule } from './event-bus.module';
8
+ export type { EventBusModuleConfig, EventBusModuleAsyncConfig, } from './event-bus.module';
9
+ export { EventBusService } from './event-bus.service';
10
+ export type { PublishOptions, PublishResult } from './event-bus.service';
11
+ export { BaseSubscriber } from './base.subscriber';
12
+ export type { SubscriberConfig, ProcessingResult, SubscriberMetrics, } from './base.subscriber';
13
+ export { DlqService } from './dlq.service';
14
+ export type { DlqEntry, DlqQueryOptions, DlqStats } from './dlq.service';
15
+ export { OnEvent, EVENT_HANDLER_METADATA } from './decorators';
16
+ export { EVENT_BUS_CONFIG, EVENT_REGISTRY, IDEMPOTENCY_STORE, ERROR_CLASSIFIER, } from './tokens';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Injection tokens for the EventBus module
3
+ */
4
+ export declare const EVENT_BUS_CONFIG: unique symbol;
5
+ export declare const EVENT_REGISTRY: unique symbol;
6
+ export declare const IDEMPOTENCY_STORE: unique symbol;
7
+ export declare const ERROR_CLASSIFIER: unique symbol;
8
+ export declare const DLQ_SERVICE: unique symbol;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @signaltree/events/nestjs
3
+ *
4
+ * Re-export barrel for NestJS integration.
5
+ * This file exists for build tooling - import from '@signaltree/events/nestjs'
6
+ */
7
+ export * from './nestjs/index';
@@ -0,0 +1,113 @@
1
+ import { BaseEvent } from '../core/types';
2
+ import { PublishedEvent } from './mock-event-bus';
3
+ /**
4
+ * Test Assertions - Assertion helpers for event testing
5
+ *
6
+ * Provides:
7
+ * - Fluent assertion API
8
+ * - Event structure validation
9
+ * - Sequence assertions
10
+ */
11
+ /**
12
+ * Assertion result
13
+ */
14
+ export interface AssertionResult {
15
+ passed: boolean;
16
+ message: string;
17
+ expected?: unknown;
18
+ actual?: unknown;
19
+ }
20
+ /**
21
+ * Event assertions class
22
+ */
23
+ export declare class EventAssertions {
24
+ private publishedEvents;
25
+ constructor(events: PublishedEvent[]);
26
+ /**
27
+ * Assert that an event was published
28
+ */
29
+ toHavePublished(eventType: string): AssertionResult;
30
+ /**
31
+ * Assert that an event was NOT published
32
+ */
33
+ toNotHavePublished(eventType: string): AssertionResult;
34
+ /**
35
+ * Assert the number of published events
36
+ */
37
+ toHavePublishedCount(count: number, eventType?: string): AssertionResult;
38
+ /**
39
+ * Assert event was published with specific data
40
+ */
41
+ toHavePublishedWith<T extends BaseEvent>(eventType: T['type'], predicate: (event: T) => boolean): AssertionResult;
42
+ /**
43
+ * Assert events were published in order
44
+ */
45
+ toHavePublishedInOrder(eventTypes: string[]): AssertionResult;
46
+ /**
47
+ * Assert event has valid structure
48
+ */
49
+ toBeValidEvent<T extends BaseEvent>(event: T): AssertionResult;
50
+ /**
51
+ * Assert all events have same correlation ID
52
+ */
53
+ toHaveSameCorrelationId(): AssertionResult;
54
+ /**
55
+ * Assert event was published to specific queue
56
+ */
57
+ toHavePublishedToQueue(eventType: string, queue: string): AssertionResult;
58
+ /**
59
+ * Get all assertions as an array
60
+ */
61
+ getAllResults(): AssertionResult[];
62
+ }
63
+ /**
64
+ * Create event assertions helper
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const eventBus = createMockEventBus();
69
+ * // ... publish events ...
70
+ *
71
+ * const assertions = createEventAssertions(eventBus.getPublishedEvents());
72
+ *
73
+ * expect(assertions.toHavePublished('TradeCreated').passed).toBe(true);
74
+ * expect(assertions.toHavePublishedCount(3).passed).toBe(true);
75
+ * expect(assertions.toHavePublishedInOrder(['TradeCreated', 'TradeAccepted']).passed).toBe(true);
76
+ * ```
77
+ */
78
+ export declare function createEventAssertions(events: PublishedEvent[]): EventAssertions;
79
+ /**
80
+ * Jest/Vitest custom matcher helpers
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * // In your test setup
85
+ * expect.extend({
86
+ * toHavePublishedEvent(received: MockEventBus, eventType: string) {
87
+ * const assertions = createEventAssertions(received.getPublishedEvents());
88
+ * const result = assertions.toHavePublished(eventType);
89
+ * return {
90
+ * pass: result.passed,
91
+ * message: () => result.message,
92
+ * };
93
+ * },
94
+ * });
95
+ *
96
+ * // In your test
97
+ * expect(eventBus).toHavePublishedEvent('TradeCreated');
98
+ * ```
99
+ */
100
+ export declare const jestMatchers: {
101
+ toHavePublishedEvent(received: {
102
+ getPublishedEvents: () => PublishedEvent[];
103
+ }, eventType: string): {
104
+ pass: boolean;
105
+ message: () => string;
106
+ };
107
+ toHavePublishedEventCount(received: {
108
+ getPublishedEvents: () => PublishedEvent[];
109
+ }, count: number, eventType?: string): {
110
+ pass: boolean;
111
+ message: () => string;
112
+ };
113
+ };