@@ -24,20 +24,27 @@ export class FeatureFlagClient {
24
24
}
25
25
26
26
public static async initialize ( options : FeatureFlagClientOptions ) : Promise < void > {
27
- const targetApp = process . env . ATLASCODE_FX3_TARGET_APP || '' ;
28
- const environment =
29
- ( process . env . ATLASCODE_FX3_ENVIRONMENT as FeatureGateEnvironment ) || FeatureGateEnvironment . Production ;
27
+ const targetApp = process . env . ATLASCODE_FX3_TARGET_APP ;
28
+ const environment = process . env . ATLASCODE_FX3_ENVIRONMENT as FeatureGateEnvironment ;
29
+ const apiKey = process . env . ATLASCODE_FX3_API_KEY ;
30
+ const timeout = process . env . ATLASCODE_FX3_TIMEOUT ;
31
+
32
+ if ( ! targetApp || ! environment || ! apiKey || ! timeout ) {
33
+ this . _featureGates = this . evaluateFeatures ( ) ;
34
+ this . _experimentValues = this . evaluateExperiments ( ) ;
35
+ return ;
36
+ }
30
37
31
38
console . log ( `FeatureGates: initializing, target: ${ targetApp } , environment: ${ environment } ` ) ;
32
39
this . analyticsClient = new AnalyticsClientMapper ( options . analyticsClient , options . identifiers ) ;
33
40
this . eventBuilder = options . eventBuilder ;
34
41
35
- return FeatureGates . initialize (
42
+ await FeatureGates . initialize (
36
43
{
37
- apiKey : process . env . ATLASCODE_FX3_API_KEY || '' ,
44
+ apiKey,
38
45
environment,
39
46
targetApp,
40
- fetchTimeoutMs : Number . parseInt ( process . env . ATLASCODE_FX3_TIMEOUT || '2000' ) ,
47
+ fetchTimeoutMs : Number . parseInt ( timeout ) ,
41
48
analyticsWebClient : Promise . resolve ( this . analyticsClient ) ,
42
49
} ,
43
50
options . identifiers ,
@@ -47,29 +54,27 @@ export class FeatureFlagClient {
47
54
this . eventBuilder . featureFlagClientInitializedEvent ( ) . then ( ( e ) => {
48
55
options . analyticsClient . sendTrackEvent ( e ) ;
49
56
} ) ;
50
- } )
51
- . then ( ( ) => {
57
+
52
58
// console log all feature gates and values
53
59
for ( const feat of Object . values ( Features ) ) {
54
60
console . log ( `FeatureGates: ${ feat } -> ${ FeatureGates . checkGate ( feat ) } ` ) ;
55
61
}
56
62
} )
57
- . then ( async ( ) => {
58
- this . _featureGates = await this . evaluateFeatures ( ) ;
59
- this . _experimentValues = await this . evaluateExperiments ( ) ;
60
- } )
61
63
. catch ( ( err ) => {
62
64
console . warn ( `FeatureGates: Failed to initialize client. ${ err } ` ) ;
63
- console . warn ( 'FeatureGates: Disabling feature flags' ) ;
64
65
this . eventBuilder
65
66
. featureFlagClientInitializationFailedEvent ( )
66
67
. then ( ( e ) => options . analyticsClient . sendTrackEvent ( e ) ) ;
68
+ } )
69
+ . finally ( ( ) => {
70
+ this . _featureGates = this . evaluateFeatures ( ) ;
71
+ this . _experimentValues = this . evaluateExperiments ( ) ;
67
72
} ) ;
68
73
}
69
74
70
- public static checkGate ( gate : string ) : boolean {
75
+ private static checkGate ( gate : Features ) : boolean {
71
76
let gateValue = false ;
72
- if ( FeatureGates === null ) {
77
+ if ( ! FeatureGates ) {
73
78
console . warn ( 'FeatureGates: FeatureGates is not initialized. Defaulting to False' ) ;
74
79
} else {
75
80
// FeatureGates.checkGate returns false if any errors
@@ -79,20 +84,18 @@ export class FeatureFlagClient {
79
84
return gateValue ;
80
85
}
81
86
82
- public static checkExperimentValue ( experiment : string ) : any {
83
- let gateValue : any ;
87
+ private static checkExperimentValue ( experiment : Experiments ) : any {
84
88
const experimentGate = ExperimentGates [ experiment ] ;
85
89
if ( ! experimentGate ) {
86
90
return undefined ;
87
91
}
88
- if ( FeatureGates === null ) {
89
- console . warn (
90
- `FeatureGates: FeatureGates is not initialized. Returning default value: ${ experimentGate . defaultValue } ` ,
91
- ) ;
92
- gateValue = experimentGate . defaultValue ;
92
+
93
+ let gateValue = experimentGate . defaultValue ;
94
+ if ( ! FeatureGates ) {
95
+ console . warn ( `FeatureGates: FeatureGates is not initialized. Returning default value: ${ gateValue } ` ) ;
93
96
} else {
94
97
gateValue = FeatureGates . getExperimentValue (
95
- experimentGate . gate ,
98
+ experiment ,
96
99
experimentGate . parameter ,
97
100
experimentGate . defaultValue ,
98
101
) ;
@@ -101,29 +104,24 @@ export class FeatureFlagClient {
101
104
return gateValue ;
102
105
}
103
106
104
- public static async evaluateFeatures ( ) {
105
- const featureFlags = await Promise . all (
106
- Object . values ( Features ) . map ( async ( feature ) => {
107
- return {
108
- // eslint-disable-next-line @typescript-eslint/await-thenable
109
- [ feature ] : await this . checkGate ( feature ) ,
110
- } ;
111
- } ) ,
112
- ) ;
113
-
114
- return featureFlags . reduce ( ( acc , val ) => ( { ...acc , ...val } ) , { } ) ;
107
+ private static evaluateFeatures ( ) : FeatureGateValues {
108
+ const featureFlags = Object . values ( Features ) . map ( async ( feature ) => {
109
+ return {
110
+ [ feature ] : this . checkGate ( feature ) ,
111
+ } ;
112
+ } ) ;
113
+
114
+ return featureFlags . reduce ( ( acc , val ) => ( { ...acc , ...val } ) , { } ) as FeatureGateValues ;
115
115
}
116
116
117
- public static async evaluateExperiments ( ) {
118
- const experimentGates = await Promise . all (
119
- Object . values ( Experiments ) . map ( async ( experiment ) => {
120
- return {
121
- [ experiment ] : await this . checkExperimentValue ( experiment ) ,
122
- } ;
123
- } ) ,
124
- ) ;
117
+ private static evaluateExperiments ( ) : ExperimentGateValues {
118
+ const experimentGates = Object . values ( Experiments ) . map ( async ( experiment ) => {
119
+ return {
120
+ [ experiment ] : this . checkExperimentValue ( experiment ) ,
121
+ } ;
122
+ } ) ;
125
123
126
- return experimentGates . reduce ( ( acc , val ) => ( { ...acc , ...val } ) , { } ) ;
124
+ return experimentGates . reduce ( ( acc , val ) => ( { ...acc , ...val } ) , { } ) as ExperimentGateValues ;
127
125
}
128
126
129
127
static dispose ( ) {
0 commit comments