1
1
import {
2
2
EvaluationContext ,
3
+ GenericEventEmitter ,
3
4
ManageContext ,
4
5
OpenFeatureCommonAPI ,
5
6
objectOrUndefined ,
6
7
stringOrUndefined ,
7
8
} from '@openfeature/core' ;
8
9
import { Client , OpenFeatureClient } from './client' ;
9
- import { NOOP_PROVIDER , Provider } from './provider' ;
10
- import { OpenFeatureEventEmitter } from './events' ;
10
+ import { OpenFeatureEventEmitter , ProviderEvents } from './events' ;
11
11
import { Hook } from './hooks' ;
12
+ import { NOOP_PROVIDER , Provider } from './provider' ;
12
13
13
14
// use a symbol as a key for the global singleton
14
15
const GLOBAL_OPENFEATURE_API_KEY = Symbol . for ( '@openfeature/web-sdk/api' ) ;
@@ -19,7 +20,7 @@ type OpenFeatureGlobal = {
19
20
const _globalThis = globalThis as OpenFeatureGlobal ;
20
21
21
22
export class OpenFeatureAPI extends OpenFeatureCommonAPI < Provider , Hook > implements ManageContext < Promise < void > > {
22
- protected _events = new OpenFeatureEventEmitter ( ) ;
23
+ protected _events : GenericEventEmitter < ProviderEvents > = new OpenFeatureEventEmitter ( ) ;
23
24
protected _defaultProvider : Provider = NOOP_PROVIDER ;
24
25
protected _createEventEmitter = ( ) => new OpenFeatureEventEmitter ( ) ;
25
26
protected _namedProviderContext : Map < string , EvaluationContext > = new Map ( ) ;
@@ -72,7 +73,7 @@ export class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider, Hook> impleme
72
73
if ( provider ) {
73
74
const oldContext = this . getContext ( clientName ) ;
74
75
this . _namedProviderContext . set ( clientName , context ) ;
75
- await this . runProviderContextChangeHandler ( provider , oldContext , context ) ;
76
+ await this . runProviderContextChangeHandler ( clientName , provider , oldContext , context ) ;
76
77
} else {
77
78
this . _namedProviderContext . set ( clientName , context ) ;
78
79
}
@@ -89,7 +90,7 @@ export class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider, Hook> impleme
89
90
90
91
const allProviders = [ this . _defaultProvider , ...providersWithoutContextOverride ] ;
91
92
await Promise . all (
92
- allProviders . map ( ( provider ) => this . runProviderContextChangeHandler ( provider , oldContext , context ) ) ,
93
+ allProviders . map ( ( provider ) => this . runProviderContextChangeHandler ( undefined , provider , oldContext , context ) ) ,
93
94
) ;
94
95
}
95
96
}
@@ -136,7 +137,7 @@ export class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider, Hook> impleme
136
137
const oldContext = this . getContext ( clientName ) ;
137
138
this . _namedProviderContext . delete ( clientName ) ;
138
139
const newContext = this . getContext ( ) ;
139
- await this . runProviderContextChangeHandler ( provider , oldContext , newContext ) ;
140
+ await this . runProviderContextChangeHandler ( clientName , provider , oldContext , newContext ) ;
140
141
} else {
141
142
this . _namedProviderContext . delete ( clientName ) ;
142
143
}
@@ -190,15 +191,24 @@ export class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider, Hook> impleme
190
191
}
191
192
192
193
private async runProviderContextChangeHandler (
194
+ clientName : string | undefined ,
193
195
provider : Provider ,
194
196
oldContext : EvaluationContext ,
195
197
newContext : EvaluationContext ,
196
198
) : Promise < void > {
197
- try {
198
- return await provider . onContextChange ?.( oldContext , newContext ) ;
199
- } catch ( err ) {
200
- this . _logger ?. error ( `Error running ${ provider . metadata . name } 's context change handler:` , err ) ;
201
- }
199
+ const providerName = provider . metadata . name ;
200
+ return provider . onContextChange ?.( oldContext , newContext ) . then ( ( ) => {
201
+ this . getAssociatedEventEmitters ( clientName ) . forEach ( ( emitter ) => {
202
+ emitter ?. emit ( ProviderEvents . ContextChanged , { clientName, providerName } ) ;
203
+ } ) ;
204
+ this . _events ?. emit ( ProviderEvents . ContextChanged , { clientName, providerName } ) ;
205
+ } ) . catch ( ( err ) => {
206
+ this . _logger ?. error ( `Error running ${ provider . metadata . name } 's context change handler:` , err ) ;
207
+ this . getAssociatedEventEmitters ( clientName ) . forEach ( ( emitter ) => {
208
+ emitter ?. emit ( ProviderEvents . Error , { clientName, providerName, message : err ?. message , } ) ;
209
+ } ) ;
210
+ this . _events ?. emit ( ProviderEvents . Error , { clientName, providerName, message : err ?. message , } ) ;
211
+ } ) ;
202
212
}
203
213
}
204
214
0 commit comments