@@ -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 }
@@ -1220,62 +1227,43 @@ export default class Optimizely implements Client {
12201227 * above) are complete. If there are no in-flight event dispatcher requests and
12211228 * no queued events waiting to be sent, returns an immediately-fulfilled Promise.
12221229 *
1223- * Returned Promises are fulfilled with result objects containing these
1224- * properties:
1225- * - success (boolean): true if the event dispatcher signaled completion of
1226- * all in-flight and final requests, or if there were no
1227- * queued events and no in-flight requests. false if an
1228- * unexpected error was encountered during the close
1229- * process.
1230- * - reason (string=): If success is false, this is a string property with
1231- * an explanatory message.
12321230 *
12331231 * NOTE: After close is called, this instance is no longer usable - any events
12341232 * generated will no longer be sent to the event dispatcher.
12351233 *
12361234 * @return {Promise }
12371235 */
1238- close ( ) : Promise < { success : boolean ; reason ?: string } > {
1239- try {
1240- this . projectConfigManager . stop ( ) ;
1241- this . eventProcessor ?. stop ( ) ;
1242- this . odpManager ?. stop ( ) ;
1243- this . notificationCenter . clearAllNotificationListeners ( ) ;
1244-
1245- const eventProcessorStoppedPromise = this . eventProcessor ? this . eventProcessor . onTerminated ( ) :
1246- Promise . resolve ( ) ;
1247-
1248- if ( this . disposeOnUpdate ) {
1249- this . disposeOnUpdate ( ) ;
1250- this . disposeOnUpdate = undefined ;
1251- }
1236+ close ( ) : Promise < unknown > {
1237+ this . stop ( ) ;
1238+ return this . onTerminated ( ) ;
1239+ }
12521240
1253- Object . keys ( this . readyTimeouts ) . forEach ( ( readyTimeoutId : string ) => {
1254- const readyTimeoutRecord = this . readyTimeouts [ readyTimeoutId ] ;
1255- clearTimeout ( readyTimeoutRecord . readyTimeout ) ;
1256- readyTimeoutRecord . onClose ( ) ;
1257- } ) ;
1258- this . readyTimeouts = { } ;
1259- return eventProcessorStoppedPromise . then (
1260- function ( ) {
1261- return {
1262- success : true ,
1263- } ;
1264- } ,
1265- function ( err ) {
1266- return {
1267- success : false ,
1268- reason : String ( err ) ,
1269- } ;
1270- }
1271- ) ;
1272- } catch ( err ) {
1241+ stop ( ) : void {
1242+ this . state = ServiceState . Stopping ;
1243+
1244+ this . projectConfigManager . stop ( ) ;
1245+ this . eventProcessor ?. stop ( ) ;
1246+ this . odpManager ?. stop ( ) ;
1247+ this . notificationCenter . clearAllNotificationListeners ( ) ;
1248+
1249+ Object . keys ( this . readyTimeouts ) . forEach ( ( readyTimeoutId : string ) => {
1250+ const readyTimeoutRecord = this . readyTimeouts [ readyTimeoutId ] ;
1251+ clearTimeout ( readyTimeoutRecord . readyTimeout ) ;
1252+ readyTimeoutRecord . onClose ( ) ;
1253+ } ) ;
1254+
1255+ Promise . all ( [
1256+ this . projectConfigManager . onTerminated ( ) ,
1257+ this . eventProcessor ? this . eventProcessor . onTerminated ( ) : Promise . resolve ( ) ,
1258+ this . odpManager ? this . odpManager . onTerminated ( ) : Promise . resolve ( ) ,
1259+ ] ) . then ( ( ) => {
1260+ this . state = ServiceState . Terminated ;
1261+ this . stopPromise . resolve ( )
1262+ } ) . catch ( ( err ) => {
12731263 this . errorReporter . report ( err ) ;
1274- return Promise . resolve ( {
1275- success : false ,
1276- reason : String ( err ) ,
1277- } ) ;
1278- }
1264+ this . state = ServiceState . Failed ;
1265+ this . stopPromise . reject ( err ) ;
1266+ } ) ;
12791267 }
12801268
12811269 /**
@@ -1312,7 +1300,7 @@ export default class Optimizely implements Client {
13121300 timeoutValue = options . timeout ;
13131301 }
13141302 }
1315- if ( ! fns . isSafeInteger ( timeoutValue ) ) {
1303+ if ( ! isSafeInteger ( timeoutValue ) ) {
13161304 timeoutValue = DEFAULT_ONREADY_TIMEOUT ;
13171305 }
13181306
@@ -1335,12 +1323,12 @@ export default class Optimizely implements Client {
13351323 onClose : onClose ,
13361324 } ;
13371325
1338- this . readyPromise . then ( ( ) => {
1326+ this . onRunning ( ) . then ( ( ) => {
13391327 clearTimeout ( readyTimeout ) ;
13401328 delete this . readyTimeouts [ timeoutId ] ;
13411329 } ) ;
13421330
1343- return Promise . race ( [ this . readyPromise , timeoutPromise ] ) ;
1331+ return Promise . race ( [ this . onRunning ( ) , timeoutPromise ] ) ;
13441332 }
13451333
13461334 //============ decide ============//
0 commit comments