1
1
import { Logger , ManageLogger , SafeLogger } from '../logger' ;
2
2
import EventEmitter from 'events' ;
3
3
import { ProviderEvents } from './events' ;
4
- import { EventDetails , EventHandler } from './eventing' ;
4
+ import { EventContext , EventDetails , EventHandler , CommonEventDetails } from './eventing' ;
5
5
6
- export class OpenFeatureEventEmitter implements ManageLogger < OpenFeatureEventEmitter > {
7
- private readonly _handlers = new WeakMap < EventHandler , EventHandler > ( ) ;
6
+ abstract class GenericEventEmitter < AdditionalContext extends Record < string , unknown > = Record < string , unknown > >
7
+ implements ManageLogger < GenericEventEmitter < AdditionalContext > >
8
+ {
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ private readonly _handlers = new WeakMap < EventHandler < any > , EventHandler < any > > ( ) ;
8
11
private readonly eventEmitter = new EventEmitter ( { captureRejections : true } ) ;
9
12
private _eventLogger ?: Logger ;
10
13
@@ -14,24 +17,24 @@ export class OpenFeatureEventEmitter implements ManageLogger<OpenFeatureEventEmi
14
17
} ) ;
15
18
}
16
19
17
- emit ( eventType : ProviderEvents , context ?: EventDetails ) : void {
20
+ emit < T extends ProviderEvents > ( eventType : T , context ?: EventContext < T , AdditionalContext > ) : void {
18
21
this . eventEmitter . emit ( eventType , context ) ;
19
22
}
20
23
21
- addHandler ( eventType : ProviderEvents , handler : EventHandler ) : void {
24
+ addHandler < T extends ProviderEvents > ( eventType : T , handler : EventHandler < T > ) : void {
22
25
// The handlers have to be wrapped with an async function because if a synchronous functions throws an error,
23
26
// the other handlers will not run.
24
- const asyncHandler = async ( context ?: EventDetails ) => {
27
+ const asyncHandler = async ( context ?: EventDetails < T > ) => {
25
28
await handler ( context ) ;
26
29
} ;
27
30
// The async handler has to be written to the map, because we need to get the wrapper function when deleting a listener
28
31
this . _handlers . set ( handler , asyncHandler ) ;
29
32
this . eventEmitter . on ( eventType , asyncHandler ) ;
30
33
}
31
34
32
- removeHandler ( eventType : ProviderEvents , handler : EventHandler ) : void {
35
+ removeHandler < T extends ProviderEvents > ( eventType : T , handler : EventHandler < T > ) : void {
33
36
// Get the wrapper function for this handler, to delete it from the event emitter
34
- const asyncHandler = this . _handlers . get ( handler ) ;
37
+ const asyncHandler = this . _handlers . get ( handler ) as EventHandler < T > | undefined ;
35
38
36
39
if ( ! asyncHandler ) {
37
40
return ;
@@ -49,8 +52,8 @@ export class OpenFeatureEventEmitter implements ManageLogger<OpenFeatureEventEmi
49
52
}
50
53
}
51
54
52
- getHandlers ( eventType : ProviderEvents ) : EventHandler [ ] {
53
- return this . eventEmitter . listeners ( eventType ) as EventHandler [ ] ;
55
+ getHandlers < T extends ProviderEvents > ( eventType : T ) : EventHandler < T > [ ] {
56
+ return this . eventEmitter . listeners ( eventType ) as EventHandler < T > [ ] ;
54
57
}
55
58
56
59
setLogger ( logger : Logger ) : this {
@@ -59,6 +62,22 @@ export class OpenFeatureEventEmitter implements ManageLogger<OpenFeatureEventEmi
59
62
}
60
63
61
64
private get _logger ( ) {
62
- return this . _eventLogger || this . globalLogger ?.( ) ;
65
+ return this . _eventLogger ?? this . globalLogger ?.( ) ;
63
66
}
64
67
}
68
+
69
+ /**
70
+ * The OpenFeatureEventEmitter can be used by provider developers to emit
71
+ * events at various parts of the provider lifecycle.
72
+ *
73
+ * NOTE: Ready and error events are automatically emitted by the SDK based on
74
+ * the result of the initialize method.
75
+ */
76
+ export class OpenFeatureEventEmitter extends GenericEventEmitter { } ;
77
+
78
+ /**
79
+ * The InternalEventEmitter should only be used within the SDK. It extends the
80
+ * OpenFeatureEventEmitter to include additional properties that can be included
81
+ * in the event details.
82
+ */
83
+ export class InternalEventEmitter extends GenericEventEmitter < CommonEventDetails > { } ;
0 commit comments