@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
135 lines (134 loc) • 5.71 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.evaluateFeaturesByFlagSets = exports.evaluateFeatures = exports.evaluateFeature = void 0;
var Engine_1 = require("./Engine");
var thenable_1 = require("../utils/promise/thenable");
var labels_1 = require("../utils/labels");
var constants_1 = require("../utils/constants");
var sets_1 = require("../utils/lang/sets");
var constants_2 = require("../logger/constants");
var treatmentException = {
treatment: constants_1.CONTROL,
label: labels_1.EXCEPTION,
config: null
};
function treatmentsException(splitNames) {
var evaluations = {};
splitNames.forEach(function (splitName) {
evaluations[splitName] = treatmentException;
});
return evaluations;
}
function evaluateFeature(log, key, splitName, attributes, storage) {
var parsedSplit;
try {
parsedSplit = storage.splits.getSplit(splitName);
}
catch (e) {
// Exception on sync `getSplit` storage. Not possible ATM with InMemory and InLocal storages.
return treatmentException;
}
if ((0, thenable_1.thenable)(parsedSplit)) {
return parsedSplit.then(function (split) { return getEvaluation(log, key, split, attributes, storage); }).catch(
// Exception on async `getSplit` storage. For example, when the storage is redis or
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
function () { return treatmentException; });
}
return getEvaluation(log, key, parsedSplit, attributes, storage);
}
exports.evaluateFeature = evaluateFeature;
function evaluateFeatures(log, key, splitNames, attributes, storage) {
var parsedSplits;
try {
parsedSplits = storage.splits.getSplits(splitNames);
}
catch (e) {
// Exception on sync `getSplits` storage. Not possible ATM with InMemory and InLocal storages.
return treatmentsException(splitNames);
}
return (0, thenable_1.thenable)(parsedSplits) ?
parsedSplits.then(function (splits) { return getEvaluations(log, key, splitNames, splits, attributes, storage); })
.catch(function () {
// Exception on async `getSplits` storage. For example, when the storage is redis or
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
return treatmentsException(splitNames);
}) :
getEvaluations(log, key, splitNames, parsedSplits, attributes, storage);
}
exports.evaluateFeatures = evaluateFeatures;
function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method) {
var storedFlagNames;
function evaluate(featureFlagsByFlagSets) {
var featureFlags = new Set();
for (var i = 0; i < flagSets.length; i++) {
var featureFlagByFlagSet = featureFlagsByFlagSets[i];
if (featureFlagByFlagSet.size) {
featureFlags = (0, sets_1.returnSetsUnion)(featureFlags, featureFlagByFlagSet);
}
else {
log.warn(constants_2.WARN_FLAGSET_WITHOUT_FLAGS, [method, flagSets[i]]);
}
}
return featureFlags.size ?
evaluateFeatures(log, key, (0, sets_1.setToArray)(featureFlags), attributes, storage) :
{};
}
// get features by flag sets
try {
storedFlagNames = storage.splits.getNamesByFlagSets(flagSets);
}
catch (e) {
// return empty evaluations
return {};
}
// evaluate related features
return (0, thenable_1.thenable)(storedFlagNames) ?
storedFlagNames.then(function (storedFlagNames) { return evaluate(storedFlagNames); })
.catch(function () {
return {};
}) :
evaluate(storedFlagNames);
}
exports.evaluateFeaturesByFlagSets = evaluateFeaturesByFlagSets;
function getEvaluation(log, key, splitJSON, attributes, storage) {
var evaluation = {
treatment: constants_1.CONTROL,
label: labels_1.SPLIT_NOT_FOUND,
config: null
};
if (splitJSON) {
var split = (0, Engine_1.engineParser)(log, splitJSON, storage);
evaluation = split.getTreatment(key, attributes, evaluateFeature);
// If the storage is async and the evaluated flag uses segments or dependencies, evaluation is thenable
if ((0, thenable_1.thenable)(evaluation)) {
return evaluation.then(function (result) {
result.changeNumber = splitJSON.changeNumber;
result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null;
result.impressionsDisabled = splitJSON.impressionsDisabled;
return result;
});
}
else {
evaluation.changeNumber = splitJSON.changeNumber;
evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
evaluation.impressionsDisabled = splitJSON.impressionsDisabled;
}
}
return evaluation;
}
function getEvaluations(log, key, splitNames, splits, attributes, storage) {
var result = {};
var thenables = [];
splitNames.forEach(function (splitName) {
var evaluation = getEvaluation(log, key, splits[splitName], attributes, storage);
if ((0, thenable_1.thenable)(evaluation)) {
thenables.push(evaluation.then(function (res) {
result[splitName] = res;
}));
}
else {
result[splitName] = evaluation;
}
});
return thenables.length > 0 ? Promise.all(thenables).then(function () { return result; }) : result;
}
;