UNPKG

@splitsoftware/splitio-commons

Version:
101 lines (100 loc) 4.51 kB
import { objectAssign } from '../utils/lang/objectAssign'; import { promiseWrapper } from '../utils/promise/wrapper'; import { readinessManagerFactory } from './readinessManager'; import { SDK_READY, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE } from './constants'; import { ERROR_CLIENT_LISTENER, CLIENT_READY_FROM_CACHE, CLIENT_READY, CLIENT_NO_LISTENER } from '../logger/constants'; var NEW_LISTENER_EVENT = 'newListener'; var REMOVE_LISTENER_EVENT = 'removeListener'; /** * SdkReadinessManager factory, which provides the public status API of SDK clients and manager: ready promise, readiness event emitter and constants (SDK_READY, etc). * It also updates logs related warnings and errors. * * @param readyTimeout - time in millis to emit SDK_READY_TIME_OUT event * @param readinessManager - optional readinessManager to use. only used internally for `shared` method */ export function sdkReadinessManagerFactory(EventEmitter, settings, readinessManager) { if (readinessManager === void 0) { readinessManager = readinessManagerFactory(EventEmitter, settings); } var log = settings.log; /** Ready callback warning */ var internalReadyCbCount = 0; var readyCbCount = 0; readinessManager.gate.on(REMOVE_LISTENER_EVENT, function (event) { if (event === SDK_READY) readyCbCount--; }); readinessManager.gate.on(NEW_LISTENER_EVENT, function (event) { if (event === SDK_READY || event === SDK_READY_TIMED_OUT) { if (readinessManager.isReady()) { log.error(ERROR_CLIENT_LISTENER, [event === SDK_READY ? 'SDK_READY' : 'SDK_READY_TIMED_OUT']); } else if (event === SDK_READY) { readyCbCount++; } } }); /** Ready promise */ var readyPromise = generateReadyPromise(); readinessManager.gate.once(SDK_READY_FROM_CACHE, function () { log.info(CLIENT_READY_FROM_CACHE); }); // default onRejected handler, that just logs the error, if ready promise doesn't have one. function defaultOnRejected(err) { log.error(err && err.message); } function generateReadyPromise() { var promise = promiseWrapper(new Promise(function (resolve, reject) { readinessManager.gate.once(SDK_READY, function () { log.info(CLIENT_READY); if (readyCbCount === internalReadyCbCount && !promise.hasOnFulfilled()) log.warn(CLIENT_NO_LISTENER); resolve(); }); readinessManager.gate.once(SDK_READY_TIMED_OUT, function (message) { reject(new Error(message)); }); }), defaultOnRejected); return promise; } return { readinessManager: readinessManager, shared: function () { return sdkReadinessManagerFactory(EventEmitter, settings, readinessManager.shared()); }, incInternalReadyCbCount: function () { internalReadyCbCount++; }, sdkStatus: objectAssign( // Expose Event Emitter functionality Object.create(readinessManager.gate), { // Expose the event constants without changing the interface Event: { SDK_READY: SDK_READY, SDK_READY_FROM_CACHE: SDK_READY_FROM_CACHE, SDK_UPDATE: SDK_UPDATE, SDK_READY_TIMED_OUT: SDK_READY_TIMED_OUT, }, ready: function () { if (readinessManager.hasTimedout()) { if (!readinessManager.isReady()) { return promiseWrapper(Promise.reject(new Error('Split SDK has emitted SDK_READY_TIMED_OUT event.')), defaultOnRejected); } else { return Promise.resolve(); } } return readyPromise; }, __getStatus: function () { return { isReady: readinessManager.isReady(), isReadyFromCache: readinessManager.isReadyFromCache(), isTimedout: readinessManager.isTimedout(), hasTimedout: readinessManager.hasTimedout(), isDestroyed: readinessManager.isDestroyed(), isOperational: readinessManager.isOperational(), lastUpdate: readinessManager.lastUpdate(), }; }, }) }; }