@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.
- package/angular.d.ts +1 -0
- package/angular.esm.js +547 -0
- package/factory.esm.js +178 -0
- package/idempotency.esm.js +701 -0
- package/index.d.ts +1 -0
- package/index.esm.js +167 -0
- package/nestjs.d.ts +1 -0
- package/nestjs.esm.js +944 -0
- package/package.json +110 -0
- package/src/angular/handlers.d.ts +132 -0
- package/src/angular/index.d.ts +12 -0
- package/src/angular/optimistic-updates.d.ts +117 -0
- package/src/angular/websocket.service.d.ts +158 -0
- package/src/angular.d.ts +7 -0
- package/src/core/error-classification.d.ts +100 -0
- package/src/core/factory.d.ts +114 -0
- package/src/core/idempotency.d.ts +209 -0
- package/src/core/registry.d.ts +147 -0
- package/src/core/types.d.ts +127 -0
- package/src/core/validation.d.ts +619 -0
- package/src/index.d.ts +56 -0
- package/src/nestjs/base.subscriber.d.ts +169 -0
- package/src/nestjs/decorators.d.ts +37 -0
- package/src/nestjs/dlq.service.d.ts +117 -0
- package/src/nestjs/event-bus.module.d.ts +117 -0
- package/src/nestjs/event-bus.service.d.ts +114 -0
- package/src/nestjs/index.d.ts +16 -0
- package/src/nestjs/tokens.d.ts +8 -0
- package/src/nestjs.d.ts +7 -0
- package/src/testing/assertions.d.ts +113 -0
- package/src/testing/factories.d.ts +106 -0
- package/src/testing/helpers.d.ts +104 -0
- package/src/testing/index.d.ts +13 -0
- package/src/testing/mock-event-bus.d.ts +144 -0
- package/src/testing.d.ts +7 -0
- package/testing.d.ts +1 -0
- package/testing.esm.js +743 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { BaseEvent, EventActor, EventMetadata, EventPriority, EventVersion } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Event Factory - Create events with proper structure
|
|
4
|
+
*
|
|
5
|
+
* Provides:
|
|
6
|
+
* - UUID v7 generation (time-sortable)
|
|
7
|
+
* - Correlation ID management
|
|
8
|
+
* - Event creation with defaults
|
|
9
|
+
* - Type-safe event factories
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for event factory
|
|
13
|
+
*/
|
|
14
|
+
export interface EventFactoryConfig {
|
|
15
|
+
/** Default source for events */
|
|
16
|
+
source: string;
|
|
17
|
+
/** Environment (production, staging, development) */
|
|
18
|
+
environment: string;
|
|
19
|
+
/** Default actor for system events */
|
|
20
|
+
systemActor?: EventActor;
|
|
21
|
+
/** Custom ID generator */
|
|
22
|
+
generateId?: () => string;
|
|
23
|
+
/** Custom correlation ID generator */
|
|
24
|
+
generateCorrelationId?: () => string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Event factory for creating typed events
|
|
28
|
+
*/
|
|
29
|
+
export interface EventFactory<TEvents extends BaseEvent = BaseEvent> {
|
|
30
|
+
/**
|
|
31
|
+
* Create an event with full control
|
|
32
|
+
*/
|
|
33
|
+
create<T extends TEvents>(type: T['type'], data: T['data'], options?: CreateEventOptions): T;
|
|
34
|
+
/**
|
|
35
|
+
* Create event with correlation from existing event
|
|
36
|
+
*/
|
|
37
|
+
createFromCause<T extends TEvents>(type: T['type'], data: T['data'], cause: BaseEvent, options?: Omit<CreateEventOptions, 'correlationId' | 'causationId'>): T;
|
|
38
|
+
/**
|
|
39
|
+
* Get current correlation ID (for request context)
|
|
40
|
+
*/
|
|
41
|
+
getCorrelationId(): string | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Set correlation ID for current context
|
|
44
|
+
*/
|
|
45
|
+
setCorrelationId(id: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* Clear correlation ID
|
|
48
|
+
*/
|
|
49
|
+
clearCorrelationId(): void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Options for creating an event
|
|
53
|
+
*/
|
|
54
|
+
export interface CreateEventOptions {
|
|
55
|
+
/** Override event ID */
|
|
56
|
+
id?: string;
|
|
57
|
+
/** Correlation ID (request trace) */
|
|
58
|
+
correlationId?: string;
|
|
59
|
+
/** Causation ID (parent event) */
|
|
60
|
+
causationId?: string;
|
|
61
|
+
/** Event actor */
|
|
62
|
+
actor?: EventActor;
|
|
63
|
+
/** Additional metadata */
|
|
64
|
+
metadata?: Partial<EventMetadata>;
|
|
65
|
+
/** Event priority */
|
|
66
|
+
priority?: EventPriority;
|
|
67
|
+
/** Aggregate info */
|
|
68
|
+
aggregate?: {
|
|
69
|
+
type: string;
|
|
70
|
+
id: string;
|
|
71
|
+
};
|
|
72
|
+
/** Schema version override */
|
|
73
|
+
version?: EventVersion;
|
|
74
|
+
/** Timestamp override (for testing/replay) */
|
|
75
|
+
timestamp?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Generate a UUID v7 (time-sortable)
|
|
79
|
+
*
|
|
80
|
+
* UUID v7 format: timestamp (48 bits) + version (4 bits) + random (12 bits) + variant (2 bits) + random (62 bits)
|
|
81
|
+
*/
|
|
82
|
+
export declare function generateEventId(): string;
|
|
83
|
+
/**
|
|
84
|
+
* Generate a correlation ID (also UUID v7 for traceability)
|
|
85
|
+
*/
|
|
86
|
+
export declare function generateCorrelationId(): string;
|
|
87
|
+
/**
|
|
88
|
+
* Create a single event
|
|
89
|
+
*/
|
|
90
|
+
export declare function createEvent<TType extends string, TData>(type: TType, data: TData, options: CreateEventOptions & {
|
|
91
|
+
source: string;
|
|
92
|
+
environment: string;
|
|
93
|
+
}): BaseEvent<TType, TData>;
|
|
94
|
+
/**
|
|
95
|
+
* Create an event factory with default configuration
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const factory = createEventFactory({
|
|
100
|
+
* source: 'trade-service',
|
|
101
|
+
* environment: process.env.NODE_ENV || 'development',
|
|
102
|
+
* });
|
|
103
|
+
*
|
|
104
|
+
* const event = factory.create('TradeProposalCreated', {
|
|
105
|
+
* tradeId: '123',
|
|
106
|
+
* initiatorId: 'user-1',
|
|
107
|
+
* recipientId: 'user-2',
|
|
108
|
+
* }, {
|
|
109
|
+
* actor: { id: 'user-1', type: 'user' },
|
|
110
|
+
* priority: 'high',
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare function createEventFactory<TEvents extends BaseEvent = BaseEvent>(config: EventFactoryConfig): EventFactory<TEvents>;
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { BaseEvent } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Idempotency Store - Prevent duplicate event processing
|
|
4
|
+
*
|
|
5
|
+
* Provides:
|
|
6
|
+
* - Idempotency key checking
|
|
7
|
+
* - In-memory implementation (for testing/development)
|
|
8
|
+
* - Redis implementation (production)
|
|
9
|
+
* - Distributed lock support
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Result of checking idempotency
|
|
13
|
+
*/
|
|
14
|
+
export interface IdempotencyCheckResult {
|
|
15
|
+
/** Whether this event has already been processed */
|
|
16
|
+
isDuplicate: boolean;
|
|
17
|
+
/** If duplicate, when was it originally processed */
|
|
18
|
+
processedAt?: Date;
|
|
19
|
+
/** If duplicate, what was the result */
|
|
20
|
+
result?: unknown;
|
|
21
|
+
/** Lock acquired for processing */
|
|
22
|
+
lockAcquired?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Record of a processed event
|
|
26
|
+
*/
|
|
27
|
+
export interface ProcessedEventRecord {
|
|
28
|
+
/** Event ID */
|
|
29
|
+
eventId: string;
|
|
30
|
+
/** Event type */
|
|
31
|
+
eventType: string;
|
|
32
|
+
/** When processing started */
|
|
33
|
+
startedAt: Date;
|
|
34
|
+
/** When processing completed */
|
|
35
|
+
completedAt?: Date;
|
|
36
|
+
/** Processing result (success/failure) */
|
|
37
|
+
status: 'processing' | 'completed' | 'failed';
|
|
38
|
+
/** Result data (for idempotent responses) */
|
|
39
|
+
result?: unknown;
|
|
40
|
+
/** Error if failed */
|
|
41
|
+
error?: string;
|
|
42
|
+
/** Consumer/subscriber that processed the event */
|
|
43
|
+
consumer: string;
|
|
44
|
+
/** Number of processing attempts */
|
|
45
|
+
attempts: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Idempotency store interface
|
|
49
|
+
*
|
|
50
|
+
* Implementations must be atomic and handle concurrent access
|
|
51
|
+
*/
|
|
52
|
+
export interface IdempotencyStore {
|
|
53
|
+
/**
|
|
54
|
+
* Check if event has been processed and optionally acquire a processing lock
|
|
55
|
+
*
|
|
56
|
+
* @param event - Event to check
|
|
57
|
+
* @param consumer - Consumer/subscriber identifier
|
|
58
|
+
* @param options - Check options
|
|
59
|
+
* @returns Check result with duplicate status and optional lock
|
|
60
|
+
*/
|
|
61
|
+
check(event: BaseEvent, consumer: string, options?: IdempotencyCheckOptions): Promise<IdempotencyCheckResult>;
|
|
62
|
+
/**
|
|
63
|
+
* Mark event as being processed (acquire lock)
|
|
64
|
+
*
|
|
65
|
+
* @param event - Event being processed
|
|
66
|
+
* @param consumer - Consumer/subscriber identifier
|
|
67
|
+
* @param ttlMs - Lock TTL in milliseconds
|
|
68
|
+
*/
|
|
69
|
+
markProcessing(event: BaseEvent, consumer: string, ttlMs?: number): Promise<boolean>;
|
|
70
|
+
/**
|
|
71
|
+
* Mark event as successfully processed
|
|
72
|
+
*
|
|
73
|
+
* @param event - Processed event
|
|
74
|
+
* @param consumer - Consumer/subscriber identifier
|
|
75
|
+
* @param result - Optional result data for idempotent responses
|
|
76
|
+
* @param ttlMs - How long to keep the record
|
|
77
|
+
*/
|
|
78
|
+
markCompleted(event: BaseEvent, consumer: string, result?: unknown, ttlMs?: number): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Mark event as failed
|
|
81
|
+
*
|
|
82
|
+
* @param event - Failed event
|
|
83
|
+
* @param consumer - Consumer/subscriber identifier
|
|
84
|
+
* @param error - Error information
|
|
85
|
+
*/
|
|
86
|
+
markFailed(event: BaseEvent, consumer: string, error: unknown): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Release processing lock without marking completed
|
|
89
|
+
* (Used when you want to allow retry)
|
|
90
|
+
*
|
|
91
|
+
* @param event - Event to release
|
|
92
|
+
* @param consumer - Consumer/subscriber identifier
|
|
93
|
+
*/
|
|
94
|
+
releaseLock(event: BaseEvent, consumer: string): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Get processing record for an event
|
|
97
|
+
*/
|
|
98
|
+
getRecord(eventId: string, consumer: string): Promise<ProcessedEventRecord | null>;
|
|
99
|
+
/**
|
|
100
|
+
* Clean up expired records (for stores that don't auto-expire)
|
|
101
|
+
*/
|
|
102
|
+
cleanup?(): Promise<number>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Options for idempotency check
|
|
106
|
+
*/
|
|
107
|
+
export interface IdempotencyCheckOptions {
|
|
108
|
+
/** Acquire a processing lock if not duplicate */
|
|
109
|
+
acquireLock?: boolean;
|
|
110
|
+
/** Lock TTL in milliseconds (default: 30000) */
|
|
111
|
+
lockTtlMs?: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Configuration for in-memory idempotency store
|
|
115
|
+
*/
|
|
116
|
+
export interface InMemoryIdempotencyStoreConfig {
|
|
117
|
+
/** Default TTL for records in milliseconds (default: 24 hours) */
|
|
118
|
+
defaultTtlMs?: number;
|
|
119
|
+
/** Default lock TTL in milliseconds (default: 30 seconds) */
|
|
120
|
+
defaultLockTtlMs?: number;
|
|
121
|
+
/** Maximum number of records to keep (LRU eviction) */
|
|
122
|
+
maxRecords?: number;
|
|
123
|
+
/** Cleanup interval in milliseconds (default: 60 seconds) */
|
|
124
|
+
cleanupIntervalMs?: number;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* In-memory idempotency store
|
|
128
|
+
*
|
|
129
|
+
* Best for:
|
|
130
|
+
* - Development and testing
|
|
131
|
+
* - Single-instance deployments
|
|
132
|
+
* - Short-lived processes
|
|
133
|
+
*
|
|
134
|
+
* NOT recommended for:
|
|
135
|
+
* - Production multi-instance deployments
|
|
136
|
+
* - Long-running processes with many events
|
|
137
|
+
*/
|
|
138
|
+
export declare class InMemoryIdempotencyStore implements IdempotencyStore {
|
|
139
|
+
private records;
|
|
140
|
+
private cleanupTimer?;
|
|
141
|
+
private readonly defaultTtlMs;
|
|
142
|
+
private readonly defaultLockTtlMs;
|
|
143
|
+
private readonly maxRecords;
|
|
144
|
+
constructor(config?: InMemoryIdempotencyStoreConfig);
|
|
145
|
+
private makeKey;
|
|
146
|
+
check(event: BaseEvent, consumer: string, options?: IdempotencyCheckOptions): Promise<IdempotencyCheckResult>;
|
|
147
|
+
markProcessing(event: BaseEvent, consumer: string, ttlMs?: number): Promise<boolean>;
|
|
148
|
+
markCompleted(event: BaseEvent, consumer: string, result?: unknown, ttlMs?: number): Promise<void>;
|
|
149
|
+
markFailed(event: BaseEvent, consumer: string, error: unknown): Promise<void>;
|
|
150
|
+
releaseLock(event: BaseEvent, consumer: string): Promise<void>;
|
|
151
|
+
getRecord(eventId: string, consumer: string): Promise<ProcessedEventRecord | null>;
|
|
152
|
+
cleanup(): Promise<number>;
|
|
153
|
+
/**
|
|
154
|
+
* Enforce max records limit using LRU-like eviction
|
|
155
|
+
*/
|
|
156
|
+
private enforceMaxRecords;
|
|
157
|
+
/**
|
|
158
|
+
* Stop cleanup timer (for graceful shutdown)
|
|
159
|
+
*/
|
|
160
|
+
dispose(): void;
|
|
161
|
+
/**
|
|
162
|
+
* Clear all records (for testing)
|
|
163
|
+
*/
|
|
164
|
+
clear(): void;
|
|
165
|
+
/**
|
|
166
|
+
* Get stats (for monitoring)
|
|
167
|
+
*/
|
|
168
|
+
getStats(): {
|
|
169
|
+
size: number;
|
|
170
|
+
maxRecords: number;
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Create an in-memory idempotency store
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```typescript
|
|
178
|
+
* const store = createInMemoryIdempotencyStore({
|
|
179
|
+
* defaultTtlMs: 60 * 60 * 1000, // 1 hour
|
|
180
|
+
* maxRecords: 50000,
|
|
181
|
+
* });
|
|
182
|
+
*
|
|
183
|
+
* // In your subscriber
|
|
184
|
+
* const result = await store.check(event, 'my-subscriber');
|
|
185
|
+
* if (result.isDuplicate) {
|
|
186
|
+
* return result.result; // Return cached result
|
|
187
|
+
* }
|
|
188
|
+
*
|
|
189
|
+
* try {
|
|
190
|
+
* const processResult = await processEvent(event);
|
|
191
|
+
* await store.markCompleted(event, 'my-subscriber', processResult);
|
|
192
|
+
* return processResult;
|
|
193
|
+
* } catch (error) {
|
|
194
|
+
* await store.markFailed(event, 'my-subscriber', error);
|
|
195
|
+
* throw error;
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
export declare function createInMemoryIdempotencyStore(config?: InMemoryIdempotencyStoreConfig): InMemoryIdempotencyStore;
|
|
200
|
+
/**
|
|
201
|
+
* Generate an idempotency key from event
|
|
202
|
+
* Useful for custom implementations
|
|
203
|
+
*/
|
|
204
|
+
export declare function generateIdempotencyKey(event: BaseEvent, consumer: string): string;
|
|
205
|
+
/**
|
|
206
|
+
* Generate an idempotency key from correlation ID
|
|
207
|
+
* Useful for request-level idempotency
|
|
208
|
+
*/
|
|
209
|
+
export declare function generateCorrelationKey(correlationId: string, operation: string): string;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { ZodTypeAny } from 'zod';
|
|
2
|
+
import { BaseEvent, EventPriority } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Event Registry - Central catalog of all registered event types
|
|
5
|
+
*
|
|
6
|
+
* Provides:
|
|
7
|
+
* - Type-safe event registration
|
|
8
|
+
* - Schema lookup by event type
|
|
9
|
+
* - Validation helpers
|
|
10
|
+
* - Event catalog for documentation
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for a registered event
|
|
14
|
+
*/
|
|
15
|
+
export interface RegisteredEvent<T extends ZodTypeAny = ZodTypeAny> {
|
|
16
|
+
/** Event type string */
|
|
17
|
+
type: string;
|
|
18
|
+
/** Zod schema for validation */
|
|
19
|
+
schema: T;
|
|
20
|
+
/** Default priority for this event type */
|
|
21
|
+
priority: EventPriority;
|
|
22
|
+
/** Human-readable description */
|
|
23
|
+
description?: string;
|
|
24
|
+
/** Event category for grouping */
|
|
25
|
+
category?: string;
|
|
26
|
+
/** Whether this event is deprecated */
|
|
27
|
+
deprecated?: boolean;
|
|
28
|
+
/** Deprecation message if deprecated */
|
|
29
|
+
deprecationMessage?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Event registry configuration
|
|
33
|
+
*/
|
|
34
|
+
export interface EventRegistryConfig {
|
|
35
|
+
/** Strict mode - throw on unknown events */
|
|
36
|
+
strict?: boolean;
|
|
37
|
+
/** Log warnings for deprecated events */
|
|
38
|
+
warnOnDeprecated?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Event catalog entry for documentation
|
|
42
|
+
*/
|
|
43
|
+
export interface EventCatalogEntry {
|
|
44
|
+
type: string;
|
|
45
|
+
category?: string;
|
|
46
|
+
priority: EventPriority;
|
|
47
|
+
description?: string;
|
|
48
|
+
deprecated: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Full event catalog
|
|
52
|
+
*/
|
|
53
|
+
export type EventCatalog = EventCatalogEntry[];
|
|
54
|
+
/**
|
|
55
|
+
* Event Registry class - manages all registered event types
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const registry = createEventRegistry();
|
|
60
|
+
*
|
|
61
|
+
* // Register events
|
|
62
|
+
* registry.register({
|
|
63
|
+
* type: 'TradeProposalCreated',
|
|
64
|
+
* schema: TradeProposalCreatedSchema,
|
|
65
|
+
* priority: 'high',
|
|
66
|
+
* description: 'Emitted when a user proposes a trade',
|
|
67
|
+
* category: 'trade',
|
|
68
|
+
* });
|
|
69
|
+
*
|
|
70
|
+
* // Validate events
|
|
71
|
+
* const validated = registry.validate(rawEvent);
|
|
72
|
+
*
|
|
73
|
+
* // Get schema for event type
|
|
74
|
+
* const schema = registry.getSchema('TradeProposalCreated');
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare class EventRegistry {
|
|
78
|
+
private readonly events;
|
|
79
|
+
private readonly config;
|
|
80
|
+
constructor(config?: EventRegistryConfig);
|
|
81
|
+
/**
|
|
82
|
+
* Register an event type with its schema
|
|
83
|
+
*/
|
|
84
|
+
register<T extends ZodTypeAny>(event: RegisteredEvent<T>): this;
|
|
85
|
+
/**
|
|
86
|
+
* Register multiple events at once
|
|
87
|
+
*/
|
|
88
|
+
registerMany(events: RegisteredEvent[]): this;
|
|
89
|
+
/**
|
|
90
|
+
* Get schema for an event type
|
|
91
|
+
*/
|
|
92
|
+
getSchema(type: string): ZodTypeAny | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Get registered event info
|
|
95
|
+
*/
|
|
96
|
+
getEvent(type: string): RegisteredEvent | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Check if event type is registered
|
|
99
|
+
*/
|
|
100
|
+
has(type: string): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Get default priority for event type
|
|
103
|
+
*/
|
|
104
|
+
getPriority(type: string): EventPriority;
|
|
105
|
+
/**
|
|
106
|
+
* Validate an event against its registered schema
|
|
107
|
+
*
|
|
108
|
+
* @throws Error if event type is unknown (in strict mode) or validation fails
|
|
109
|
+
*/
|
|
110
|
+
validate<T extends BaseEvent = BaseEvent>(event: unknown): T;
|
|
111
|
+
/**
|
|
112
|
+
* Check if event is valid without throwing
|
|
113
|
+
*/
|
|
114
|
+
isValid(event: unknown): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Get all registered event types
|
|
117
|
+
*/
|
|
118
|
+
getAllTypes(): string[];
|
|
119
|
+
/**
|
|
120
|
+
* Get all registered events
|
|
121
|
+
*/
|
|
122
|
+
getAll(): RegisteredEvent[];
|
|
123
|
+
/**
|
|
124
|
+
* Get events by category
|
|
125
|
+
*/
|
|
126
|
+
getByCategory(category: string): RegisteredEvent[];
|
|
127
|
+
/**
|
|
128
|
+
* Get event catalog for documentation
|
|
129
|
+
*/
|
|
130
|
+
getCatalog(): EventCatalog;
|
|
131
|
+
/**
|
|
132
|
+
* Export registry as JSON schema (for external tools)
|
|
133
|
+
*/
|
|
134
|
+
toJSONSchema(): Record<string, unknown>;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Create a new event registry
|
|
138
|
+
*/
|
|
139
|
+
export declare function createEventRegistry(config?: EventRegistryConfig): EventRegistry;
|
|
140
|
+
/**
|
|
141
|
+
* Get schema for an event type from a registry
|
|
142
|
+
*/
|
|
143
|
+
export declare function getEventSchema(registry: EventRegistry, type: string): ZodTypeAny | undefined;
|
|
144
|
+
/**
|
|
145
|
+
* Get all registered event types from a registry
|
|
146
|
+
*/
|
|
147
|
+
export declare function getAllEventTypes(registry: EventRegistry): string[];
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core event types - framework-agnostic definitions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Event priority levels for queue routing and SLA management
|
|
6
|
+
*/
|
|
7
|
+
export type EventPriority = 'critical' | 'high' | 'normal' | 'low' | 'bulk';
|
|
8
|
+
/**
|
|
9
|
+
* Priority configuration with SLA targets
|
|
10
|
+
*/
|
|
11
|
+
export declare const EVENT_PRIORITIES: Record<EventPriority, {
|
|
12
|
+
sla: number;
|
|
13
|
+
weight: number;
|
|
14
|
+
}>;
|
|
15
|
+
/**
|
|
16
|
+
* Event schema version for evolution tracking
|
|
17
|
+
*/
|
|
18
|
+
export interface EventVersion {
|
|
19
|
+
major: number;
|
|
20
|
+
minor: number;
|
|
21
|
+
}
|
|
22
|
+
export declare const DEFAULT_EVENT_VERSION: EventVersion;
|
|
23
|
+
/**
|
|
24
|
+
* Actor who triggered the event
|
|
25
|
+
*/
|
|
26
|
+
export interface EventActor {
|
|
27
|
+
/** User, system, or admin ID */
|
|
28
|
+
id: string;
|
|
29
|
+
/** Type of actor */
|
|
30
|
+
type: 'user' | 'system' | 'admin' | 'webhook';
|
|
31
|
+
/** Optional display name for audit */
|
|
32
|
+
name?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Event metadata for tracing, audit, and debugging
|
|
36
|
+
*/
|
|
37
|
+
export interface EventMetadata {
|
|
38
|
+
/** Service/module that emitted the event */
|
|
39
|
+
source: string;
|
|
40
|
+
/** Environment (production, staging, development) */
|
|
41
|
+
environment: string;
|
|
42
|
+
/** Client IP address (for audit) */
|
|
43
|
+
ip?: string;
|
|
44
|
+
/** User agent string (for analytics) */
|
|
45
|
+
userAgent?: string;
|
|
46
|
+
/** Additional context */
|
|
47
|
+
[key: string]: unknown;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Base event interface - all events must extend this
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* interface TradeProposalCreated extends BaseEvent {
|
|
55
|
+
* type: 'TradeProposalCreated';
|
|
56
|
+
* data: {
|
|
57
|
+
* tradeId: string;
|
|
58
|
+
* initiatorId: string;
|
|
59
|
+
* recipientId: string;
|
|
60
|
+
* };
|
|
61
|
+
* }
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export interface BaseEvent<TType extends string = string, TData = unknown> {
|
|
65
|
+
/**
|
|
66
|
+
* Unique event ID (UUID v7 recommended - time-sortable)
|
|
67
|
+
*/
|
|
68
|
+
id: string;
|
|
69
|
+
/**
|
|
70
|
+
* Event type in PascalCase (e.g., 'TradeProposalCreated')
|
|
71
|
+
* Must be past tense - events are facts that happened
|
|
72
|
+
*/
|
|
73
|
+
type: TType;
|
|
74
|
+
/**
|
|
75
|
+
* Schema version for event evolution
|
|
76
|
+
*/
|
|
77
|
+
version: EventVersion;
|
|
78
|
+
/**
|
|
79
|
+
* When the event occurred (ISO 8601)
|
|
80
|
+
*/
|
|
81
|
+
timestamp: string;
|
|
82
|
+
/**
|
|
83
|
+
* Request/trace ID for distributed tracing
|
|
84
|
+
* All events from the same user action share this ID
|
|
85
|
+
*/
|
|
86
|
+
correlationId: string;
|
|
87
|
+
/**
|
|
88
|
+
* ID of the event that caused this event (for event chains)
|
|
89
|
+
*/
|
|
90
|
+
causationId?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Who/what triggered this event
|
|
93
|
+
*/
|
|
94
|
+
actor: EventActor;
|
|
95
|
+
/**
|
|
96
|
+
* Event metadata for tracing and audit
|
|
97
|
+
*/
|
|
98
|
+
metadata: EventMetadata;
|
|
99
|
+
/**
|
|
100
|
+
* Event-specific payload
|
|
101
|
+
*/
|
|
102
|
+
data: TData;
|
|
103
|
+
/**
|
|
104
|
+
* Priority for queue routing
|
|
105
|
+
* @default 'normal'
|
|
106
|
+
*/
|
|
107
|
+
priority?: EventPriority;
|
|
108
|
+
/**
|
|
109
|
+
* Aggregate information for event sourcing
|
|
110
|
+
*/
|
|
111
|
+
aggregate?: {
|
|
112
|
+
type: string;
|
|
113
|
+
id: string;
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Type helper to extract event data type
|
|
118
|
+
*/
|
|
119
|
+
export type EventData<T extends BaseEvent> = T['data'];
|
|
120
|
+
/**
|
|
121
|
+
* Type helper to extract event type string
|
|
122
|
+
*/
|
|
123
|
+
export type EventType<T extends BaseEvent> = T['type'];
|
|
124
|
+
/**
|
|
125
|
+
* Union type of all registered events (to be extended by apps)
|
|
126
|
+
*/
|
|
127
|
+
export type AnyEvent = BaseEvent<string, unknown>;
|