@@ -4,7 +4,7 @@ const FeatureStoreEventWrapper = require('./feature_store_event_wrapper');
44const FileDataSource = require ( './file_data_source' ) ;
55const Requestor = require ( './requestor' ) ;
66const EventEmitter = require ( 'events' ) . EventEmitter ;
7- const EventFactory = require ( './event_factory' ) ;
7+ const { EventFactory, isExperiment } = require ( './event_factory' ) ;
88const EventProcessor = require ( './event_processor' ) ;
99const PollingProcessor = require ( './polling' ) ;
1010const StreamingProcessor = require ( './streaming' ) ;
@@ -298,50 +298,71 @@ const newClient = function (sdkKey, originalConfig) {
298298 options = options || { } ;
299299 }
300300 return wrapPromiseCallback (
301- new Promise ( ( resolve , reject ) => {
301+ ( async ( ) => {
302302 if ( client . isOffline ( ) ) {
303303 config . logger . info ( 'allFlagsState() called in offline mode. Returning empty state.' ) ;
304- return resolve ( FlagsStateBuilder ( false ) . build ( ) ) ;
304+ return FlagsStateBuilder ( false ) . build ( ) ;
305305 }
306306
307307 if ( ! user ) {
308308 config . logger . info ( 'allFlagsState() called without user. Returning empty state.' ) ;
309- return resolve ( FlagsStateBuilder ( false ) . build ( ) ) ;
309+ return FlagsStateBuilder ( false ) . build ( ) ;
310+ }
311+
312+ let valid = true ;
313+
314+ if ( ! initComplete ) {
315+ const inited = await new Promise ( resolve => config . featureStore . initialized ( resolve ) ) ;
316+ if ( inited ) {
317+ config . logger . warn (
318+ 'Called allFlagsState before client initialization; using last known values from data store'
319+ ) ;
320+ } else {
321+ config . logger . warn (
322+ 'Called allFlagsState before client initialization. Data store not available; returning empty state'
323+ ) ;
324+ valid = false ;
325+ }
310326 }
311327
312- const builder = FlagsStateBuilder ( true ) ;
328+ const builder = FlagsStateBuilder ( valid , options . withReasons ) ;
313329 const clientOnly = options . clientSideOnly ;
314- const withReasons = options . withReasons ;
315330 const detailsOnlyIfTracked = options . detailsOnlyForTrackedFlags ;
316- config . featureStore . all ( dataKind . features , flags => {
317- safeAsyncEach (
318- flags ,
319- ( flag , iterateeCb ) => {
320- if ( clientOnly && ! flag . clientSide ) {
321- iterateeCb ( ) ;
322- } else {
323- // At the moment, we don't send any events here
324- evaluator . evaluate ( flag , user , eventFactoryDefault , ( err , detail ) => {
325- if ( err !== null ) {
326- maybeReportError (
327- new Error ( 'Error for feature flag "' + flag . key + '" while evaluating all flags: ' + err )
328- ) ;
329- }
330- builder . addFlag (
331- flag ,
332- detail . value ,
333- detail . variationIndex ,
334- withReasons ? detail . reason : null ,
335- detailsOnlyIfTracked
336- ) ;
331+
332+ return await new Promise ( ( resolve , reject ) =>
333+ config . featureStore . all ( dataKind . features , flags => {
334+ safeAsyncEach (
335+ flags ,
336+ ( flag , iterateeCb ) => {
337+ if ( clientOnly && ! flag . clientSide ) {
337338 iterateeCb ( ) ;
338- } ) ;
339- }
340- } ,
341- err => ( err ? reject ( err ) : resolve ( builder . build ( ) ) )
342- ) ;
343- } ) ;
344- } ) ,
339+ } else {
340+ // At the moment, we don't send any events here
341+ evaluator . evaluate ( flag , user , eventFactoryDefault , ( err , detail ) => {
342+ if ( err !== null ) {
343+ maybeReportError (
344+ new Error ( 'Error for feature flag "' + flag . key + '" while evaluating all flags: ' + err )
345+ ) ;
346+ }
347+ const requireExperimentData = isExperiment ( flag , detail . reason ) ;
348+ builder . addFlag (
349+ flag ,
350+ detail . value ,
351+ detail . variationIndex ,
352+ detail . reason ,
353+ flag . trackEvents || requireExperimentData ,
354+ requireExperimentData ,
355+ detailsOnlyIfTracked
356+ ) ;
357+ iterateeCb ( ) ;
358+ } ) ;
359+ }
360+ } ,
361+ err => ( err ? reject ( err ) : resolve ( builder . build ( ) ) )
362+ ) ;
363+ } )
364+ ) ;
365+ } ) ( ) ,
345366 callback
346367 ) ;
347368 } ;
0 commit comments