clarity-pattern-parser 11.4.1 → 11.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -431,9 +431,10 @@ class CursorHistory {
431
431
  }
432
432
  }
433
433
 
434
+ const segmenter = new Intl.Segmenter("und", { granularity: "grapheme" });
434
435
  class Cursor {
435
436
  get text() {
436
- return this._chars.join("");
437
+ return this._text;
437
438
  }
438
439
  get isOnFirst() {
439
440
  return this._index === 0;
@@ -481,33 +482,55 @@ class Cursor {
481
482
  return this._history.error != null;
482
483
  }
483
484
  get currentChar() {
484
- return this._chars[this._index];
485
+ const index = this.getCharStartIndex(this._index);
486
+ return this.text.slice(index, index + this._charSize[index]);
485
487
  }
486
488
  constructor(text) {
487
- this._chars = [...text];
489
+ this._text = text;
490
+ this._length = text.length;
491
+ this._charSize = [];
492
+ this._charMap = [];
488
493
  this._index = 0;
489
- this._length = this._chars.length;
490
494
  this._history = new CursorHistory();
495
+ let index = 0;
496
+ for (const segment of segmenter.segment(text)) {
497
+ const size = segment.segment.length;
498
+ for (let i = 0; i < size; i++) {
499
+ this._charMap.push(index);
500
+ this._charSize.push(size);
501
+ }
502
+ index += size;
503
+ }
491
504
  }
492
505
  hasNext() {
493
- return this._index + 1 < this._length;
506
+ const index = this._charMap[this._index];
507
+ const charSize = this._charSize[index];
508
+ return index + charSize < this._length;
494
509
  }
495
510
  next() {
496
511
  if (this.hasNext()) {
497
- this._index++;
512
+ const index = this._charMap[this._index];
513
+ const size = this._charSize[index];
514
+ this.moveTo(index + size);
498
515
  }
499
516
  }
500
517
  hasPrevious() {
501
- return this._index - 1 >= 0;
518
+ var _a;
519
+ const index = this._charMap[this._index];
520
+ const previousIndex = (_a = this._charMap[index - 1]) !== null && _a !== void 0 ? _a : -1;
521
+ return previousIndex >= 0;
502
522
  }
503
523
  previous() {
524
+ var _a;
504
525
  if (this.hasPrevious()) {
505
- this._index--;
526
+ const index = this._charMap[this._index];
527
+ const previousIndex = (_a = this._charMap[index - 1]) !== null && _a !== void 0 ? _a : -1;
528
+ this.moveTo(previousIndex);
506
529
  }
507
530
  }
508
531
  moveTo(position) {
509
532
  if (position >= 0 && position < this._length) {
510
- this._index = position;
533
+ this._index = this._charMap[position];
511
534
  }
512
535
  }
513
536
  moveToFirstChar() {
@@ -519,8 +542,8 @@ class Cursor {
519
542
  getLastIndex() {
520
543
  return this._length - 1;
521
544
  }
522
- getChars(first, last) {
523
- return this._chars.slice(first, last + 1).join("");
545
+ substring(first, last) {
546
+ return this._text.slice(first, last + 1);
524
547
  }
525
548
  recordMatch(pattern, node) {
526
549
  this._history.recordMatch(pattern, node);
@@ -537,6 +560,18 @@ class Cursor {
537
560
  stopRecording() {
538
561
  this._history.stopRecording();
539
562
  }
563
+ getCharStartIndex(index) {
564
+ return this._charMap[index];
565
+ }
566
+ getCharEndIndex(index) {
567
+ var _a;
568
+ let startIndex = this.getCharStartIndex(index);
569
+ return (_a = startIndex + this._charSize[startIndex]) !== null && _a !== void 0 ? _a : 1;
570
+ }
571
+ getCharLastIndex(index) {
572
+ var _a;
573
+ return (_a = this.getCharEndIndex(index) - 1) !== null && _a !== void 0 ? _a : 0;
574
+ }
540
575
  }
541
576
 
542
577
  function execPattern(pattern, text, record = false) {
@@ -602,11 +637,9 @@ class Literal {
602
637
  this._type = "literal";
603
638
  this._name = name;
604
639
  this._token = value;
605
- this._runes = Array.from(value);
606
640
  this._parent = null;
607
641
  this._firstIndex = 0;
608
642
  this._lastIndex = 0;
609
- this._endIndex = 0;
610
643
  }
611
644
  test(text, record = false) {
612
645
  return testPattern(this, text, record);
@@ -616,6 +649,7 @@ class Literal {
616
649
  }
617
650
  parse(cursor) {
618
651
  this._firstIndex = cursor.index;
652
+ this._lastIndex = cursor.index;
619
653
  const passed = this._tryToParse(cursor);
620
654
  if (passed) {
621
655
  cursor.resolveError();
@@ -623,31 +657,28 @@ class Literal {
623
657
  cursor.recordMatch(this, node);
624
658
  return node;
625
659
  }
626
- cursor.recordErrorAt(this._firstIndex, this._endIndex, this);
660
+ cursor.recordErrorAt(this._firstIndex, this._lastIndex, this);
627
661
  return null;
628
662
  }
629
663
  _tryToParse(cursor) {
630
- let passed = false;
631
- const literalRuneLength = this._runes.length;
632
- for (let i = 0; i < literalRuneLength; i++) {
633
- const literalRune = this._runes[i];
634
- const cursorRune = cursor.currentChar;
635
- if (literalRune !== cursorRune) {
636
- this._endIndex = cursor.index;
637
- break;
638
- }
639
- if (i + 1 === literalRuneLength) {
640
- this._lastIndex = this._firstIndex + this._token.length - 1;
641
- passed = true;
642
- break;
643
- }
644
- if (!cursor.hasNext()) {
645
- this._endIndex = cursor.index + 1;
646
- break;
664
+ const token = this._token;
665
+ const compareToToken = cursor.text.slice(this._firstIndex, this._firstIndex + this._token.length);
666
+ const length = Math.min(token.length, compareToToken.length);
667
+ for (let i = 0; i < length; i++) {
668
+ if (token[i] !== compareToToken[i]) {
669
+ this._lastIndex = this._firstIndex + i;
670
+ cursor.moveTo(this._lastIndex);
671
+ return false;
647
672
  }
648
- cursor.next();
649
673
  }
650
- return passed;
674
+ if (token != compareToToken) {
675
+ this._lastIndex = this._firstIndex + compareToToken.length - 1;
676
+ cursor.moveTo(this._lastIndex);
677
+ return false;
678
+ }
679
+ this._lastIndex = this._firstIndex + this._token.length - 1;
680
+ cursor.moveTo(this._lastIndex);
681
+ return true;
651
682
  }
652
683
  _createNode() {
653
684
  return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._token);
@@ -726,7 +757,7 @@ class Regex {
726
757
  this._name = name;
727
758
  this._parent = null;
728
759
  this._originalRegexString = regex;
729
- this._regex = new RegExp(`^${regex}`, "g");
760
+ this._regex = new RegExp(`^${regex}`, "gu");
730
761
  this.assertArguments();
731
762
  }
732
763
  assertArguments() {
@@ -755,7 +786,7 @@ class Regex {
755
786
  resetState(cursor) {
756
787
  this._cursor = cursor;
757
788
  this._regex.lastIndex = 0;
758
- this._substring = this._cursor.text.substr(this._cursor.index);
789
+ this._substring = this._cursor.text.slice(this._cursor.index);
759
790
  this._node = null;
760
791
  }
761
792
  tryToParse(cursor) {
@@ -770,10 +801,9 @@ class Regex {
770
801
  processResult(cursor, result) {
771
802
  const currentIndex = cursor.index;
772
803
  const match = result[0];
773
- const matchLength = [...match].length;
774
- const newIndex = currentIndex + matchLength - 1;
775
- this._node = new Node("regex", this._name, currentIndex, newIndex, undefined, result[0]);
776
- cursor.moveTo(newIndex);
804
+ const lastIndex = cursor.getCharLastIndex(currentIndex + match.length - 1);
805
+ this._node = new Node("regex", this._name, currentIndex, lastIndex, undefined, result[0]);
806
+ cursor.moveTo(lastIndex);
777
807
  cursor.recordMatch(this, this._node);
778
808
  }
779
809
  processError(cursor) {
@@ -3301,7 +3331,7 @@ class TakeUntil {
3301
3331
  }
3302
3332
  if (foundMatch) {
3303
3333
  cursor.moveTo(cursorIndex - 1);
3304
- const value = cursor.getChars(this.startedOnIndex, cursorIndex - 1);
3334
+ const value = cursor.substring(this.startedOnIndex, cursorIndex - 1);
3305
3335
  const node = Node.createValueNode(this._type, this._name, value);
3306
3336
  cursor.recordMatch(this, node);
3307
3337
  return node;
@@ -3453,7 +3483,7 @@ function generateErrorMessage(pattern, cursor) {
3453
3483
  }
3454
3484
  const lastPattern = furthestMatch.pattern;
3455
3485
  const suggestions = cleanSuggestions(lastPattern.getNextTokens());
3456
- const strUpToError = cursor.getChars(0, endIndex);
3486
+ const strUpToError = cursor.substring(0, endIndex);
3457
3487
  const lines = strUpToError.split("\n");
3458
3488
  const lastLine = lines[lines.length - 1];
3459
3489
  const line = lines.length;
@@ -4191,9 +4221,9 @@ class AutoComplete {
4191
4221
  }
4192
4222
  _createSuggestionOptionsFromErrors() {
4193
4223
  // These errored because the length of the string.
4194
- const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length);
4224
+ const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length - 1);
4195
4225
  const errorSuggestionOptions = errors.map(parseError => {
4196
- const currentText = this._cursor.getChars(parseError.startIndex, parseError.lastIndex);
4226
+ const currentText = this._cursor.substring(parseError.startIndex, parseError.lastIndex);
4197
4227
  const compositeSuggestions = this._getCompositeSuggestionsForPattern(parseError.pattern);
4198
4228
  const trimmedErrorCompositeSuggestions = this._trimSuggestionsByExistingText(currentText, compositeSuggestions);
4199
4229
  return this._createSuggestions(parseError.lastIndex, trimmedErrorCompositeSuggestions);
@@ -4249,7 +4279,7 @@ class AutoComplete {
4249
4279
  * ie. sequence pattern segments ≈ [{look}, {an example}, {phrase}]
4250
4280
  * fullText = "look an"
4251
4281
  * remove {look} segment as its already been completed by the existing text.
4252
- */
4282
+ */
4253
4283
  _filterCompletedSubSegments(currentText, compositeSuggestion) {
4254
4284
  let elementsToRemove = [];
4255
4285
  let workingText = currentText;
@@ -4352,7 +4382,7 @@ class AutoComplete {
4352
4382
  return unique;
4353
4383
  }
4354
4384
  _createSuggestions(lastIndex, compositeSuggestionList) {
4355
- let textToIndex = lastIndex === -1 ? "" : this._cursor.getChars(0, lastIndex);
4385
+ let textToIndex = lastIndex === -1 ? "" : this._cursor.substring(0, lastIndex);
4356
4386
  const options = [];
4357
4387
  for (const compositeSuggestion of compositeSuggestionList) {
4358
4388
  // concatenated for start index identification inside createSuggestion