@@ -18,69 +18,67 @@ import * as optimizely from '@optimizely/optimizely-sdk';
18
18
import { getLogger } from '@optimizely/js-sdk-logging' ;
19
19
20
20
import { setupAutoUpdateListeners } from './autoUpdate' ;
21
- import { VariableValuesObject , OnReadyResult } from './client'
21
+ import { VariableValuesObject , OnReadyResult } from './client' ;
22
22
import { OptimizelyContext } from './Context' ;
23
23
24
24
const useFeatureLogger = getLogger ( 'useFeature' ) ;
25
25
26
26
type UseFeatureState = {
27
- isEnabled : boolean ,
28
- variables : VariableValuesObject ,
27
+ isEnabled : boolean ;
28
+ variables : VariableValuesObject ;
29
29
} ;
30
30
31
31
type ClientReady = boolean ;
32
32
type DidTimeout = boolean ;
33
33
34
34
type UseFeatureOptions = {
35
- autoUpdate ?: boolean ,
36
- timeout ?: number
35
+ autoUpdate ?: boolean ;
36
+ timeout ?: number ;
37
37
} ;
38
38
39
39
type UseFeatureOverrides = {
40
- overrideUserId ?: string ,
41
- overrideAttributes ?: optimizely . UserAttributes ,
42
- }
40
+ overrideUserId ?: string ;
41
+ overrideAttributes ?: optimizely . UserAttributes ;
42
+ } ;
43
43
44
44
interface UseFeature {
45
- (
46
- featureKey : string ,
47
- options ?: UseFeatureOptions ,
48
- overrides ?: UseFeatureOverrides ,
49
- ) : [
50
- UseFeatureState [ "isEnabled" ] ,
51
- UseFeatureState [ "variables" ] ,
45
+ ( featureKey : string , options ?: UseFeatureOptions , overrides ?: UseFeatureOverrides ) : [
46
+ UseFeatureState [ 'isEnabled' ] ,
47
+ UseFeatureState [ 'variables' ] ,
52
48
ClientReady ,
53
49
DidTimeout
54
- ]
50
+ ] ;
55
51
}
56
52
57
53
/**
58
54
* A React Hook that retrieves the status of a feature flag and its variables, optionally
59
55
* auto updating those values based on underlying user or datafile changes.
60
- *
61
- * Note: The react client can become ready AFTER the timeout period.
56
+ *
57
+ * Note: The react client can become ready AFTER the timeout period.
62
58
* ClientReady and DidTimeout provide signals to handle this scenario.
63
59
*/
64
- export const useFeature : UseFeature = ( featureKey , options = { } , overrides = { } ) => {
60
+ export const useFeature : UseFeature = ( featureKey , options = { } , overrides = { } ) => {
65
61
const { isServerSide, optimizely, timeout } = useContext ( OptimizelyContext ) ;
66
62
if ( ! optimizely ) {
67
63
throw new Error ( 'optimizely prop must be supplied via a parent <OptimizelyProvider>' ) ;
68
64
}
69
- const finalReadyTimeout : number | undefined =
70
- options . timeout !== undefined ? options . timeout : timeout ;
65
+ const finalReadyTimeout : number | undefined = options . timeout !== undefined ? options . timeout : timeout ;
71
66
72
67
// Helper function to return the current values for isEnabled and variables.
73
- const getCurrentValues = useCallback ( ( ) => ( {
74
- isEnabled : optimizely . isFeatureEnabled ( featureKey , overrides . overrideUserId , overrides . overrideAttributes ) ,
75
- variables : optimizely . getFeatureVariables ( featureKey , overrides . overrideUserId , overrides . overrideAttributes ) ,
76
- } ) , [ featureKey , overrides ] ) ;
68
+ const getCurrentValues = useCallback (
69
+ ( ) => ( {
70
+ isEnabled : optimizely . isFeatureEnabled ( featureKey , overrides . overrideUserId , overrides . overrideAttributes ) ,
71
+ variables : optimizely . getFeatureVariables ( featureKey , overrides . overrideUserId , overrides . overrideAttributes ) ,
72
+ } ) ,
73
+ [ featureKey , overrides ]
74
+ ) ;
77
75
78
76
// Set the initial state immediately serverSide
79
- const [ data , setData ] = useState < UseFeatureState > ( ( ) => {
77
+ const [ data , setData ] = useState < UseFeatureState > ( ( ) => {
80
78
if ( isServerSide ) {
81
79
return getCurrentValues ( ) ;
82
80
}
83
- return { isEnabled : false , variables : { } } ;
81
+ return { isEnabled : false , variables : { } } ;
84
82
} ) ;
85
83
86
84
const [ clientReady , setClientReady ] = useState ( isServerSide ? true : false ) ;
@@ -89,53 +87,48 @@ export const useFeature : UseFeature = (featureKey, options = {}, overrides = {}
89
87
useEffect ( ( ) => {
90
88
const cleanupFns : Array < ( ) => void > = [ ] ;
91
89
92
- optimizely . onReady ( { timeout : finalReadyTimeout } ) . then ( ( res : OnReadyResult ) => {
93
- if ( res . success ) {
94
- // didTimeout=false
95
- useFeatureLogger . info ( `feature="${ featureKey } " successfully set for user="${ optimizely . user . id } "` ) ;
96
- return ;
97
- }
98
- setDidTimeout ( true ) ;
99
- useFeatureLogger . info (
100
- `feature="${ featureKey } " could not be set before timeout of ${ finalReadyTimeout } ms, reason="${ res . reason || '' } "` ,
101
- ) ;
102
- // Since we timed out, wait for the dataReadyPromise to resolve before setting up.
103
- return res . dataReadyPromise ! . then (
104
- ( ) => {
105
- useFeatureLogger . info (
106
- `feature="${ featureKey } " is now set, but after timeout.` ,
107
- ) ;
108
- } ) ;
109
- } )
110
- . then ( ( ) => {
111
- setClientReady ( true ) ;
112
- setData ( getCurrentValues ( ) ) ;
113
- if ( options . autoUpdate ) {
114
- cleanupFns . push (
115
- setupAutoUpdateListeners ( optimizely , 'feature' , featureKey , useFeatureLogger , ( ) => {
116
- if ( cleanupFns . length ) {
117
- setData ( getCurrentValues ( ) ) ;
118
- }
119
- } )
90
+ optimizely
91
+ . onReady ( { timeout : finalReadyTimeout } )
92
+ . then ( ( res : OnReadyResult ) => {
93
+ if ( res . success ) {
94
+ // didTimeout=false
95
+ useFeatureLogger . info ( `feature="${ featureKey } " successfully set for user="${ optimizely . user . id } "` ) ;
96
+ return ;
97
+ }
98
+ setDidTimeout ( true ) ;
99
+ useFeatureLogger . info (
100
+ `feature="${ featureKey } " could not be set before timeout of ${ finalReadyTimeout } ms, reason="${ res . reason ||
101
+ '' } "`
120
102
) ;
121
- }
122
- } )
123
- . catch ( ( ) => {
124
- /* The user promise or core client promise rejected. */
125
- useFeatureLogger . error ( `Error initializing client. The core client or user promise(s) rejected.` ) ;
126
- } )
103
+ // Since we timed out, wait for the dataReadyPromise to resolve before setting up.
104
+ return res . dataReadyPromise ! . then ( ( ) => {
105
+ useFeatureLogger . info ( `feature="${ featureKey } " is now set, but after timeout.` ) ;
106
+ } ) ;
107
+ } )
108
+ . then ( ( ) => {
109
+ setClientReady ( true ) ;
110
+ setData ( getCurrentValues ( ) ) ;
111
+ if ( options . autoUpdate ) {
112
+ cleanupFns . push (
113
+ setupAutoUpdateListeners ( optimizely , 'feature' , featureKey , useFeatureLogger , ( ) => {
114
+ if ( cleanupFns . length ) {
115
+ setData ( getCurrentValues ( ) ) ;
116
+ }
117
+ } )
118
+ ) ;
119
+ }
120
+ } )
121
+ . catch ( ( ) => {
122
+ /* The user promise or core client promise rejected. */
123
+ useFeatureLogger . error ( `Error initializing client. The core client or user promise(s) rejected.` ) ;
124
+ } ) ;
127
125
128
126
return ( ) => {
129
- while ( cleanupFns . length ) {
127
+ while ( cleanupFns . length ) {
130
128
cleanupFns . shift ( ) ! ( ) ;
131
129
}
132
130
} ;
133
131
} , [ optimizely ] ) ;
134
132
135
- return [
136
- data . isEnabled ,
137
- data . variables ,
138
- clientReady ,
139
- didTimeout ,
140
- ] ;
133
+ return [ data . isEnabled , data . variables , clientReady , didTimeout ] ;
141
134
} ;
0 commit comments