@croct/rule-engine-audiences
Version:
A rule engine extension for audience targeting.
119 lines (118 loc) • 5.81 kB
JavaScript
import { __assign, __awaiter, __generator, __read, __values } from "tslib";
import { EvaluationErrorType } from '@croct/plug/sdk/evaluation';
import { formatCause } from '@croct/plug/sdk/validation';
import { Variable } from '@croct/plug-rule-engine/predicate';
var AudiencesExtension = /** @class */ (function () {
function AudiencesExtension(options, evaluator, tracker, logger) {
var _a;
this.audiences = options.map;
this.evaluationOptions = (_a = options.defaultOptions) !== null && _a !== void 0 ? _a : { timeout: 800 };
this.evaluator = evaluator;
this.tracker = tracker;
this.logger = logger;
}
AudiencesExtension.prototype.getPredicate = function (_a) {
var name = _a.name, audience = _a.properties.audience;
if (audience === undefined) {
return null;
}
if (typeof audience !== 'string') {
this.logger.error("Invalid audience specified for rule \"" + name + "\", "
+ ("expected string but got " + typeof audience + "."));
return null;
}
if (this.audiences[audience] === undefined) {
this.logger.error("Audience \"" + audience + "\" does not exist.");
return null;
}
return new Variable(audience);
};
AudiencesExtension.prototype.getVariables = function () {
var e_1, _a;
var _this = this;
var variables = {};
var _loop_1 = function (audience, definition) {
variables[audience] = typeof definition === 'string'
? function () { return _this.evaluatePredicate(audience, { expression: definition }); }
: function () { return _this.evaluatePredicate(audience, definition); };
};
try {
for (var _b = __values(Object.entries(this.audiences)), _c = _b.next(); !_c.done; _c = _b.next()) {
var _d = __read(_c.value, 2), audience = _d[0], definition = _d[1];
_loop_1(audience, definition);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
return variables;
};
AudiencesExtension.prototype.evaluatePredicate = function (audience, _a) {
var expression = _a.expression, options = _a.options;
return __awaiter(this, void 0, void 0, function () {
var generatedExpression, evaluation, result, error_1, _b, type, title_1, detail, promise;
var _this = this;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
generatedExpression = this.generateExpression(expression);
if (generatedExpression === null) {
this.logger.warn("Invalid expression definition specified for audience \"" + audience + "\".");
return [2 /*return*/, false];
}
evaluation = this.evaluator.evaluate(generatedExpression, __assign(__assign({}, this.evaluationOptions), (options !== null && options !== void 0 ? options : {})));
_c.label = 1;
case 1:
_c.trys.push([1, 3, , 4]);
return [4 /*yield*/, evaluation];
case 2:
result = _c.sent();
return [3 /*break*/, 4];
case 3:
error_1 = _c.sent();
_b = error_1.response, type = _b.type, title_1 = _b.title, detail = _b.detail;
this.logger.error("Evaluation of audience \"" + audience + "\" failed: " + formatCause(error_1));
if (type === EvaluationErrorType.TIMEOUT) {
promise = this.tracker.track('eventOccurred', {
name: 'audienceTimeout',
audience: audience,
details: {
expression: generatedExpression,
errorType: type,
errorTitle: title_1,
errorDetail: detail !== null && detail !== void 0 ? detail : '',
},
});
promise.catch(function () {
_this.logger.debug("Failed to log audience evaluation error \"" + title_1 + "\"");
});
}
return [2 /*return*/, false];
case 4:
if (typeof result !== 'boolean') {
this.logger.warn("Evaluation result for audience \"" + audience + "\" is not boolean "
+ 'which may lead to unexpected results.');
}
return [2 /*return*/, result === true];
}
});
});
};
AudiencesExtension.prototype.generateExpression = function (definition) {
var _a;
if (typeof definition === 'string') {
return definition;
}
var conjunction = definition.conjunction, subexpressions = definition.subexpressions;
if (subexpressions.length < 2) {
return (_a = subexpressions[0]) !== null && _a !== void 0 ? _a : null;
}
return "(" + subexpressions.join(") " + conjunction + " (") + ")";
};
return AudiencesExtension;
}());
export default AudiencesExtension;