predictor.js 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. "use strict";
  2. // Prefix predictor for the mnemonicode wordlist. Words are not distinct at
  3. // any fixed prefix length (one pair, "capital"/"capitan", needs 6 of 7
  4. // chars), so matching always refines on the full typed prefix rather than
  5. // assuming a fixed cutoff.
  6. function lowerBound(sorted, target) {
  7. let lo = 0;
  8. let hi = sorted.length;
  9. while (lo < hi) {
  10. const mid = (lo + hi) >>> 1;
  11. if (sorted[mid] < target) lo = mid + 1;
  12. else hi = mid;
  13. }
  14. return lo;
  15. }
  16. class Predictor {
  17. constructor(words) {
  18. this.words = words.slice().sort();
  19. }
  20. // All words starting with `prefix`, in alphabetical order.
  21. matches(prefix) {
  22. const lo = lowerBound(this.words, prefix);
  23. const hi = lowerBound(this.words, prefix + "￿");
  24. return this.words.slice(lo, hi);
  25. }
  26. // Prediction state for a prefix the user has typed so far.
  27. predict(prefix) {
  28. const matches = this.matches(prefix);
  29. return {
  30. prefix,
  31. matches,
  32. isWord: matches.includes(prefix),
  33. completion: matches.length === 1 ? matches[0] : null,
  34. };
  35. }
  36. }
  37. module.exports = { Predictor };