@@ -2,14 +2,20 @@ import {
22 ErrorCode ,
33 EvaluationContext , FlagValue , Hook ,
44 JsonValue ,
5- Provider , ProviderMetadata , ResolutionDetails , StandardResolutionReasons ,
6- } from '@openfeature/js-sdk' ;
5+ OpenFeatureEventEmitter ,
6+ Provider ,
7+ ProviderEvents ,
8+ ProviderMetadata ,
9+ ProviderStatus ,
10+ ResolutionDetails ,
11+ StandardResolutionReasons ,
12+ } from '@openfeature/server-sdk' ;
713import {
8- basicLogger , LDClient , LDLogger ,
14+ basicLogger , init , LDClient , LDLogger , LDOptions ,
915} from '@launchdarkly/node-server-sdk' ;
10- import { LaunchDarklyProviderOptions } from './LaunchDarklyProviderOptions' ;
1116import translateContext from './translateContext' ;
1217import translateResult from './translateResult' ;
18+ import SafeLogger from './SafeLogger' ;
1319
1420/**
1521 * Create a ResolutionDetails for an evaluation that produced a type different
@@ -31,20 +37,67 @@ function wrongTypeResult<T>(value: T): ResolutionDetails<T> {
3137export default class LaunchDarklyProvider implements Provider {
3238 private readonly logger : LDLogger ;
3339
40+ private readonly client : LDClient ;
41+
42+ private readonly clientConstructionError : any ;
43+
3444 readonly metadata : ProviderMetadata = {
3545 name : 'launchdarkly-node-provider' ,
3646 } ;
3747
48+ private innerStatus : ProviderStatus = ProviderStatus . NOT_READY ;
49+
50+ public readonly events = new OpenFeatureEventEmitter ( ) ;
51+
52+ /**
53+ * Get the status of the LaunchDarkly provider.
54+ */
55+ public get status ( ) {
56+ return this . innerStatus ;
57+ }
58+
3859 /**
3960 * Construct a {@link LaunchDarklyProvider}.
4061 * @param client The LaunchDarkly client instance to use.
4162 */
42- constructor ( private readonly client : LDClient , options : LaunchDarklyProviderOptions = { } ) {
63+ constructor ( sdkKey : string , options : LDOptions = { } ) {
4364 if ( options . logger ) {
44- this . logger = options . logger ;
65+ this . logger = new SafeLogger ( options . logger , basicLogger ( { level : 'info' } ) ) ;
4566 } else {
4667 this . logger = basicLogger ( { level : 'info' } ) ;
4768 }
69+ try {
70+ this . client = init ( sdkKey , {
71+ ...options ,
72+ wrapperName : 'open-feature/node-server' ,
73+ // The wrapper version should be kept on its own line to allow easy updates using
74+ // release-please.
75+ wrapperVersion : '0.4.0' , // x-release-please-version
76+ } ) ;
77+ this . client . on ( 'update' , ( { key } : { key : string } ) => this . events . emit ( ProviderEvents . ConfigurationChanged , { flagsChanged : [ key ] } ) ) ;
78+ } catch ( e ) {
79+ this . clientConstructionError = e ;
80+ this . logger . error ( `Encountered unrecoverable initialization error, ${ e } ` ) ;
81+ this . innerStatus = ProviderStatus . ERROR ;
82+ }
83+ }
84+
85+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
86+ async initialize ( context ?: EvaluationContext ) : Promise < void > {
87+ if ( ! this . client ) {
88+ // The client could not be constructed.
89+ if ( this . clientConstructionError ) {
90+ throw this . clientConstructionError ;
91+ }
92+ throw new Error ( 'Unknown problem encountered during initialization' ) ;
93+ }
94+ try {
95+ await this . client . waitForInitialization ( ) ;
96+ this . innerStatus = ProviderStatus . READY ;
97+ } catch ( e ) {
98+ this . innerStatus = ProviderStatus . ERROR ;
99+ throw e ;
100+ }
48101 }
49102
50103 /**
@@ -169,4 +222,22 @@ export default class LaunchDarklyProvider implements Provider {
169222 private translateContext ( context : EvaluationContext ) {
170223 return translateContext ( this . logger , context ) ;
171224 }
225+
226+ /**
227+ * Get the LDClient instance used by this provider.
228+ *
229+ * @returns The client for this provider.
230+ */
231+ public getClient ( ) : LDClient {
232+ return this . client ;
233+ }
234+
235+ /**
236+ * Called by OpenFeature when it needs to close the provider. This will flush
237+ * events from the LDClient and then close it.
238+ */
239+ async onClose ( ) : Promise < void > {
240+ await this . client . flush ( ) ;
241+ this . client . close ( ) ;
242+ }
172243}
0 commit comments