UNPKG

autosuggestion

Version:

  Generates suggestions for text completion.  

129 lines 5.15 kB
var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; import { Suggestion } from './suggestion'; var Node = /** @class */ (function () { function Node(value) { this.value = value; this.end = false; this.next = { char: {}, word: {}, lookup: {} }; } Node.prototype.isLeaf = function () { return Object.keys(this.next.char).length === 0 && Object.keys(this.next.word).length === 0 && Object.keys(this.next.lookup).length === 0; }; /** * Given an input sequence of words, a starting [[Node | node]], and * a [[Dictionary | dictionary]], finds all valid matching paths that * the input satisfies. * * #### Simple Example * If we have a starting node which yields the following * sub-trie, * ``` * t - r - i - e * \ * e - e * ``` * and input *"tr"*, the returned node will be *"r"*. * * #### Advanced Example * With a more complex starting trie, * ``` * null - a - b - c - - d (1) * \ * <X> - - d (2) * * <X>: null - a - b - c * \ * <Y> * * <Y>: null - a - b - c - - d (3) * ``` * given **"abc d"**, it wll return the **"d"** [[Node | nodes]] labeled * _(1)_, _(2)_, _(3)_ * * Since patterns can span multiple levels of nested contexts, we need to return * not only the matched words (partially matched on completed words), but also the * remainder of the match. This way, we can check for matches in parent contexts in * case a pattern satisfies a match over an arbitrary number of contextual levels. */ Node.prototype.matchPattern = function (tokens) { if (tokens.length === 0) return []; var matches = []; // find matching paths from lookups for (var _i = 0, _a = Object.entries(this.next.lookup); _i < _a.length; _i++) { var _b = _a[_i], alias = _b[0], lookup = _b[1]; matches = matches.concat(lookup.matchPattern(tokens)); } return matches.concat(this.matchWord(tokens)); }; Node.prototype.matchWord = function (tokens) { var word = this.next.word[tokens[0][0]]; if (!word) return []; var node = word.matchChars(tokens[0]); if (!node) return []; var match = { nodes: [node], remainder: tokens.slice(1) }; // (1) if there are no remainders keep searching. include match in results if it is a terminal. // (2) if there are no remainders, return this single match (regardless of if it isa terminal). return match.remainder.length > 0 ? (node.end ? [match] : []).concat(node.matchPattern(match.remainder)) // (1) : [match]; // (2) }; /** * Given an word, returns the final node which matches the complete word. null otherwise. */ Node.prototype.matchChars = function (word) { if (this.value !== word[0]) return null; var node = this; word = word.substr(1); while (word) { node = node.next.char[word[0]]; if (!node) return null; word = word.substr(1); } return node; }; Node.prototype.completePattern = function (tokens) { var _a; var suggestions = []; // complete pattern in all next lookups for (var _i = 0, _b = Object.entries(this.next.lookup); _i < _b.length; _i++) { var _c = _b[_i], alias = _c[0], lookup = _c[1]; suggestions = suggestions.concat(lookup.completePattern(__spreadArrays(tokens, [(_a = {}, _a[lookup.value] = lookup.contexts, _a)]))); } // complete pattern in all next words for (var _d = 0, _e = Object.entries(this.next.word); _d < _e.length; _d++) { var _f = _e[_d], char = _f[0], word = _f[1]; suggestions = suggestions.concat(word.completeWord(__spreadArrays(tokens, [char]))); } return suggestions.concat(this.completeWord(tokens)); }; Node.prototype.completeWord = function (tokens) { var suggestions = []; // if this is an ending node, add it to suggestions if (this.end) suggestions.push(new Suggestion(__spreadArrays(tokens))); var lastWord = tokens.pop() || ''; // augment the last token with the next characters for (var _i = 0, _a = Object.values(this.next.char); _i < _a.length; _i++) { var char = _a[_i]; var augmentedTokens = __spreadArrays(tokens, ["" + lastWord + char.value]); suggestions = suggestions.concat(char.completePattern(augmentedTokens)); } return suggestions; }; return Node; }()); export { Node }; //# sourceMappingURL=node.js.map