@@ -69,12 +69,15 @@ export interface IClientConfig {
69
69
70
70
export { IAssignmentLogger , IAssignmentEvent , IEppoClient } from '@eppo/js-client-sdk-common' ;
71
71
72
+ const localStorage = new EppoLocalStorage ( ) ;
73
+
72
74
/**
73
75
* Client for assigning experiment variations.
74
76
* @public
75
77
*/
76
78
export class EppoJSClient extends EppoClient {
77
- public static instance : EppoJSClient ;
79
+ public static instance : EppoJSClient = new EppoJSClient ( localStorage ) ;
80
+ public static initialized = false ;
78
81
79
82
public getAssignment (
80
83
subjectKey : string ,
@@ -83,6 +86,7 @@ export class EppoJSClient extends EppoClient {
83
86
subjectAttributes ?: Record < string , any > ,
84
87
assignmentHooks ?: IAssignmentHooks ,
85
88
) : string | null {
89
+ EppoJSClient . getAssignmentInitializationCheck ( ) ;
86
90
return super . getAssignment ( subjectKey , flagKey , subjectAttributes , assignmentHooks , true ) ;
87
91
}
88
92
@@ -93,6 +97,7 @@ export class EppoJSClient extends EppoClient {
93
97
subjectAttributes ?: Record < string , any > ,
94
98
assignmentHooks ?: IAssignmentHooks ,
95
99
) : string | null {
100
+ EppoJSClient . getAssignmentInitializationCheck ( ) ;
96
101
return super . getStringAssignment ( subjectKey , flagKey , subjectAttributes , assignmentHooks , true ) ;
97
102
}
98
103
@@ -103,6 +108,7 @@ export class EppoJSClient extends EppoClient {
103
108
subjectAttributes ?: Record < string , any > ,
104
109
assignmentHooks ?: IAssignmentHooks ,
105
110
) : boolean | null {
111
+ EppoJSClient . getAssignmentInitializationCheck ( ) ;
106
112
return super . getBoolAssignment ( subjectKey , flagKey , subjectAttributes , assignmentHooks , true ) ;
107
113
}
108
114
@@ -113,6 +119,7 @@ export class EppoJSClient extends EppoClient {
113
119
subjectAttributes ?: Record < string , any > ,
114
120
assignmentHooks ?: IAssignmentHooks ,
115
121
) : number | null {
122
+ EppoJSClient . getAssignmentInitializationCheck ( ) ;
116
123
return super . getNumericAssignment (
117
124
subjectKey ,
118
125
flagKey ,
@@ -129,6 +136,7 @@ export class EppoJSClient extends EppoClient {
129
136
subjectAttributes ?: Record < string , any > ,
130
137
assignmentHooks ?: IAssignmentHooks ,
131
138
) : string | null {
139
+ EppoJSClient . getAssignmentInitializationCheck ( ) ;
132
140
return super . getJSONStringAssignment (
133
141
subjectKey ,
134
142
flagKey ,
@@ -145,6 +153,7 @@ export class EppoJSClient extends EppoClient {
145
153
subjectAttributes ?: Record < string , any > ,
146
154
assignmentHooks ?: IAssignmentHooks ,
147
155
) : object | null {
156
+ EppoJSClient . getAssignmentInitializationCheck ( ) ;
148
157
return super . getParsedJSONAssignment (
149
158
subjectKey ,
150
159
flagKey ,
@@ -153,6 +162,12 @@ export class EppoJSClient extends EppoClient {
153
162
true ,
154
163
) ;
155
164
}
165
+
166
+ private static getAssignmentInitializationCheck ( ) {
167
+ if ( ! EppoJSClient . initialized ) {
168
+ console . warn ( 'Eppo SDK assignment requested before init() completed' ) ;
169
+ }
170
+ }
156
171
}
157
172
158
173
/**
@@ -169,8 +184,6 @@ export async function init(config: IClientConfig): Promise<IEppoClient> {
169
184
EppoJSClient . instance . stopPolling ( ) ;
170
185
}
171
186
172
- const localStorage = new EppoLocalStorage ( ) ;
173
-
174
187
const requestConfiguration : ExperimentConfigurationRequestParameters = {
175
188
apiKey : config . apiKey ,
176
189
sdkName,
@@ -184,18 +197,16 @@ export async function init(config: IClientConfig): Promise<IEppoClient> {
184
197
throwOnFailedInitialization : true , // always use true here as underlying instance fetch is surrounded by try/catch
185
198
} ;
186
199
187
- EppoJSClient . instance = new EppoJSClient ( localStorage , requestConfiguration ) ;
188
-
189
200
EppoJSClient . instance . setLogger ( config . assignmentLogger ) ;
190
201
191
202
// default behavior is to use a LocalStorage-based assignment cache.
192
203
// this can be overridden after initialization.
193
204
EppoJSClient . instance . useCustomAssignmentCache ( new LocalStorageAssignmentCache ( ) ) ;
194
-
205
+ EppoJSClient . instance . setConfigurationRequestParameters ( requestConfiguration ) ;
195
206
await EppoJSClient . instance . fetchFlagConfigurations ( ) ;
196
207
} catch ( error ) {
197
208
console . warn (
198
- 'Error encountered initializing the Eppo SDK , assignment calls will return null and not be logged' +
209
+ 'Eppo SDK encountered an error initializing , assignment calls will return null and not be logged' +
199
210
( config . pollAfterFailedInitialization
200
211
? ' until an experiment configuration is successfully retrieved'
201
212
: '' ) ,
@@ -204,6 +215,7 @@ export async function init(config: IClientConfig): Promise<IEppoClient> {
204
215
throw error ;
205
216
}
206
217
}
218
+ EppoJSClient . initialized = true ;
207
219
return EppoJSClient . instance ;
208
220
}
209
221
@@ -214,8 +226,5 @@ export async function init(config: IClientConfig): Promise<IEppoClient> {
214
226
* @public
215
227
*/
216
228
export function getInstance ( ) : IEppoClient {
217
- if ( ! EppoJSClient . instance ) {
218
- throw Error ( 'init() must first be called to initialize a client instance' ) ;
219
- }
220
229
return EppoJSClient . instance ;
221
230
}
0 commit comments