UNPKG

@coorpacademy/progression-engine

Version:

87 lines 2.89 kB
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