@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
121 lines (120 loc) • 5.51 kB
JavaScript
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 } from '../logger/constants';
var NEW_LISTENER_EVENT = 'newListener';
var TIMEOUT_ERROR = new Error(SDK_READY_TIMED_OUT);
/**
* 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;
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_FROM_CACHE && readinessManager.isReadyFromCache()) {
log.error(ERROR_CLIENT_LISTENER, ['SDK_READY_FROM_CACHE']);
}
});
/** 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);
resolve();
});
readinessManager.gate.once(SDK_READY_TIMED_OUT, function (message) {
reject(new Error(message));
});
}), defaultOnRejected);
return promise;
}
function getStatus() {
return {
isReady: readinessManager.isReady(),
isReadyFromCache: readinessManager.isReadyFromCache(),
isTimedout: readinessManager.isTimedout(),
hasTimedout: readinessManager.hasTimedout(),
isDestroyed: readinessManager.isDestroyed(),
isOperational: readinessManager.isOperational(),
lastUpdate: readinessManager.lastUpdate(),
};
}
return {
readinessManager: readinessManager,
shared: function () {
return sdkReadinessManagerFactory(EventEmitter, settings, readinessManager.shared());
},
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,
},
// @TODO: remove in next major
ready: function () {
if (readinessManager.hasTimedout()) {
if (!readinessManager.isReady()) {
return promiseWrapper(Promise.reject(new Error('SDK client has emitted SDK_READY_TIMED_OUT event.')), defaultOnRejected);
}
else {
return Promise.resolve();
}
}
return readyPromise;
},
whenReady: function () {
return new Promise(function (resolve, reject) {
if (readinessManager.isReady()) {
resolve(readinessManager.metadataReady());
}
else if (readinessManager.hasTimedout()) {
reject(TIMEOUT_ERROR);
}
else {
readinessManager.gate.once(SDK_READY, resolve);
readinessManager.gate.once(SDK_READY_TIMED_OUT, function () { return reject(TIMEOUT_ERROR); });
}
});
},
whenReadyFromCache: function () {
return new Promise(function (resolve, reject) {
if (readinessManager.isReadyFromCache()) {
resolve(readinessManager.metadataReady());
}
else if (readinessManager.hasTimedout()) {
reject(TIMEOUT_ERROR);
}
else {
readinessManager.gate.once(SDK_READY_FROM_CACHE, resolve);
readinessManager.gate.once(SDK_READY_TIMED_OUT, function () { return reject(TIMEOUT_ERROR); });
}
});
},
getStatus: getStatus,
// @TODO: remove in next major
__getStatus: getStatus
})
};
}