UNPKG

elliptical

Version:

Interactive natural-language interfaces

449 lines (346 loc) 14.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _regenerator = require('babel-runtime/regenerator'); var _regenerator2 = _interopRequireDefault(_regenerator); var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray'); var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); var _typeof2 = require('babel-runtime/helpers/typeof'); var _typeof3 = _interopRequireDefault(_typeof2); var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray'); var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2); exports.default = compile; var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _utils = require('./utils'); var _phrases = require('./phrases'); var phrases = _interopRequireWildcard(_phrases); var _option = require('./option'); var _option2 = _interopRequireDefault(_option); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _marked = [postProcess].map(_regenerator2.default.mark); function applyDefaults(element) { return _lodash2.default.assign({}, element, { props: _lodash2.default.defaults({}, element.props, element.type.defaultProps || {}) }); } function compileAndAddToMap(subElement, process, elementMap, _ref) { var errors = _ref.errors; var traverse = compileNonRoot(subElement, process, { errors: errors }); elementMap.set(subElement, traverse); return traverse; } function next(elementMap, process, subElement, option, _ref2) { var errors = _ref2.errors; var traverser = elementMap.get(subElement); if (traverser) { return traverser(option); } else { var newTraverser = compileAndAddToMap(subElement, process, elementMap, { errors: errors }); return newTraverser(option); } } function compileProp(prop, process, elementMap, _ref3) { var errors = _ref3.errors; if (prop && prop.type && prop.props && prop.children && (_lodash2.default.isPlainObject(prop.type) || _lodash2.default.isString(prop.type)) && _lodash2.default.isPlainObject(prop.props) && _lodash2.default.isArray(prop.children)) { // We can be pretty sure this is an element, return compileAndAddToMap(prop, process, elementMap, { errors: errors }); } else { return prop; } } function getPhrase(element) { return _lodash2.default.isString(element.type) ? phrases[element.type] : element.type; } function tryRunning(func, errors, messages) { var defaultIfError = arguments.length <= 3 || arguments[3] === undefined ? null : arguments[3]; if (errors === 'log') { try { return func(); } catch (e) { var _console; (_console = console).error.apply(_console, (0, _toConsumableArray3.default)(messages).concat([e])); return defaultIfError; } } else { return func(); } } function compileNonRoot(element, process, _ref4) { var errors = _ref4.errors; // ignore null elements if (element == null) return function () { return []; }; // assign defaultProps element = applyDefaults(element); if (process) { element = tryRunning(function () { return process(element); }, errors, ['An error occurred processing', element]); // allow process calls to nullify elements if (element == null) return function () { return []; }; } var phrase = getPhrase(element); // call describe if (phrase.describe) { if (phrase.lazy === false) { var description = tryRunning(function () { return phrase.describe(element); }, errors, ['An error occurred describing', element]); var _traverse = compileNonRoot(description, process, { errors: errors }); return addOutbound(element, _traverse, { errors: errors }); } else { var _ret = function () { var subTraverse = void 0; var traverse = function traverse(input) { if (!subTraverse) { var _description = tryRunning(function () { return phrase.describe(element); }, errors, ['An error occurred dynamically describing', element]); subTraverse = compileNonRoot(_description, process, { errors: errors }); } return subTraverse(input); }; return { v: addOutbound(element, traverse, { errors: errors }) }; }(); if ((typeof _ret === 'undefined' ? 'undefined' : (0, _typeof3.default)(_ret)) === "object") return _ret.v; } } var elementMap = new Map(); // if there's no describe, check to see if any props are elements // and compile those _lodash2.default.forEach(element.props, function (prop) { return compileProp(prop, process, elementMap, { errors: errors }); }); // generate the traverse thunk _lodash2.default.forEach(element.children, function (child) { return compileAndAddToMap(child, process, elementMap, { errors: errors }); }); var subTraverse = function subTraverse(subElem, option) { return next(elementMap, process, subElem, option, { errors: errors }); }; var traverse = function traverse(option) { return tryRunning(function () { return phrase.visit(option, element, subTraverse); }, errors, ['An error occurred visiting', element], []); }; return addOutbound(element, traverse, { errors: errors }); } function addOutbound(element, traverse, _ref5) { var errors = _ref5.errors; return _regenerator2.default.mark(function _callee(option) { var _this = this; var start, mods, newOption, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _loop, _iterator, _step, _ret2; return _regenerator2.default.wrap(function _callee$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: start = option.words.length; mods = {}; if (element.props.data != null) { mods.data = _lodash2.default.concat(option.data, [element.props.data]); } newOption = _lodash2.default.assign({}, option, mods); _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; _context2.prev = 7; _loop = _regenerator2.default.mark(function _loop() { var output, newResult, filterResultResult, end, mods; return _regenerator2.default.wrap(function _loop$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: output = _step.value; if (!(0, _utils.isComplete)(output)) { _context.next = 7; break; } if (element.type.mapResult) { newResult = tryRunning(function () { return element.type.mapResult(output.result, element); }, errors, ['An error occurred in mapResult of', element], output.result); output = _lodash2.default.assign({}, output, { result: newResult }); } if (!element.type.filterResult) { _context.next = 7; break; } filterResultResult = tryRunning(function () { return element.type.filterResult(output.result, element); }, errors, ['An error occurred in filterResult of', element], true); if (filterResultResult) { _context.next = 7; break; } return _context.abrupt('return', 'continue'); case 7: end = output.words.length; mods = {}; if (element.props.value != null) { mods.result = element.props.value; } if (element.props.score != null) { mods.score = element.props.score; } if (element.props.multiplier != null) { mods.score = element.props.multiplier * (element.props.score == null ? output.score : element.props.score); } _lodash2.default.forEach([['qualifiers', 'qualifier'], ['arguments', 'argument'], ['annotations', 'annotation'], ['categories', 'category']], function (_ref6) { var _ref7 = (0, _slicedToArray3.default)(_ref6, 2); var plural = _ref7[0]; var singular = _ref7[1]; if (element.props[plural] != null || element.props[singular] != null) { var theseAdditions = element.props[plural] || [element.props[singular]]; var outputAdditions = _lodash2.default.map(theseAdditions, function (addition) { return { value: addition, start: start, end: end }; }); mods[plural] = _lodash2.default.concat(outputAdditions, output[plural]); } }); _context.next = 15; return _lodash2.default.assign({}, output, mods); case 15: case 'end': return _context.stop(); } } }, _loop, _this); }); _iterator = traverse(newOption)[Symbol.iterator](); case 10: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { _context2.next = 18; break; } return _context2.delegateYield(_loop(), 't0', 12); case 12: _ret2 = _context2.t0; if (!(_ret2 === 'continue')) { _context2.next = 15; break; } return _context2.abrupt('continue', 15); case 15: _iteratorNormalCompletion = true; _context2.next = 10; break; case 18: _context2.next = 24; break; case 20: _context2.prev = 20; _context2.t1 = _context2['catch'](7); _didIteratorError = true; _iteratorError = _context2.t1; case 24: _context2.prev = 24; _context2.prev = 25; if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } case 27: _context2.prev = 27; if (!_didIteratorError) { _context2.next = 30; break; } throw _iteratorError; case 30: return _context2.finish(27); case 31: return _context2.finish(24); case 32: case 'end': return _context2.stop(); } } }, _callee, this, [[7, 20, 24, 32], [25,, 27, 31]]); }); } function compile(element, process) { var _ref8 = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; var _ref8$errors = _ref8.errors; var errors = _ref8$errors === undefined ? 'none' : _ref8$errors; var compiled = compileNonRoot(element, process, { errors: errors }); return function traverse(input) { var postProcessed = postProcess(compiled, input); var allOutputs = Array.from(postProcessed); return _lodash2.default.sortBy(allOutputs, function (output) { return -output.score; }); }; } function postProcess(compiled, input) { var option, outputs, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, _output, newOutput; return _regenerator2.default.wrap(function postProcess$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: option = (0, _option2.default)({ text: input }); outputs = compiled(option); _iteratorNormalCompletion2 = true; _didIteratorError2 = false; _iteratorError2 = undefined; _context3.prev = 5; _iterator2 = outputs[Symbol.iterator](); case 7: if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) { _context3.next = 18; break; } _output = _step2.value; if (!(_output.text === '' || _output.text == null)) { _context3.next = 15; break; } _lodash2.default.forEach(_output.callbacks, function (callback) { return callback(); }); newOutput = _lodash2.default.clone(_output); delete newOutput.callbacks; _context3.next = 15; return newOutput; case 15: _iteratorNormalCompletion2 = true; _context3.next = 7; break; case 18: _context3.next = 24; break; case 20: _context3.prev = 20; _context3.t0 = _context3['catch'](5); _didIteratorError2 = true; _iteratorError2 = _context3.t0; case 24: _context3.prev = 24; _context3.prev = 25; if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } case 27: _context3.prev = 27; if (!_didIteratorError2) { _context3.next = 30; break; } throw _iteratorError2; case 30: return _context3.finish(27); case 31: return _context3.finish(24); case 32: case 'end': return _context3.stop(); } } }, _marked[0], this, [[5, 20, 24, 32], [25,, 27, 31]]); }