@hyperfixi/core 2.0.0 → 2.2.0

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.
Files changed (76) hide show
  1. package/dist/api/hyperscript-api.d.ts +8 -1
  2. package/dist/ast-utils/index.d.ts +1 -1
  3. package/dist/ast-utils/index.js +11 -1
  4. package/dist/ast-utils/index.mjs +11 -1
  5. package/dist/ast-utils/interchange/index.d.ts +1 -1
  6. package/dist/ast-utils/interchange/lsp.d.ts +4 -1
  7. package/dist/behaviors/index.js +13 -5
  8. package/dist/behaviors/index.mjs +13 -5
  9. package/dist/bundle-generator/index.js +9 -0
  10. package/dist/bundle-generator/index.mjs +9 -0
  11. package/dist/chunks/{bridge-I6ceoWxV.js → bridge-D2DBo02Z.js} +2 -2
  12. package/dist/chunks/browser-modular-BA3JFmkq.js +2 -0
  13. package/dist/chunks/feature-eventsource-B5F2-H1r.js +2 -0
  14. package/dist/chunks/feature-sockets-ClOH7vk7.js +2 -0
  15. package/dist/chunks/feature-webworker-3bAp0ac9.js +2 -0
  16. package/dist/chunks/index-C6Fn0jGB.js +2 -0
  17. package/dist/commands/dom/toggle.d.ts +2 -0
  18. package/dist/commands/index.js +62 -6
  19. package/dist/commands/index.mjs +62 -6
  20. package/dist/debug/debug-controller.d.ts +62 -0
  21. package/dist/debug/index.d.ts +5 -0
  22. package/dist/expressions/index.js +16 -79
  23. package/dist/expressions/index.mjs +16 -79
  24. package/dist/hyperfixi-classic-i18n.js +1 -1
  25. package/dist/hyperfixi-hx.js +1 -1
  26. package/dist/hyperfixi-hybrid-complete.js +1 -1
  27. package/dist/hyperfixi-minimal.js +1 -1
  28. package/dist/hyperfixi-multilingual.js +1 -1
  29. package/dist/hyperfixi-standard.js +1 -1
  30. package/dist/hyperfixi.js +1 -1
  31. package/dist/hyperfixi.mjs +1 -1
  32. package/dist/i18n/error-catalog.d.ts +12 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +35334 -24306
  35. package/dist/index.min.js +1 -1
  36. package/dist/index.mjs +35333 -24307
  37. package/dist/lokascript-browser-classic-i18n.js +1 -1
  38. package/dist/lokascript-browser-minimal.js +1 -1
  39. package/dist/lokascript-browser-standard.js +1 -1
  40. package/dist/lokascript-browser.js +1 -1
  41. package/dist/lokascript-hybrid-complete.js +1 -1
  42. package/dist/lokascript-hybrid-hx.js +1 -1
  43. package/dist/lokascript-multilingual.js +1 -1
  44. package/dist/lse/index.d.ts +15 -0
  45. package/dist/lse/index.js +84 -0
  46. package/dist/lse/index.mjs +71 -0
  47. package/dist/metadata.d.ts +4 -4
  48. package/dist/metadata.js +4 -4
  49. package/dist/metadata.mjs +4 -4
  50. package/dist/parser/full-parser.js +608 -271
  51. package/dist/parser/full-parser.mjs +608 -271
  52. package/dist/parser/helpers/ast-helpers.d.ts +1 -0
  53. package/dist/parser/hybrid/index.js +35 -2
  54. package/dist/parser/hybrid/index.mjs +35 -2
  55. package/dist/parser/hybrid/parser-core.d.ts +1 -0
  56. package/dist/parser/hybrid/parser-core.js +35 -2
  57. package/dist/parser/hybrid/parser-core.mjs +35 -2
  58. package/dist/parser/hybrid/tokenizer.js +5 -0
  59. package/dist/parser/hybrid/tokenizer.mjs +5 -0
  60. package/dist/parser/hybrid-parser.js +35 -2
  61. package/dist/parser/hybrid-parser.mjs +35 -2
  62. package/dist/parser/parser-types.d.ts +22 -7
  63. package/dist/parser/parser.d.ts +7 -0
  64. package/dist/parser/pratt-parser.d.ts +42 -0
  65. package/dist/parser/token-consumer.d.ts +1 -2
  66. package/dist/parser/tokenizer.d.ts +0 -33
  67. package/dist/registry/index.js +16 -79
  68. package/dist/registry/index.mjs +16 -79
  69. package/dist/runtime/runtime-base.d.ts +4 -0
  70. package/dist/types/base-types.d.ts +11 -0
  71. package/dist/types/core.d.ts +1 -0
  72. package/package.json +15 -6
  73. package/dist/chunks/browser-modular-Dv6PAV3c.js +0 -2
  74. package/dist/chunks/feature-eventsource-DWb514fy.js +0 -2
  75. package/dist/chunks/feature-sockets-3PFuvCVY.js +0 -2
  76. package/dist/chunks/feature-webworker-DTm_eh-E.js +0 -2
@@ -18,5 +18,6 @@ export declare function createArrayLiteral(elements: ASTNode[], pos: Position):
18
18
  export declare function createPropertyOfExpression(property: ASTNode, target: ASTNode, pos: Position): PropertyOfExpressionNode;
19
19
  export declare function createCommandSequence(commands: ASTNode[]): CommandSequenceNode;
20
20
  export declare function createErrorNode(pos: Position): IdentifierNode;
21
+ export declare function createErrorCommandNode(pos: Position, message: string, source?: string): ASTNode;
21
22
  export declare function createProgramNode(statements: ASTNode[]): ASTNode;
22
23
  //# sourceMappingURL=ast-helpers.d.ts.map
@@ -78,6 +78,11 @@ const KEYWORDS = new Set([
78
78
  'init',
79
79
  'every',
80
80
  'by',
81
+ 'halt',
82
+ 'via',
83
+ 'values',
84
+ 'default',
85
+ 'event',
81
86
  ]);
82
87
  function tokenize(code) {
83
88
  const tokens = [];
@@ -403,6 +408,7 @@ class HybridParser {
403
408
  go: () => this.parseGo(),
404
409
  return: () => this.parseReturn(),
405
410
  transition: () => this.parseTransition(),
411
+ halt: () => this.parseHalt(),
406
412
  };
407
413
  const normalized = normalizeCommand(this.peek().value);
408
414
  if (cmdMap[normalized]) {
@@ -470,11 +476,17 @@ class HybridParser {
470
476
  const url = this.parseExpression();
471
477
  let responseType = { type: 'literal', value: 'text' };
472
478
  let options;
479
+ let method;
473
480
  if (this.match('{')) {
474
481
  this.pos--;
475
482
  options = this.parseExpression();
476
483
  }
477
- for (let i = 0; i < 2; i++) {
484
+ for (let i = 0; i < 3; i++) {
485
+ if (this.match('via') && !method) {
486
+ this.advance();
487
+ method = this.parseExpression();
488
+ continue;
489
+ }
478
490
  if (this.match('as')) {
479
491
  this.advance();
480
492
  if (this.match('a') || this.match('an'))
@@ -492,7 +504,11 @@ class HybridParser {
492
504
  if (this.match('then'))
493
505
  this.advance();
494
506
  const body = this.parseCommandSequence();
495
- return { type: 'fetch', condition: { type: 'fetchConfig', url, responseType, options }, body };
507
+ return {
508
+ type: 'fetch',
509
+ condition: { type: 'fetchConfig', url, responseType, options, method },
510
+ body,
511
+ };
496
512
  }
497
513
  parseToggle() {
498
514
  this.expect('toggle');
@@ -683,6 +699,14 @@ class HybridParser {
683
699
  }
684
700
  return { type: 'command', name: 'return', args: value ? [value] : [] };
685
701
  }
702
+ parseHalt() {
703
+ this.expect('halt');
704
+ if (this.match('the'))
705
+ this.advance();
706
+ if (this.match('event', 'default'))
707
+ this.advance();
708
+ return { type: 'command', name: 'halt', args: [] };
709
+ }
686
710
  parseTransition() {
687
711
  this.expect('transition');
688
712
  let target;
@@ -959,6 +983,15 @@ class HybridParser {
959
983
  const target = this.parsePositionalTarget();
960
984
  return { type: 'positional', position, target };
961
985
  }
986
+ if (this.match('values')) {
987
+ this.advance();
988
+ if (this.match('of')) {
989
+ this.advance();
990
+ const target = this.parseExpression();
991
+ return { type: 'valuesOf', target };
992
+ }
993
+ return { type: 'identifier', value: token.value };
994
+ }
962
995
  if (token.type === 'identifier' || token.type === 'keyword') {
963
996
  this.advance();
964
997
  return { type: 'identifier', value: token.value };
@@ -76,6 +76,11 @@ const KEYWORDS = new Set([
76
76
  'init',
77
77
  'every',
78
78
  'by',
79
+ 'halt',
80
+ 'via',
81
+ 'values',
82
+ 'default',
83
+ 'event',
79
84
  ]);
80
85
  function tokenize(code) {
81
86
  const tokens = [];
@@ -401,6 +406,7 @@ class HybridParser {
401
406
  go: () => this.parseGo(),
402
407
  return: () => this.parseReturn(),
403
408
  transition: () => this.parseTransition(),
409
+ halt: () => this.parseHalt(),
404
410
  };
405
411
  const normalized = normalizeCommand(this.peek().value);
406
412
  if (cmdMap[normalized]) {
@@ -468,11 +474,17 @@ class HybridParser {
468
474
  const url = this.parseExpression();
469
475
  let responseType = { type: 'literal', value: 'text' };
470
476
  let options;
477
+ let method;
471
478
  if (this.match('{')) {
472
479
  this.pos--;
473
480
  options = this.parseExpression();
474
481
  }
475
- for (let i = 0; i < 2; i++) {
482
+ for (let i = 0; i < 3; i++) {
483
+ if (this.match('via') && !method) {
484
+ this.advance();
485
+ method = this.parseExpression();
486
+ continue;
487
+ }
476
488
  if (this.match('as')) {
477
489
  this.advance();
478
490
  if (this.match('a') || this.match('an'))
@@ -490,7 +502,11 @@ class HybridParser {
490
502
  if (this.match('then'))
491
503
  this.advance();
492
504
  const body = this.parseCommandSequence();
493
- return { type: 'fetch', condition: { type: 'fetchConfig', url, responseType, options }, body };
505
+ return {
506
+ type: 'fetch',
507
+ condition: { type: 'fetchConfig', url, responseType, options, method },
508
+ body,
509
+ };
494
510
  }
495
511
  parseToggle() {
496
512
  this.expect('toggle');
@@ -681,6 +697,14 @@ class HybridParser {
681
697
  }
682
698
  return { type: 'command', name: 'return', args: value ? [value] : [] };
683
699
  }
700
+ parseHalt() {
701
+ this.expect('halt');
702
+ if (this.match('the'))
703
+ this.advance();
704
+ if (this.match('event', 'default'))
705
+ this.advance();
706
+ return { type: 'command', name: 'halt', args: [] };
707
+ }
684
708
  parseTransition() {
685
709
  this.expect('transition');
686
710
  let target;
@@ -957,6 +981,15 @@ class HybridParser {
957
981
  const target = this.parsePositionalTarget();
958
982
  return { type: 'positional', position, target };
959
983
  }
984
+ if (this.match('values')) {
985
+ this.advance();
986
+ if (this.match('of')) {
987
+ this.advance();
988
+ const target = this.parseExpression();
989
+ return { type: 'valuesOf', target };
990
+ }
991
+ return { type: 'identifier', value: token.value };
992
+ }
960
993
  if (token.type === 'identifier' || token.type === 'keyword') {
961
994
  this.advance();
962
995
  return { type: 'identifier', value: token.value };
@@ -37,6 +37,7 @@ export declare class HybridParser {
37
37
  private parseFocusBlur;
38
38
  private parseGo;
39
39
  private parseReturn;
40
+ private parseHalt;
40
41
  private parseTransition;
41
42
  private parseTransitionRest;
42
43
  private parseExpression;
@@ -78,6 +78,11 @@ const KEYWORDS = new Set([
78
78
  'init',
79
79
  'every',
80
80
  'by',
81
+ 'halt',
82
+ 'via',
83
+ 'values',
84
+ 'default',
85
+ 'event',
81
86
  ]);
82
87
  function tokenize(code) {
83
88
  const tokens = [];
@@ -397,6 +402,7 @@ class HybridParser {
397
402
  go: () => this.parseGo(),
398
403
  return: () => this.parseReturn(),
399
404
  transition: () => this.parseTransition(),
405
+ halt: () => this.parseHalt(),
400
406
  };
401
407
  const normalized = normalizeCommand(this.peek().value);
402
408
  if (cmdMap[normalized]) {
@@ -464,11 +470,17 @@ class HybridParser {
464
470
  const url = this.parseExpression();
465
471
  let responseType = { type: 'literal', value: 'text' };
466
472
  let options;
473
+ let method;
467
474
  if (this.match('{')) {
468
475
  this.pos--;
469
476
  options = this.parseExpression();
470
477
  }
471
- for (let i = 0; i < 2; i++) {
478
+ for (let i = 0; i < 3; i++) {
479
+ if (this.match('via') && !method) {
480
+ this.advance();
481
+ method = this.parseExpression();
482
+ continue;
483
+ }
472
484
  if (this.match('as')) {
473
485
  this.advance();
474
486
  if (this.match('a') || this.match('an'))
@@ -486,7 +498,11 @@ class HybridParser {
486
498
  if (this.match('then'))
487
499
  this.advance();
488
500
  const body = this.parseCommandSequence();
489
- return { type: 'fetch', condition: { type: 'fetchConfig', url, responseType, options }, body };
501
+ return {
502
+ type: 'fetch',
503
+ condition: { type: 'fetchConfig', url, responseType, options, method },
504
+ body,
505
+ };
490
506
  }
491
507
  parseToggle() {
492
508
  this.expect('toggle');
@@ -677,6 +693,14 @@ class HybridParser {
677
693
  }
678
694
  return { type: 'command', name: 'return', args: value ? [value] : [] };
679
695
  }
696
+ parseHalt() {
697
+ this.expect('halt');
698
+ if (this.match('the'))
699
+ this.advance();
700
+ if (this.match('event', 'default'))
701
+ this.advance();
702
+ return { type: 'command', name: 'halt', args: [] };
703
+ }
680
704
  parseTransition() {
681
705
  this.expect('transition');
682
706
  let target;
@@ -953,6 +977,15 @@ class HybridParser {
953
977
  const target = this.parsePositionalTarget();
954
978
  return { type: 'positional', position, target };
955
979
  }
980
+ if (this.match('values')) {
981
+ this.advance();
982
+ if (this.match('of')) {
983
+ this.advance();
984
+ const target = this.parseExpression();
985
+ return { type: 'valuesOf', target };
986
+ }
987
+ return { type: 'identifier', value: token.value };
988
+ }
956
989
  if (token.type === 'identifier' || token.type === 'keyword') {
957
990
  this.advance();
958
991
  return { type: 'identifier', value: token.value };
@@ -76,6 +76,11 @@ const KEYWORDS = new Set([
76
76
  'init',
77
77
  'every',
78
78
  'by',
79
+ 'halt',
80
+ 'via',
81
+ 'values',
82
+ 'default',
83
+ 'event',
79
84
  ]);
80
85
  function tokenize(code) {
81
86
  const tokens = [];
@@ -395,6 +400,7 @@ class HybridParser {
395
400
  go: () => this.parseGo(),
396
401
  return: () => this.parseReturn(),
397
402
  transition: () => this.parseTransition(),
403
+ halt: () => this.parseHalt(),
398
404
  };
399
405
  const normalized = normalizeCommand(this.peek().value);
400
406
  if (cmdMap[normalized]) {
@@ -462,11 +468,17 @@ class HybridParser {
462
468
  const url = this.parseExpression();
463
469
  let responseType = { type: 'literal', value: 'text' };
464
470
  let options;
471
+ let method;
465
472
  if (this.match('{')) {
466
473
  this.pos--;
467
474
  options = this.parseExpression();
468
475
  }
469
- for (let i = 0; i < 2; i++) {
476
+ for (let i = 0; i < 3; i++) {
477
+ if (this.match('via') && !method) {
478
+ this.advance();
479
+ method = this.parseExpression();
480
+ continue;
481
+ }
470
482
  if (this.match('as')) {
471
483
  this.advance();
472
484
  if (this.match('a') || this.match('an'))
@@ -484,7 +496,11 @@ class HybridParser {
484
496
  if (this.match('then'))
485
497
  this.advance();
486
498
  const body = this.parseCommandSequence();
487
- return { type: 'fetch', condition: { type: 'fetchConfig', url, responseType, options }, body };
499
+ return {
500
+ type: 'fetch',
501
+ condition: { type: 'fetchConfig', url, responseType, options, method },
502
+ body,
503
+ };
488
504
  }
489
505
  parseToggle() {
490
506
  this.expect('toggle');
@@ -675,6 +691,14 @@ class HybridParser {
675
691
  }
676
692
  return { type: 'command', name: 'return', args: value ? [value] : [] };
677
693
  }
694
+ parseHalt() {
695
+ this.expect('halt');
696
+ if (this.match('the'))
697
+ this.advance();
698
+ if (this.match('event', 'default'))
699
+ this.advance();
700
+ return { type: 'command', name: 'halt', args: [] };
701
+ }
678
702
  parseTransition() {
679
703
  this.expect('transition');
680
704
  let target;
@@ -951,6 +975,15 @@ class HybridParser {
951
975
  const target = this.parsePositionalTarget();
952
976
  return { type: 'positional', position, target };
953
977
  }
978
+ if (this.match('values')) {
979
+ this.advance();
980
+ if (this.match('of')) {
981
+ this.advance();
982
+ const target = this.parseExpression();
983
+ return { type: 'valuesOf', target };
984
+ }
985
+ return { type: 'identifier', value: token.value };
986
+ }
954
987
  if (token.type === 'identifier' || token.type === 'keyword') {
955
988
  this.advance();
956
989
  return { type: 'identifier', value: token.value };
@@ -78,6 +78,11 @@ const KEYWORDS = new Set([
78
78
  'init',
79
79
  'every',
80
80
  'by',
81
+ 'halt',
82
+ 'via',
83
+ 'values',
84
+ 'default',
85
+ 'event',
81
86
  ]);
82
87
  function tokenize(code) {
83
88
  const tokens = [];
@@ -76,6 +76,11 @@ const KEYWORDS = new Set([
76
76
  'init',
77
77
  'every',
78
78
  'by',
79
+ 'halt',
80
+ 'via',
81
+ 'values',
82
+ 'default',
83
+ 'event',
79
84
  ]);
80
85
  function tokenize(code) {
81
86
  const tokens = [];
@@ -78,6 +78,11 @@ const KEYWORDS = new Set([
78
78
  'init',
79
79
  'every',
80
80
  'by',
81
+ 'halt',
82
+ 'via',
83
+ 'values',
84
+ 'default',
85
+ 'event',
81
86
  ]);
82
87
  function tokenize(code) {
83
88
  const tokens = [];
@@ -403,6 +408,7 @@ class HybridParser {
403
408
  go: () => this.parseGo(),
404
409
  return: () => this.parseReturn(),
405
410
  transition: () => this.parseTransition(),
411
+ halt: () => this.parseHalt(),
406
412
  };
407
413
  const normalized = normalizeCommand(this.peek().value);
408
414
  if (cmdMap[normalized]) {
@@ -470,11 +476,17 @@ class HybridParser {
470
476
  const url = this.parseExpression();
471
477
  let responseType = { type: 'literal', value: 'text' };
472
478
  let options;
479
+ let method;
473
480
  if (this.match('{')) {
474
481
  this.pos--;
475
482
  options = this.parseExpression();
476
483
  }
477
- for (let i = 0; i < 2; i++) {
484
+ for (let i = 0; i < 3; i++) {
485
+ if (this.match('via') && !method) {
486
+ this.advance();
487
+ method = this.parseExpression();
488
+ continue;
489
+ }
478
490
  if (this.match('as')) {
479
491
  this.advance();
480
492
  if (this.match('a') || this.match('an'))
@@ -492,7 +504,11 @@ class HybridParser {
492
504
  if (this.match('then'))
493
505
  this.advance();
494
506
  const body = this.parseCommandSequence();
495
- return { type: 'fetch', condition: { type: 'fetchConfig', url, responseType, options }, body };
507
+ return {
508
+ type: 'fetch',
509
+ condition: { type: 'fetchConfig', url, responseType, options, method },
510
+ body,
511
+ };
496
512
  }
497
513
  parseToggle() {
498
514
  this.expect('toggle');
@@ -683,6 +699,14 @@ class HybridParser {
683
699
  }
684
700
  return { type: 'command', name: 'return', args: value ? [value] : [] };
685
701
  }
702
+ parseHalt() {
703
+ this.expect('halt');
704
+ if (this.match('the'))
705
+ this.advance();
706
+ if (this.match('event', 'default'))
707
+ this.advance();
708
+ return { type: 'command', name: 'halt', args: [] };
709
+ }
686
710
  parseTransition() {
687
711
  this.expect('transition');
688
712
  let target;
@@ -959,6 +983,15 @@ class HybridParser {
959
983
  const target = this.parsePositionalTarget();
960
984
  return { type: 'positional', position, target };
961
985
  }
986
+ if (this.match('values')) {
987
+ this.advance();
988
+ if (this.match('of')) {
989
+ this.advance();
990
+ const target = this.parseExpression();
991
+ return { type: 'valuesOf', target };
992
+ }
993
+ return { type: 'identifier', value: token.value };
994
+ }
962
995
  if (token.type === 'identifier' || token.type === 'keyword') {
963
996
  this.advance();
964
997
  return { type: 'identifier', value: token.value };
@@ -76,6 +76,11 @@ const KEYWORDS = new Set([
76
76
  'init',
77
77
  'every',
78
78
  'by',
79
+ 'halt',
80
+ 'via',
81
+ 'values',
82
+ 'default',
83
+ 'event',
79
84
  ]);
80
85
  function tokenize(code) {
81
86
  const tokens = [];
@@ -401,6 +406,7 @@ class HybridParser {
401
406
  go: () => this.parseGo(),
402
407
  return: () => this.parseReturn(),
403
408
  transition: () => this.parseTransition(),
409
+ halt: () => this.parseHalt(),
404
410
  };
405
411
  const normalized = normalizeCommand(this.peek().value);
406
412
  if (cmdMap[normalized]) {
@@ -468,11 +474,17 @@ class HybridParser {
468
474
  const url = this.parseExpression();
469
475
  let responseType = { type: 'literal', value: 'text' };
470
476
  let options;
477
+ let method;
471
478
  if (this.match('{')) {
472
479
  this.pos--;
473
480
  options = this.parseExpression();
474
481
  }
475
- for (let i = 0; i < 2; i++) {
482
+ for (let i = 0; i < 3; i++) {
483
+ if (this.match('via') && !method) {
484
+ this.advance();
485
+ method = this.parseExpression();
486
+ continue;
487
+ }
476
488
  if (this.match('as')) {
477
489
  this.advance();
478
490
  if (this.match('a') || this.match('an'))
@@ -490,7 +502,11 @@ class HybridParser {
490
502
  if (this.match('then'))
491
503
  this.advance();
492
504
  const body = this.parseCommandSequence();
493
- return { type: 'fetch', condition: { type: 'fetchConfig', url, responseType, options }, body };
505
+ return {
506
+ type: 'fetch',
507
+ condition: { type: 'fetchConfig', url, responseType, options, method },
508
+ body,
509
+ };
494
510
  }
495
511
  parseToggle() {
496
512
  this.expect('toggle');
@@ -681,6 +697,14 @@ class HybridParser {
681
697
  }
682
698
  return { type: 'command', name: 'return', args: value ? [value] : [] };
683
699
  }
700
+ parseHalt() {
701
+ this.expect('halt');
702
+ if (this.match('the'))
703
+ this.advance();
704
+ if (this.match('event', 'default'))
705
+ this.advance();
706
+ return { type: 'command', name: 'halt', args: [] };
707
+ }
684
708
  parseTransition() {
685
709
  this.expect('transition');
686
710
  let target;
@@ -957,6 +981,15 @@ class HybridParser {
957
981
  const target = this.parsePositionalTarget();
958
982
  return { type: 'positional', position, target };
959
983
  }
984
+ if (this.match('values')) {
985
+ this.advance();
986
+ if (this.match('of')) {
987
+ this.advance();
988
+ const target = this.parseExpression();
989
+ return { type: 'valuesOf', target };
990
+ }
991
+ return { type: 'identifier', value: token.value };
992
+ }
960
993
  if (token.type === 'identifier' || token.type === 'keyword') {
961
994
  this.advance();
962
995
  return { type: 'identifier', value: token.value };
@@ -1,5 +1,4 @@
1
1
  import type { Token, ASTNode, CommandNode } from '../types/core';
2
- import { TokenType } from './tokenizer';
3
2
  export interface Position {
4
3
  start: number;
5
4
  end: number;
@@ -86,14 +85,20 @@ export interface MultiWordPattern {
86
85
  minArgs?: number;
87
86
  maxArgs?: number;
88
87
  }
89
- export interface ParserContext {
88
+ export interface TokenStream {
90
89
  readonly tokens: Token[];
91
90
  current: number;
92
91
  advance(): Token;
93
92
  peek(): Token;
94
93
  previous(): Token;
95
- consume(expected: string | TokenType, message: string): Token;
94
+ consume(expected: string, message: string): Token;
96
95
  check(value: string): boolean;
96
+ match(...types: string[]): boolean;
97
+ matchOperator(operator: string): boolean;
98
+ isAtEnd(): boolean;
99
+ peekAt(offset: number): Token | null;
100
+ }
101
+ export interface TokenPredicates {
97
102
  checkIdentifierLike(): boolean;
98
103
  checkSelector(): boolean;
99
104
  checkAnySelector(): boolean;
@@ -103,9 +108,8 @@ export interface ParserContext {
103
108
  checkEvent(): boolean;
104
109
  checkIsCommand(): boolean;
105
110
  checkContextVar(): boolean;
106
- match(...types: Array<string | TokenType>): boolean;
107
- matchOperator(operator: string): boolean;
108
- isAtEnd(): boolean;
111
+ }
112
+ export interface ASTFactory {
109
113
  createIdentifier(name: string): IdentifierNode;
110
114
  createLiteral(value: unknown, raw: string): ASTNode;
111
115
  createSelector(value: string): ASTNode;
@@ -117,6 +121,8 @@ export interface ParserContext {
117
121
  createErrorNode(): ASTNode;
118
122
  createProgramNode(statements: ASTNode[]): ASTNode;
119
123
  createCommandFromIdentifier(identifierNode: IdentifierNode): CommandNode;
124
+ }
125
+ export interface ExpressionParser {
120
126
  parseExpression(): ASTNode;
121
127
  parsePrimary(): ASTNode;
122
128
  parseCall(): ASTNode;
@@ -139,15 +145,22 @@ export interface ParserContext {
139
145
  parseAttributeOrArrayLiteral(): ASTNode;
140
146
  parseObjectLiteral(): ASTNode;
141
147
  parseCSSObjectLiteral(): ASTNode;
148
+ }
149
+ export interface CommandParser {
142
150
  parseCommand(): CommandNode;
143
151
  parseCommandSequence(): ASTNode;
144
152
  parseCommandListUntilEnd(): ASTNode[];
153
+ }
154
+ export interface PositionCheckpoint {
145
155
  savePosition(): number;
146
156
  restorePosition(pos: number): void;
147
- peekAt(offset: number): Token | null;
148
157
  getPosition(): Position;
158
+ }
159
+ export interface ParserErrorHandler {
149
160
  addError(message: string): void;
150
161
  addWarning(warning: string): void;
162
+ }
163
+ export interface ParserUtilities {
151
164
  isCommand(name: string): boolean;
152
165
  isCompoundCommand(name: string): boolean;
153
166
  isKeyword(name: string): boolean;
@@ -155,6 +168,8 @@ export interface ParserContext {
155
168
  resolveKeyword(value: string): string;
156
169
  getInputSlice(start: number, end?: number): string;
157
170
  }
171
+ export interface ParserContext extends TokenStream, TokenPredicates, ASTFactory, ExpressionParser, CommandParser, PositionCheckpoint, ParserErrorHandler, ParserUtilities {
172
+ }
158
173
  export type CommandParserFunction = (token: Token, context: ParserContext) => CommandNode;
159
174
  export type CompoundCommandParserFunction = (identifierNode: IdentifierNode, context: ParserContext) => CommandNode | null;
160
175
  export type TokenNavigationFunction = (context: ParserContext) => Token | boolean;
@@ -6,17 +6,23 @@ export declare class Parser {
6
6
  private tokens;
7
7
  private current;
8
8
  private error;
9
+ private errors;
9
10
  private warnings;
10
11
  private keywordResolver?;
11
12
  private semanticAdapter?;
12
13
  private originalInput?;
13
14
  private registryIntegration?;
15
+ private prattCache;
14
16
  private static readonly POSTFIX_UNARY_OPERATORS;
15
17
  constructor(tokens: Token[], options?: ParserOptions, originalInput?: string);
16
18
  private resolveKeyword;
17
19
  private addWarning;
18
20
  parse(): ParseResult;
21
+ private parseInternal;
19
22
  private parseExpression;
23
+ private static readonly PRATT_TABLE;
24
+ private parseExpressionPratt;
25
+ private makePrattContext;
20
26
  private parseAssignment;
21
27
  private parseLogicalOr;
22
28
  private parseLogicalAnd;
@@ -138,6 +144,7 @@ export declare class Parser {
138
144
  private previous;
139
145
  private consume;
140
146
  private addError;
147
+ private synchronizeToCommandBoundary;
141
148
  private parseAttributeOrArrayLiteral;
142
149
  private getPosition;
143
150
  getContext(): import('./parser-types').ParserContext;