11import {
22 EvaluationContext ,
33 FlagNotFoundError ,
4- InvalidContextError ,
54 JsonValue ,
65 OpenFeatureEventEmitter ,
76 ParseError ,
@@ -20,7 +19,8 @@ type SplitProviderOptions = {
2019}
2120
2221type Consumer = {
23- key : string | undefined ;
22+ targetingKey : string | undefined ;
23+ trafficType : string ;
2424 attributes : SplitIO . Attributes ;
2525} ;
2626
@@ -31,9 +31,9 @@ export class OpenFeatureSplitProvider implements Provider {
3131 metadata = {
3232 name : 'split' ,
3333 } ;
34- private initialized : Promise < void > ;
35- private client : SplitIO . IClient | SplitIO . IAsyncClient ;
3634
35+ private client : SplitIO . IClient | SplitIO . IAsyncClient ;
36+ private trafficType : string ;
3737 public readonly events = new OpenFeatureEventEmitter ( ) ;
3838
3939 private getSplitClient ( options : SplitProviderOptions | string | SplitIO . ISDK | SplitIO . IAsyncSDK ) {
@@ -53,27 +53,15 @@ export class OpenFeatureSplitProvider implements Provider {
5353 }
5454
5555 constructor ( options : SplitProviderOptions | string | SplitIO . ISDK | SplitIO . IAsyncSDK ) {
56-
56+ // Asume 'user' as default traffic type'
57+ this . trafficType = 'user' ;
5758 this . client = this . getSplitClient ( options ) ;
58-
5959 this . client . on ( this . client . Event . SDK_UPDATE , ( ) => {
60- this . events . emit ( ProviderEvents . ConfigurationChanged )
61- } ) ;
62- this . initialized = new Promise ( ( resolve ) => {
63- // eslint-disable-next-line @typescript-eslint/no-explicit-any
64- if ( ( this . client as any ) . __getStatus ( ) . isReady ) {
65- console . log ( `${ this . metadata . name } provider initialized` ) ;
66- resolve ( ) ;
67- } else {
68- this . client . on ( this . client . Event . SDK_READY , ( ) => {
69- console . log ( `${ this . metadata . name } provider initialized` ) ;
70- resolve ( ) ;
71- } ) ;
72- }
73- } ) ;
60+ this . events . emit ( ProviderEvents . ConfigurationChanged ) ;
61+ } ) ;
7462 }
7563
76- async resolveBooleanEvaluation (
64+ public async resolveBooleanEvaluation (
7765 flagKey : string ,
7866 _ : boolean ,
7967 context : EvaluationContext
@@ -95,7 +83,7 @@ export class OpenFeatureSplitProvider implements Provider {
9583 throw new ParseError ( `Invalid boolean value for ${ treatment } ` ) ;
9684 }
9785
98- async resolveStringEvaluation (
86+ public async resolveStringEvaluation (
9987 flagKey : string ,
10088 _ : string ,
10189 context : EvaluationContext
@@ -107,7 +95,7 @@ export class OpenFeatureSplitProvider implements Provider {
10795 return details ;
10896 }
10997
110- async resolveNumberEvaluation (
98+ public async resolveNumberEvaluation (
11199 flagKey : string ,
112100 _ : number ,
113101 context : EvaluationContext
@@ -119,7 +107,7 @@ export class OpenFeatureSplitProvider implements Provider {
119107 return { ...details , value : this . parseValidNumber ( details . value ) } ;
120108 }
121109
122- async resolveObjectEvaluation < U extends JsonValue > (
110+ public async resolveObjectEvaluation < U extends JsonValue > (
123111 flagKey : string ,
124112 _ : U ,
125113 context : EvaluationContext
@@ -135,7 +123,7 @@ export class OpenFeatureSplitProvider implements Provider {
135123 flagKey : string ,
136124 consumer : Consumer
137125 ) : Promise < ResolutionDetails < string > > {
138- if ( ! consumer . key ) {
126+ if ( ! consumer . targetingKey ) {
139127 throw new TargetingKeyMissingError (
140128 'The Split provider requires a targeting key.'
141129 ) ;
@@ -146,9 +134,12 @@ export class OpenFeatureSplitProvider implements Provider {
146134 ) ;
147135 }
148136
149- await this . initialized ;
137+ await new Promise ( ( resolve , reject ) => {
138+ this . readinessHandler ( resolve , reject ) ;
139+ } ) ;
140+
150141 const { treatment : value , config } : SplitIO . TreatmentWithConfig = await this . client . getTreatmentWithConfig (
151- consumer . key ,
142+ consumer . targetingKey ,
152143 flagKey ,
153144 consumer . attributes
154145 ) ;
@@ -171,23 +162,14 @@ export class OpenFeatureSplitProvider implements Provider {
171162 details : TrackingEventDetails
172163 ) : Promise < void > {
173164
174- // targetingKey is always required
175- const { targetingKey } = context ;
176- if ( targetingKey == null || targetingKey === '' )
177- throw new TargetingKeyMissingError ( 'Missing targetingKey, required to track' ) ;
178-
179165 // eventName is always required
180166 if ( trackingEventName == null || trackingEventName === '' )
181167 throw new ParseError ( 'Missing eventName, required to track' ) ;
182168
183- // trafficType is always required
184- const ttVal = context [ 'trafficType' ] ;
185- const trafficType =
186- ttVal != null && typeof ttVal === 'string' && ttVal . trim ( ) !== ''
187- ? ttVal
188- : null ;
189- if ( trafficType == null || trafficType === '' )
190- throw new InvalidContextError ( 'Missing trafficType variable, required to track' ) ;
169+ // targetingKey is always required
170+ const { targetingKey, trafficType } = this . transformContext ( context ) ;
171+ if ( targetingKey == null || targetingKey === '' )
172+ throw new TargetingKeyMissingError ( 'Missing targetingKey, required to track' ) ;
191173
192174 let value ;
193175 let properties : SplitIO . Properties = { } ;
@@ -203,15 +185,20 @@ export class OpenFeatureSplitProvider implements Provider {
203185 this . client . track ( targetingKey , trafficType , trackingEventName , value , properties ) ;
204186 }
205187
206- async onClose ?( ) : Promise < void > {
188+ public async onClose ?( ) : Promise < void > {
207189 return this . client . destroy ( ) ;
208190 }
209191
210192 //Transform the context into an object useful for the Split API, an key string with arbitrary Split 'Attributes'.
211193 private transformContext ( context : EvaluationContext ) : Consumer {
212- const { targetingKey, ...attributes } = context ;
194+ const { targetingKey, trafficType : ttVal , ...attributes } = context ;
195+ const trafficType =
196+ ttVal != null && typeof ttVal === 'string' && ttVal . trim ( ) !== ''
197+ ? ttVal
198+ : this . trafficType ;
213199 return {
214- key : targetingKey ,
200+ targetingKey,
201+ trafficType,
215202 // Stringify context objects include date.
216203 attributes : JSON . parse ( JSON . stringify ( attributes ) ) ,
217204 } ;
@@ -247,4 +234,19 @@ export class OpenFeatureSplitProvider implements Provider {
247234 throw new ParseError ( `Error parsing ${ stringValue } as JSON, ${ err } ` ) ;
248235 }
249236 }
250- }
237+
238+ private async readinessHandler ( onSdkReady : ( params ?: unknown ) => void , onSdkTimedOut : ( ) => void ) : Promise < void > {
239+
240+ const clientStatus = this . client . getStatus ( ) ;
241+ if ( clientStatus . isReady ) {
242+ onSdkReady ( ) ;
243+ } else {
244+ if ( clientStatus . hasTimedout ) {
245+ onSdkTimedOut ( ) ;
246+ } else {
247+ this . client . on ( this . client . Event . SDK_READY_TIMED_OUT , onSdkTimedOut ) ;
248+ }
249+ this . client . on ( this . client . Event . SDK_READY , onSdkReady ) ;
250+ }
251+ }
252+ }
0 commit comments