@@ -22,7 +22,7 @@ import { OdpManager } from '../odp/odp_manager';
2222import { VuidManager } from '../vuid/vuid_manager' ;
2323import { OdpEvent } from '../odp/event_manager/odp_event' ;
2424import { OptimizelySegmentOption } from '../odp/segment_manager/optimizely_segment_option' ;
25- import { BaseService } from '../service' ;
25+ import { BaseService , ServiceState } from '../service' ;
2626
2727import {
2828 UserAttributes ,
@@ -43,7 +43,7 @@ import { ProjectConfigManager } from '../project_config/project_config_manager';
4343import { createDecisionService , DecisionService , DecisionObj } from '../core/decision_service' ;
4444import { buildLogEvent } from '../event_processor/event_builder/log_event' ;
4545import { buildImpressionEvent , buildConversionEvent } from '../event_processor/event_builder/user_event' ;
46- import fns from '../utils/fns' ;
46+ import { isSafeInteger } from '../utils/fns' ;
4747import { validate } from '../utils/attributes_validator' ;
4848import * as eventTagsValidator from '../utils/event_tags_validator' ;
4949import * as projectConfig from '../project_config/project_config' ;
@@ -132,9 +132,7 @@ export type OptimizelyOptions = {
132132 disposable ?: boolean ;
133133}
134134
135- export default class Optimizely implements Client {
136- private disposeOnUpdate ?: Fn ;
137- private readyPromise : Promise < unknown > ;
135+ export default class Optimizely extends BaseService implements Client {
138136 // readyTimeout is specified as any to make this work in both browser & Node
139137 // eslint-disable-next-line @typescript-eslint/no-explicit-any
140138 private readyTimeouts : { [ key : string ] : { readyTimeout : any ; onClose : ( ) => void } } ;
@@ -143,7 +141,6 @@ export default class Optimizely implements Client {
143141 private clientVersion : string ;
144142 private errorNotifier ?: ErrorNotifier ;
145143 private errorReporter : ErrorReporter ;
146- protected logger ?: LoggerFacade ;
147144 private projectConfigManager : ProjectConfigManager ;
148145 private decisionService : DecisionService ;
149146 private eventProcessor ?: EventProcessor ;
@@ -153,6 +150,8 @@ export default class Optimizely implements Client {
153150 private vuidManager ?: VuidManager ;
154151
155152 constructor ( config : OptimizelyOptions ) {
153+ super ( ) ;
154+
156155 let clientEngine = config . clientEngine ;
157156 if ( ! clientEngine ) {
158157 config . logger ?. info ( INVALID_CLIENT_ENGINE , clientEngine ) ;
@@ -193,7 +192,8 @@ export default class Optimizely implements Client {
193192 } ) ;
194193 this . defaultDecideOptions = defaultDecideOptions ;
195194
196- this . disposeOnUpdate = this . projectConfigManager . onUpdate ( ( configObj : projectConfig . ProjectConfig ) => {
195+ this . projectConfigManager = config . projectConfigManager ;
196+ this . projectConfigManager . onUpdate ( ( configObj : projectConfig . ProjectConfig ) => {
197197 this . logger ?. info (
198198 UPDATED_OPTIMIZELY_CONFIG ,
199199 configObj . revision ,
@@ -205,9 +205,14 @@ export default class Optimizely implements Client {
205205 this . updateOdpSettings ( ) ;
206206 } ) ;
207207
208- this . projectConfigManager . start ( ) ;
209- const projectConfigManagerRunningPromise = this . projectConfigManager . onRunning ( ) ;
208+ this . eventProcessor = config . eventProcessor ;
209+ this . eventProcessor ?. onDispatch ( ( event ) => {
210+ this . notificationCenter . sendNotifications ( NOTIFICATION_TYPES . LOG_EVENT , event ) ;
211+ } ) ;
212+
213+ this . odpManager = config . odpManager ;
210214
215+
211216 let userProfileService : UserProfileService | null = null ;
212217 if ( config . userProfileService ) {
213218 try {
@@ -228,36 +233,38 @@ export default class Optimizely implements Client {
228233
229234 this . notificationCenter = createNotificationCenter ( { logger : this . logger , errorNotifier : this . errorNotifier } ) ;
230235
231- this . eventProcessor = config . eventProcessor ;
236+ this . readyTimeouts = { } ;
237+ this . nextReadyTimeoutId = 0 ;
232238
233- this . eventProcessor ?. start ( ) ;
234- const eventProcessorRunningPromise = this . eventProcessor ? this . eventProcessor . onRunning ( ) :
235- Promise . resolve ( undefined ) ;
239+ this . start ( ) ;
240+ }
236241
237- this . eventProcessor ?. onDispatch ( ( event ) => {
238- this . notificationCenter . sendNotifications ( NOTIFICATION_TYPES . LOG_EVENT , event ) ;
239- } ) ;
242+ start ( ) : void {
243+ super . start ( ) ;
240244
245+ this . state = ServiceState . Starting ;
246+ this . projectConfigManager . start ( ) ;
247+ this . eventProcessor ?. start ( ) ;
241248 this . odpManager ?. start ( ) ;
242249
243- this . readyPromise = Promise . all ( [
244- projectConfigManagerRunningPromise ,
245- eventProcessorRunningPromise ,
246- config . odpManager ? config . odpManager . onRunning ( ) : Promise . resolve ( ) ,
247- config . vuidManager ? config . vuidManager . initialize ( ) : Promise . resolve ( ) ,
248- ] ) ;
250+ Promise . all ( [
251+ this . projectConfigManager . onRunning ( ) ,
252+ this . eventProcessor ? this . eventProcessor . onRunning ( ) : Promise . resolve ( ) ,
253+ this . odpManager ? this . odpManager . onRunning ( ) : Promise . resolve ( ) ,
254+ this . vuidManager ? this . vuidManager . initialize ( ) : Promise . resolve ( ) ,
255+ ] ) . then ( ( ) => {
256+ this . state = ServiceState . Running ;
257+ this . startPromise . resolve ( ) ;
249258
250- this . readyPromise . then ( ( ) => {
251259 const vuid = this . vuidManager ?. getVuid ( ) ;
252260 if ( vuid ) {
253261 this . odpManager ?. setVuid ( vuid ) ;
254262 }
255263 } ) ;
256-
257- this . readyTimeouts = { } ;
258- this . nextReadyTimeoutId = 0 ;
259264 }
260265
266+
267+
261268 /**
262269 * Returns the project configuration retrieved from projectConfigManager
263270 * @return {projectConfig.ProjectConfig }
@@ -1228,62 +1235,43 @@ export default class Optimizely implements Client {
12281235 * above) are complete. If there are no in-flight event dispatcher requests and
12291236 * no queued events waiting to be sent, returns an immediately-fulfilled Promise.
12301237 *
1231- * Returned Promises are fulfilled with result objects containing these
1232- * properties:
1233- * - success (boolean): true if the event dispatcher signaled completion of
1234- * all in-flight and final requests, or if there were no
1235- * queued events and no in-flight requests. false if an
1236- * unexpected error was encountered during the close
1237- * process.
1238- * - reason (string=): If success is false, this is a string property with
1239- * an explanatory message.
12401238 *
12411239 * NOTE: After close is called, this instance is no longer usable - any events
12421240 * generated will no longer be sent to the event dispatcher.
12431241 *
12441242 * @return {Promise }
12451243 */
1246- close ( ) : Promise < { success : boolean ; reason ?: string } > {
1247- try {
1248- this . projectConfigManager . stop ( ) ;
1249- this . eventProcessor ?. stop ( ) ;
1250- this . odpManager ?. stop ( ) ;
1251- this . notificationCenter . clearAllNotificationListeners ( ) ;
1252-
1253- const eventProcessorStoppedPromise = this . eventProcessor ? this . eventProcessor . onTerminated ( ) :
1254- Promise . resolve ( ) ;
1255-
1256- if ( this . disposeOnUpdate ) {
1257- this . disposeOnUpdate ( ) ;
1258- this . disposeOnUpdate = undefined ;
1259- }
1244+ close ( ) : Promise < unknown > {
1245+ this . stop ( ) ;
1246+ return this . onTerminated ( ) ;
1247+ }
12601248
1261- Object . keys ( this . readyTimeouts ) . forEach ( ( readyTimeoutId : string ) => {
1262- const readyTimeoutRecord = this . readyTimeouts [ readyTimeoutId ] ;
1263- clearTimeout ( readyTimeoutRecord . readyTimeout ) ;
1264- readyTimeoutRecord . onClose ( ) ;
1265- } ) ;
1266- this . readyTimeouts = { } ;
1267- return eventProcessorStoppedPromise . then (
1268- function ( ) {
1269- return {
1270- success : true ,
1271- } ;
1272- } ,
1273- function ( err ) {
1274- return {
1275- success : false ,
1276- reason : String ( err ) ,
1277- } ;
1278- }
1279- ) ;
1280- } catch ( err ) {
1249+ stop ( ) : void {
1250+ this . state = ServiceState . Stopping ;
1251+
1252+ this . projectConfigManager . stop ( ) ;
1253+ this . eventProcessor ?. stop ( ) ;
1254+ this . odpManager ?. stop ( ) ;
1255+ this . notificationCenter . clearAllNotificationListeners ( ) ;
1256+
1257+ Object . keys ( this . readyTimeouts ) . forEach ( ( readyTimeoutId : string ) => {
1258+ const readyTimeoutRecord = this . readyTimeouts [ readyTimeoutId ] ;
1259+ clearTimeout ( readyTimeoutRecord . readyTimeout ) ;
1260+ readyTimeoutRecord . onClose ( ) ;
1261+ } ) ;
1262+
1263+ Promise . all ( [
1264+ this . projectConfigManager . onTerminated ( ) ,
1265+ this . eventProcessor ? this . eventProcessor . onTerminated ( ) : Promise . resolve ( ) ,
1266+ this . odpManager ? this . odpManager . onTerminated ( ) : Promise . resolve ( ) ,
1267+ ] ) . then ( ( ) => {
1268+ this . state = ServiceState . Terminated ;
1269+ this . stopPromise . resolve ( )
1270+ } ) . catch ( ( err ) => {
12811271 this . errorReporter . report ( err ) ;
1282- return Promise . resolve ( {
1283- success : false ,
1284- reason : String ( err ) ,
1285- } ) ;
1286- }
1272+ this . state = ServiceState . Failed ;
1273+ this . stopPromise . reject ( err ) ;
1274+ } ) ;
12871275 }
12881276
12891277 /**
@@ -1320,7 +1308,7 @@ export default class Optimizely implements Client {
13201308 timeoutValue = options . timeout ;
13211309 }
13221310 }
1323- if ( ! fns . isSafeInteger ( timeoutValue ) ) {
1311+ if ( ! isSafeInteger ( timeoutValue ) ) {
13241312 timeoutValue = DEFAULT_ONREADY_TIMEOUT ;
13251313 }
13261314
@@ -1343,12 +1331,12 @@ export default class Optimizely implements Client {
13431331 onClose : onClose ,
13441332 } ;
13451333
1346- this . readyPromise . then ( ( ) => {
1334+ this . onRunning ( ) . then ( ( ) => {
13471335 clearTimeout ( readyTimeout ) ;
13481336 delete this . readyTimeouts [ timeoutId ] ;
13491337 } ) ;
13501338
1351- return Promise . race ( [ this . readyPromise , timeoutPromise ] ) ;
1339+ return Promise . race ( [ this . onRunning ( ) , timeoutPromise ] ) ;
13521340 }
13531341
13541342 //============ decide ============//
0 commit comments