@@ -14,6 +14,7 @@ import { AssignmentCache } from '../cache/abstract-assignment-cache';
1414import { LRUInMemoryAssignmentCache } from '../cache/lru-in-memory-assignment-cache' ;
1515import { NonExpiringInMemoryAssignmentCache } from '../cache/non-expiring-in-memory-cache-assignment' ;
1616import { TLRUInMemoryAssignmentCache } from '../cache/tlru-in-memory-assignment-cache' ;
17+ import { Configuration } from '../configuration' ;
1718import ConfigurationRequestor from '../configuration-requestor' ;
1819import { ConfigurationStore } from '../configuration-store' ;
1920import { IConfigurationStore , ISyncStore } from '../configuration-store/configuration-store' ;
@@ -30,7 +31,6 @@ import {
3031 DEFAULT_POLL_INTERVAL_MS ,
3132 DEFAULT_REQUEST_TIMEOUT_MS ,
3233} from '../constants' ;
33- import { decodeFlag } from '../decoding' ;
3434import { EppoValue } from '../eppo_value' ;
3535import { Evaluator , FlagEvaluation , noneResult , overrideResult } from '../evaluator' ;
3636import { BoundedEventQueue } from '../events/bounded-event-queue' ;
@@ -42,19 +42,18 @@ import {
4242} from '../flag-evaluation-details-builder' ;
4343import { FlagEvaluationError } from '../flag-evaluation-error' ;
4444import FetchHttpClient from '../http-client' ;
45- import { Configuration , IConfiguration } from '../i-configuration' ;
4645import {
4746 BanditModelData ,
4847 BanditParameters ,
4948 BanditVariation ,
5049 Flag ,
50+ FormatEnum ,
5151 IPrecomputedBandit ,
5252 ObfuscatedFlag ,
5353 PrecomputedFlag ,
5454 Variation ,
5555 VariationType ,
5656} from '../interfaces' ;
57- import { getMD5Hash } from '../obfuscation' ;
5857import { OverridePayload , OverrideValidator } from '../override-validator' ;
5958import initPoller , { IPoller } from '../poller' ;
6059import {
@@ -106,6 +105,7 @@ export type EppoClientParameters = {
106105 banditModelConfigurationStore ?: IConfigurationStore < BanditParameters > ;
107106 overrideStore ?: ISyncStore < Variation > ;
108107 configurationRequestParameters ?: FlagConfigurationRequestParameters ;
108+ initialConfiguration ?: Configuration ;
109109 /**
110110 * Setting this value will have no side effects other than triggering a warning when the actual
111111 * configuration's obfuscated does not match the value set here.
@@ -135,7 +135,7 @@ export default class EppoClient {
135135 private configurationRequestor ?: ConfigurationRequestor ;
136136 private readonly overrideValidator = new OverrideValidator ( ) ;
137137
138- private readonly configurationStore = new ConfigurationStore ( null ) ;
138+ private readonly configurationStore ;
139139 /** @deprecated use configurationStore instead. */
140140 private flagConfigurationStore : IConfigurationStore < Flag | ObfuscatedFlag > ;
141141 /** @deprecated use configurationStore instead. */
@@ -151,7 +151,10 @@ export default class EppoClient {
151151 banditModelConfigurationStore,
152152 overrideStore,
153153 configurationRequestParameters,
154+ initialConfiguration,
154155 } : EppoClientParameters ) {
156+ this . configurationStore = new ConfigurationStore ( initialConfiguration ) ;
157+
155158 this . eventDispatcher = eventDispatcher ;
156159 this . flagConfigurationStore = flagConfigurationStore ;
157160 this . banditVariationConfigurationStore = banditVariationConfigurationStore ;
@@ -167,10 +170,14 @@ export default class EppoClient {
167170 }
168171 }
169172
170- private getConfiguration ( ) : Configuration | null {
173+ public getConfiguration ( ) : Configuration {
171174 return this . configurationStore . getConfiguration ( ) ;
172175 }
173176
177+ public setConfiguration ( configuration : Configuration ) {
178+ this . configurationStore . setConfiguration ( configuration ) ;
179+ }
180+
174181 /**
175182 * Validates and parses x-eppo-overrides header sent by Eppo's Chrome extension
176183 */
@@ -606,16 +613,13 @@ export default class EppoClient {
606613 defaultAction : string ,
607614 ) : string {
608615 const config = this . getConfiguration ( ) ;
609- if ( ! config ) {
610- return defaultAction ;
611- }
612616 let result : string | null = null ;
613617
614618 const flagBanditVariations = config . getFlagBanditVariations ( flagKey ) ;
615- const banditKey = flagBanditVariations ? .at ( 0 ) ?. key ;
619+ const banditKey = flagBanditVariations . at ( 0 ) ?. key ;
616620
617621 if ( banditKey ) {
618- const banditParameters = config . getBandit ( banditKey ) ;
622+ const banditParameters = config . getBanditConfiguration ( ) ?. response . bandits [ banditKey ] ;
619623 if ( banditParameters ) {
620624 const contextualSubjectAttributes = ensureContextualSubjectAttributes ( subjectAttributes ) ;
621625 const actionsWithContextualAttributes = ensureActionsWithContextualAttributes ( actions ) ;
@@ -673,7 +677,6 @@ export default class EppoClient {
673677 // Note: the reason for non-bandit assignments include the subject being bucketed into a non-bandit variation or
674678 // a rollout having been done.
675679 const bandit = config . getFlagVariationBandit ( flagKey , variation ) ;
676-
677680 if ( ! bandit ) {
678681 return { variation, action : null , evaluationDetails } ;
679682 }
@@ -901,29 +904,19 @@ export default class EppoClient {
901904 subjectAttributes : Attributes = { } ,
902905 ) : Record < FlagKey , PrecomputedFlag > {
903906 const config = this . getConfiguration ( ) ;
904- if ( ! config ) {
905- return { } ;
906- }
907- const configDetails = config . getFlagConfigDetails ( ) ;
908907 const flagKeys = config . getFlagKeys ( ) ;
909908 const flags : Record < FlagKey , PrecomputedFlag > = { } ;
910909
911910 // Evaluate all the enabled flags for the user
912911 flagKeys . forEach ( ( flagKey ) => {
913- const flag = this . getNormalizedFlag ( config , flagKey ) ;
912+ const flag = config . getFlag ( flagKey ) ;
914913 if ( ! flag ) {
915914 logger . debug ( `${ loggerPrefix } No assigned variation. Flag does not exist.` ) ;
916915 return ;
917916 }
918917
919918 // Evaluate the flag for this subject.
920- const evaluation = this . evaluator . evaluateFlag (
921- flag ,
922- configDetails ,
923- subjectKey ,
924- subjectAttributes ,
925- config . isObfuscated ( ) ,
926- ) ;
919+ const evaluation = this . evaluator . evaluateFlag ( config , flag , subjectKey , subjectAttributes ) ;
927920
928921 // allocationKey is set along with variation when there is a result. this check appeases typescript below
929922 if ( ! evaluation . variation || ! evaluation . allocationKey ) {
@@ -960,24 +953,10 @@ export default class EppoClient {
960953 banditActions : Record < FlagKey , BanditActions > = { } ,
961954 salt ?: string ,
962955 ) : string {
963- const subjectContextualAttributes = ensureContextualSubjectAttributes ( subjectAttributes ) ;
964- const subjectFlatAttributes = ensureNonContextualSubjectAttributes ( subjectAttributes ) ;
965-
966956 const config = this . getConfiguration ( ) ;
967- if ( ! config ) {
968- const precomputedConfig = PrecomputedConfiguration . obfuscated (
969- subjectKey ,
970- { } ,
971- { } ,
972- salt ?? '' ,
973- subjectContextualAttributes ,
974- undefined ,
975- ) ;
976- return JSON . stringify ( ConfigurationWireV1 . precomputed ( precomputedConfig ) ) ;
977- }
978-
979- const configDetails = config . getFlagConfigDetails ( ) ;
980957
958+ const subjectContextualAttributes = ensureContextualSubjectAttributes ( subjectAttributes ) ;
959+ const subjectFlatAttributes = ensureNonContextualSubjectAttributes ( subjectAttributes ) ;
981960 const flags = this . getAllAssignments ( subjectKey , subjectFlatAttributes ) ;
982961
983962 const bandits = this . computeBanditsForFlags (
@@ -994,7 +973,7 @@ export default class EppoClient {
994973 bandits ,
995974 salt ?? '' , // no salt if not provided
996975 subjectContextualAttributes ,
997- configDetails . configEnvironment ,
976+ config . getFlagsConfiguration ( ) ?. response . environment ,
998977 ) ;
999978
1000979 const configWire : IConfigurationWire = ConfigurationWireV1 . precomputed ( precomputedConfig ) ;
@@ -1043,8 +1022,7 @@ export default class EppoClient {
10431022 ) ;
10441023 }
10451024
1046- const configDetails = config . getFlagConfigDetails ( ) ;
1047- const flag = this . getNormalizedFlag ( config , flagKey ) ;
1025+ const flag = config . getFlag ( flagKey ) ;
10481026
10491027 if ( flag === null ) {
10501028 logger . warn ( `${ loggerPrefix } No assigned variation. Flag not found: ${ flagKey } ` ) ;
@@ -1058,7 +1036,7 @@ export default class EppoClient {
10581036 subjectKey ,
10591037 subjectAttributes ,
10601038 flagEvaluationDetails ,
1061- configDetails . configFormat ,
1039+ config . getFlagsConfiguration ( ) ?. response . environment . name ?? '' ,
10621040 ) ;
10631041 }
10641042
@@ -1074,7 +1052,7 @@ export default class EppoClient {
10741052 subjectKey ,
10751053 subjectAttributes ,
10761054 flagEvaluationDetails ,
1077- configDetails . configFormat ,
1055+ config . getFlagsConfiguration ( ) ?. response . format ?? '' ,
10781056 ) ;
10791057 }
10801058 throw new TypeError ( errorMessage ) ;
@@ -1092,23 +1070,20 @@ export default class EppoClient {
10921070 subjectKey ,
10931071 subjectAttributes ,
10941072 flagEvaluationDetails ,
1095- configDetails . configFormat ,
1073+ config . getFlagsConfiguration ( ) ?. response . format ?? '' ,
10961074 ) ;
10971075 }
10981076
1099- const isObfuscated = config . isObfuscated ( ) ;
11001077 const result = this . evaluator . evaluateFlag (
1078+ config ,
11011079 flag ,
1102- configDetails ,
11031080 subjectKey ,
11041081 subjectAttributes ,
1105- isObfuscated ,
11061082 expectedVariationType ,
11071083 ) ;
1108- if ( isObfuscated ) {
1109- // flag.key is obfuscated, replace with requested flag key
1110- result . flagKey = flagKey ;
1111- }
1084+
1085+ // if flag.key is obfuscated, replace with requested flag key
1086+ result . flagKey = flagKey ;
11121087
11131088 try {
11141089 if ( result ?. doLog ) {
@@ -1134,36 +1109,22 @@ export default class EppoClient {
11341109 }
11351110
11361111 private newFlagEvaluationDetailsBuilder (
1137- config : IConfiguration | null ,
1112+ config : Configuration ,
11381113 flagKey : string ,
11391114 ) : FlagEvaluationDetailsBuilder {
1140- if ( ! config ) {
1141- return new FlagEvaluationDetailsBuilder ( '' , [ ] , '' , '' ) ;
1142- }
1143-
1144- const flag = this . getNormalizedFlag ( config , flagKey ) ;
1145- const configDetails = config . getFlagConfigDetails ( ) ;
1115+ const flag = config . getFlag ( flagKey ) ;
1116+ const flagsConfiguration = config . getFlagsConfiguration ( ) ;
11461117 return new FlagEvaluationDetailsBuilder (
1147- configDetails . configEnvironment . name ,
1118+ flagsConfiguration ?. response . environment . name ?? '' ,
11481119 flag ?. allocations ?? [ ] ,
1149- configDetails . configFetchedAt ,
1150- configDetails . configPublishedAt ,
1120+ flagsConfiguration ?. fetchedAt ?? '' ,
1121+ flagsConfiguration ?. response . createdAt ?? '' ,
11511122 ) ;
11521123 }
11531124
1154- private getNormalizedFlag ( config : IConfiguration , flagKey : string ) : Flag | null {
1155- return config . isObfuscated ( )
1156- ? this . getObfuscatedFlag ( config , flagKey )
1157- : config . getFlag ( flagKey ) ;
1158- }
1159-
1160- private getObfuscatedFlag ( config : IConfiguration , flagKey : string ) : Flag | null {
1161- const flag : ObfuscatedFlag | null = config . getFlag ( getMD5Hash ( flagKey ) ) as ObfuscatedFlag ;
1162- return flag ? decodeFlag ( flag ) : null ;
1163- }
1164-
11651125 isInitialized ( ) {
1166- return this . getConfiguration ( ) ?. isInitialized ( ) ?? false ;
1126+ // We treat configuration as initialized if we have flags config.
1127+ return ! ! this . configurationStore . getConfiguration ( ) ?. getFlagsConfiguration ( ) ;
11671128 }
11681129
11691130 /** @deprecated Use `setAssignmentLogger` */
@@ -1304,14 +1265,15 @@ export default class EppoClient {
13041265
13051266 private buildLoggerMetadata ( ) : Record < string , unknown > {
13061267 return {
1307- obfuscated : this . getConfiguration ( ) ?. isObfuscated ( ) ,
1268+ obfuscated :
1269+ this . getConfiguration ( ) ?. getFlagsConfiguration ( ) ?. response . format === FormatEnum . CLIENT ,
13081270 sdkLanguage : 'javascript' ,
13091271 sdkLibVersion : LIB_VERSION ,
13101272 } ;
13111273 }
13121274
13131275 private computeBanditsForFlags (
1314- config : IConfiguration ,
1276+ config : Configuration ,
13151277 subjectKey : string ,
13161278 subjectAttributes : ContextAttributes ,
13171279 banditActions : Record < FlagKey , BanditActions > ,
@@ -1341,7 +1303,7 @@ export default class EppoClient {
13411303 }
13421304
13431305 private getPrecomputedBandit (
1344- config : IConfiguration ,
1306+ config : Configuration ,
13451307 flagKey : string ,
13461308 variationValue : string ,
13471309 subjectKey : string ,
0 commit comments