@coorpacademy/progression-engine
Version:
87 lines • 2.89 kB
JavaScript
import _sample from "lodash/fp/sample";
import _uniqBy from "lodash/fp/uniqBy";
import _reverse from "lodash/fp/reverse";
import _find from "lodash/fp/find";
import _pipe from "lodash/fp/pipe";
import _sortBy from "lodash/fp/sortBy";
import _filter from "lodash/fp/filter";
import _isEqual from "lodash/fp/isEqual";
import _head from "lodash/fp/head";
import _get from "lodash/fp/get";
import checkCondition from './condition-operators';
export const DEFAULT_SOURCE = {
type: 'slide',
ref: ''
};
const isRuleAvailable = source => chapterRule => {
const isSameSource = _isEqual(source, chapterRule.source);
const hasSameType = (source && source.type) === chapterRule.source.type;
const isGlobalRule = hasSameType && _get('source.ref', chapterRule) === '*';
return isSameSource || isGlobalRule;
};
const isSameType = refValue => value => {
if (Array.isArray(value) && Array.isArray(refValue)) return value.every(isSameType(refValue[0]));
return typeof refValue === typeof value;
};
const matchWithState = (state, chapterRule) => {
const conditions = chapterRule.conditions;
return conditions.every(condition => {
const {
target,
operator,
values
} = condition;
switch (target.scope) {
case 'slide':
{
const {
ref,
field
} = target;
const answerRecord = _pipe(_reverse, _uniqBy('slideRef'), _find({
slideRef: ref
}))(state.allAnswers);
if (!answerRecord) return false;
const value = answerRecord[field];
const typedValues = values.filter(isSameType(value));
return checkCondition(operator, typedValues, value);
}
case 'variable':
{
const {
field
} = target;
const variables = {
lives: state.lives,
stars: state.stars,
...state.variables
};
const value = variables[field];
const typedValues = values.filter(isSameType(value));
return checkCondition(operator, typedValues, value);
}
/* istanbul ignore next */
default:
{
return false;
}
}
});
};
const match = state => chapterRule => {
if (!state) {
return chapterRule.source.ref === '' && chapterRule.source.type === 'slide';
}
return matchWithState(state, chapterRule);
};
const selectRule = (rules, state) => {
const targetedChapterRules = _filter(isRuleAvailable(state ? state.nextContent : DEFAULT_SOURCE), rules);
const sortedChapterRules = _sortBy('priority', targetedChapterRules);
const machedRules = sortedChapterRules.filter(match(state));
const priority = _pipe(_head, _get('priority'))(machedRules);
return _pipe(_filter({
priority
}), _sample)(machedRules) || null;
};
export default selectRule;
//# sourceMappingURL=select-rule.js.map