@hyperfixi/core 2.9.1 → 2.9.3

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 (49) hide show
  1. package/dist/bundle-generator/index.js +6 -0
  2. package/dist/bundle-generator/index.mjs +6 -0
  3. package/dist/bundle-generator/parser-templates.d.ts +1 -1
  4. package/dist/chunks/{bridge-BYhqTOnL.js → bridge-DwtNLKK3.js} +2 -2
  5. package/dist/chunks/browser-modular-6HT1r2AH.js +2 -0
  6. package/dist/chunks/{index-DXgJaDj-.js → index-B8jwvuj_.js} +2 -2
  7. package/dist/commands/index.js +133 -74
  8. package/dist/commands/index.mjs +133 -74
  9. package/dist/hyperfixi-browser-classic-i18n.js +1 -1
  10. package/dist/hyperfixi-browser-minimal.js +1 -1
  11. package/dist/hyperfixi-browser-standard.js +1 -1
  12. package/dist/hyperfixi-browser.js +1 -1
  13. package/dist/hyperfixi-classic-i18n.js +1 -1
  14. package/dist/hyperfixi-hx-v4.js +1 -1
  15. package/dist/hyperfixi-hx.js +1 -1
  16. package/dist/hyperfixi-hybrid-complete.js +1 -1
  17. package/dist/hyperfixi-hybrid-hx.js +1 -1
  18. package/dist/hyperfixi-minimal.js +1 -1
  19. package/dist/hyperfixi-multilingual.js +1 -1
  20. package/dist/hyperfixi-standard.js +1 -1
  21. package/dist/hyperfixi.js +1 -1
  22. package/dist/hyperfixi.mjs +1 -1
  23. package/dist/index.js +233 -79
  24. package/dist/index.min.js +1 -1
  25. package/dist/index.mjs +233 -79
  26. package/dist/lokascript-browser-classic-i18n.js +1 -1
  27. package/dist/lokascript-browser-minimal.js +1 -1
  28. package/dist/lokascript-browser-standard.js +1 -1
  29. package/dist/lokascript-browser.js +1 -1
  30. package/dist/lokascript-hybrid-complete.js +1 -1
  31. package/dist/lokascript-hybrid-hx.js +1 -1
  32. package/dist/lokascript-multilingual.js +1 -1
  33. package/dist/parser/command-parsers/utility-commands.d.ts +1 -1
  34. package/dist/parser/full-parser.js +133 -74
  35. package/dist/parser/full-parser.mjs +133 -74
  36. package/dist/parser/hybrid/index.js +3 -0
  37. package/dist/parser/hybrid/index.mjs +3 -0
  38. package/dist/parser/hybrid/parser-core.js +3 -0
  39. package/dist/parser/hybrid/parser-core.mjs +3 -0
  40. package/dist/parser/hybrid-parser.js +3 -0
  41. package/dist/parser/hybrid-parser.mjs +3 -0
  42. package/dist/reference/index.js +1 -0
  43. package/dist/reference/index.mjs +1 -0
  44. package/dist/registry/index.js +133 -74
  45. package/dist/registry/index.mjs +133 -74
  46. package/dist/runtime/runtime-base.d.ts +2 -1
  47. package/dist/types/core.d.ts +1 -0
  48. package/package.json +6 -6
  49. package/dist/chunks/browser-modular-D2BHzZFB.js +0 -2
@@ -6310,13 +6310,13 @@ function tokenize(input) {
6310
6310
  continue;
6311
6311
  }
6312
6312
  if (char === '{') {
6313
- addToken(tokenizer, TokenKind.OPERATOR, '{');
6314
6313
  advance(tokenizer);
6314
+ addToken(tokenizer, TokenKind.OPERATOR, '{');
6315
6315
  continue;
6316
6316
  }
6317
6317
  if (char === '}') {
6318
- addToken(tokenizer, TokenKind.OPERATOR, '}');
6319
6318
  advance(tokenizer);
6319
+ addToken(tokenizer, TokenKind.OPERATOR, '}');
6320
6320
  continue;
6321
6321
  }
6322
6322
  if (char === '[') {
@@ -6332,24 +6332,24 @@ function tokenize(input) {
6332
6332
  prevToken.value === ']') &&
6333
6333
  !isEventCondition;
6334
6334
  if (isMemberAccess) {
6335
- addToken(tokenizer, TokenKind.OPERATOR, '[');
6336
6335
  advance(tokenizer);
6336
+ addToken(tokenizer, TokenKind.OPERATOR, '[');
6337
6337
  }
6338
6338
  else {
6339
6339
  if (isEventCondition) {
6340
- addToken(tokenizer, TokenKind.SYMBOL, '[');
6341
6340
  advance(tokenizer);
6341
+ addToken(tokenizer, TokenKind.SYMBOL, '[');
6342
6342
  }
6343
6343
  else {
6344
- addToken(tokenizer, TokenKind.OPERATOR, '[');
6345
6344
  advance(tokenizer);
6345
+ addToken(tokenizer, TokenKind.OPERATOR, '[');
6346
6346
  }
6347
6347
  }
6348
6348
  continue;
6349
6349
  }
6350
6350
  if (char === ']') {
6351
- addToken(tokenizer, TokenKind.OPERATOR, ']');
6352
6351
  advance(tokenizer);
6352
+ addToken(tokenizer, TokenKind.OPERATOR, ']');
6353
6353
  continue;
6354
6354
  }
6355
6355
  if (char === '$') {
@@ -7978,7 +7978,6 @@ const MULTI_WORD_PATTERNS = [
7978
7978
  keywords: ['a', 'an', 'from', 'called'],
7979
7979
  syntax: 'make (a|an) <type> [from <args>] [called <name>]',
7980
7980
  },
7981
- { command: 'send', keywords: ['to'], syntax: 'send <event> to <target>' },
7982
7981
  { command: 'throw', keywords: [], syntax: 'throw <error>' },
7983
7982
  ];
7984
7983
  function getMultiWordPattern(commandName) {
@@ -8279,7 +8278,13 @@ function parseTriggerCommand(ctx, identifierNode) {
8279
8278
  finalArgs.push(ctx.createIdentifier(keyword));
8280
8279
  continue;
8281
8280
  }
8282
- finalArgs.push(ctx.parsePrimary());
8281
+ const before = ctx.savePosition();
8282
+ const expr = ctx.parsePrimary();
8283
+ if (expr)
8284
+ finalArgs.push(expr);
8285
+ if (ctx.savePosition() === before) {
8286
+ ctx.advance();
8287
+ }
8283
8288
  }
8284
8289
  return CommandNodeBuilder.fromIdentifier(identifierNode)
8285
8290
  .withArgs(...finalArgs)
@@ -8498,11 +8503,64 @@ function parseRepeatCommand(ctx, commandToken) {
8498
8503
  }
8499
8504
  return builder.endingAt(ctx.getPosition()).build();
8500
8505
  }
8506
+ function parseIfBranchCommands(ctx, stopAtElse) {
8507
+ const commands = [];
8508
+ const atTerminator = () => ctx.check(KEYWORDS$1.END) || (stopAtElse && ctx.check(KEYWORDS$1.ELSE));
8509
+ while (!ctx.isAtEnd() && !atTerminator()) {
8510
+ if (isComment(ctx.peek())) {
8511
+ ctx.advance();
8512
+ continue;
8513
+ }
8514
+ if (!ctx.checkIsCommand() && !ctx.isCommand(ctx.peek().value))
8515
+ break;
8516
+ ctx.advance();
8517
+ const cmd = ctx.parseCommand();
8518
+ if (cmd) {
8519
+ commands.push(cmd);
8520
+ }
8521
+ if (ctx.check(KEYWORDS$1.THEN) || ctx.check(KEYWORDS$1.AND) || ctx.check(',')) {
8522
+ ctx.advance();
8523
+ }
8524
+ }
8525
+ return commands;
8526
+ }
8527
+ const OPERAND_INTRODUCERS = new Set([
8528
+ 'is',
8529
+ 'am',
8530
+ 'are',
8531
+ 'not',
8532
+ 'no',
8533
+ 'and',
8534
+ 'or',
8535
+ '==',
8536
+ '===',
8537
+ '!=',
8538
+ '!==',
8539
+ '<',
8540
+ '>',
8541
+ '<=',
8542
+ '>=',
8543
+ '+',
8544
+ '-',
8545
+ '*',
8546
+ '/',
8547
+ 'mod',
8548
+ ]);
8549
+ function isBodyCommandStart(ctx, prevToken, token) {
8550
+ if (prevToken === null) {
8551
+ return false;
8552
+ }
8553
+ if (OPERAND_INTRODUCERS.has(prevToken.value?.toLowerCase?.() ?? '')) {
8554
+ return false;
8555
+ }
8556
+ return ctx.checkIsCommand() || ctx.isCommand(token.value?.toLowerCase());
8557
+ }
8501
8558
  function parseIfCommand(ctx, commandToken) {
8502
8559
  const args = [];
8503
8560
  let hasThen = false;
8504
8561
  const savedPosForThen = ctx.savePosition();
8505
8562
  const maxThenLookahead = 500;
8563
+ let prevForThen = null;
8506
8564
  for (let i = 0; i < maxThenLookahead && !ctx.isAtEnd(); i++) {
8507
8565
  const token = ctx.peek();
8508
8566
  if (token.value === KEYWORDS$1.THEN) {
@@ -8515,6 +8573,14 @@ function parseIfCommand(ctx, commandToken) {
8515
8573
  token.value === KEYWORDS$1.ON) {
8516
8574
  break;
8517
8575
  }
8576
+ if (token.line !== undefined &&
8577
+ token.line !== commandToken.line &&
8578
+ isBodyCommandStart(ctx, prevForThen, token)) {
8579
+ break;
8580
+ }
8581
+ if (!isComment(token)) {
8582
+ prevForThen = token;
8583
+ }
8518
8584
  ctx.advance();
8519
8585
  }
8520
8586
  ctx.restorePosition(savedPosForThen);
@@ -8523,9 +8589,14 @@ function parseIfCommand(ctx, commandToken) {
8523
8589
  const savedPosition = ctx.savePosition();
8524
8590
  const ifStatementLine = commandToken.line;
8525
8591
  const maxLookahead = 100;
8592
+ let firstCommandOnIfLine = false;
8593
+ let prevToken = null;
8526
8594
  while (!ctx.isAtEnd() && ctx.current - savedPosition < maxLookahead) {
8527
8595
  const token = ctx.peek();
8528
8596
  const tokenValue = token.value?.toLowerCase();
8597
+ if (firstCommandOnIfLine && token.line !== undefined && token.line !== ifStatementLine) {
8598
+ break;
8599
+ }
8529
8600
  if (tokenValue === KEYWORDS$1.BEHAVIOR ||
8530
8601
  tokenValue === KEYWORDS$1.DEF ||
8531
8602
  tokenValue === KEYWORDS$1.ON) {
@@ -8537,11 +8608,15 @@ function parseIfCommand(ctx, commandToken) {
8537
8608
  }
8538
8609
  break;
8539
8610
  }
8540
- if (ctx.checkIsCommand() || ctx.isCommand(tokenValue)) {
8611
+ if (isBodyCommandStart(ctx, prevToken, token)) {
8541
8612
  if (token.line !== undefined && token.line !== ifStatementLine) {
8542
8613
  hasImplicitMultiLineEnd = true;
8543
8614
  break;
8544
8615
  }
8616
+ firstCommandOnIfLine = true;
8617
+ }
8618
+ if (!isComment(token)) {
8619
+ prevToken = token;
8545
8620
  }
8546
8621
  ctx.advance();
8547
8622
  }
@@ -8556,11 +8631,12 @@ function parseIfCommand(ctx, commandToken) {
8556
8631
  const conditionTokens = [];
8557
8632
  const maxIterations = 20;
8558
8633
  let iterations = 0;
8634
+ let firstConditionParse = true;
8559
8635
  while (!ctx.isAtEnd() &&
8560
- !ctx.checkIsCommand() &&
8561
- !ctx.isCommand(ctx.peek().value) &&
8562
8636
  !ctx.check(KEYWORDS$1.THEN) &&
8637
+ (firstConditionParse || (!ctx.checkIsCommand() && !ctx.isCommand(ctx.peek().value))) &&
8563
8638
  iterations < maxIterations) {
8639
+ firstConditionParse = false;
8564
8640
  const beforePos = ctx.savePosition();
8565
8641
  conditionTokens.push(ctx.parseLogicalAnd());
8566
8642
  if (ctx.savePosition() === beforePos) {
@@ -8587,22 +8663,8 @@ function parseIfCommand(ctx, commandToken) {
8587
8663
  }
8588
8664
  args.push(condition);
8589
8665
  if (isMultiLine) {
8590
- if (hasThen) {
8591
- ctx.advance();
8592
- }
8593
- const thenCommands = [];
8594
- while (!ctx.isAtEnd() && !ctx.check(KEYWORDS$1.ELSE) && !ctx.check(KEYWORDS$1.END)) {
8595
- if (ctx.checkIsCommand() || ctx.isCommand(ctx.peek().value)) {
8596
- ctx.advance();
8597
- const cmd = ctx.parseCommand();
8598
- if (cmd) {
8599
- thenCommands.push(cmd);
8600
- }
8601
- }
8602
- else {
8603
- break;
8604
- }
8605
- }
8666
+ consumeOptionalKeyword(ctx, KEYWORDS$1.THEN);
8667
+ const thenCommands = parseIfBranchCommands(ctx, true);
8606
8668
  if (thenCommands.length === 0 && ctx.isAtEnd()) {
8607
8669
  throw new Error("Expected command after 'then' in if statement - incomplete conditional");
8608
8670
  }
@@ -8628,19 +8690,7 @@ function parseIfCommand(ctx, commandToken) {
8628
8690
  consumedElseIf = true;
8629
8691
  }
8630
8692
  else {
8631
- const elseCommands = [];
8632
- while (!ctx.isAtEnd() && !ctx.check(KEYWORDS$1.END)) {
8633
- if (ctx.checkIsCommand() || ctx.isCommand(ctx.peek().value)) {
8634
- ctx.advance();
8635
- const cmd = ctx.parseCommand();
8636
- if (cmd) {
8637
- elseCommands.push(cmd);
8638
- }
8639
- }
8640
- else {
8641
- break;
8642
- }
8643
- }
8693
+ const elseCommands = parseIfBranchCommands(ctx, false);
8644
8694
  args.push(createBlock(elseCommands, {
8645
8695
  start: commandToken.start,
8646
8696
  end: ctx.getPosition().end,
@@ -9462,21 +9512,6 @@ const GO_KEYWORDS = new Set([
9462
9512
  'back',
9463
9513
  'forward',
9464
9514
  ]);
9465
- const GO_URL_STOP = new Set([
9466
- 'in',
9467
- 'then',
9468
- 'and',
9469
- 'else',
9470
- 'end',
9471
- 'otherwise',
9472
- 'when',
9473
- 'where',
9474
- 'catch',
9475
- 'finally',
9476
- ]);
9477
- function isGoURLTerminator(ctx) {
9478
- return ctx.isAtEnd() || GO_URL_STOP.has(ctx.peek().value);
9479
- }
9480
9515
  function stringNode(value, tok) {
9481
9516
  return {
9482
9517
  type: 'string',
@@ -9498,7 +9533,7 @@ function parseGoCommand(ctx, identifierNode) {
9498
9533
  continue;
9499
9534
  }
9500
9535
  if (isNakedURLStart(ctx)) {
9501
- const url = parseBareURLPath(ctx, isGoURLTerminator);
9536
+ const url = parseBareURLPath(ctx);
9502
9537
  if (url) {
9503
9538
  args.push(url);
9504
9539
  continue;
@@ -9638,13 +9673,6 @@ function parseMultiWordCommand(ctx, commandToken, commandName) {
9638
9673
  }
9639
9674
  return builder.build();
9640
9675
  }
9641
- function isFetchURLTerminator(ctx) {
9642
- if (ctx.isAtEnd())
9643
- return true;
9644
- const val = ctx.peek().value;
9645
- return (['as', 'with', '{', 'then', 'end', 'else', 'otherwise', ')'].includes(val) ||
9646
- isCommandBoundary(ctx));
9647
- }
9648
9676
  function isNakedURLStart(ctx) {
9649
9677
  const tok = ctx.peek();
9650
9678
  if (tok.value === '/')
@@ -9655,23 +9683,50 @@ function isNakedURLStart(ctx) {
9655
9683
  }
9656
9684
  return false;
9657
9685
  }
9658
- function parseBareURLPath(ctx, isTerminator = isFetchURLTerminator) {
9686
+ const URL_HARD_STOPS = new Set(['{', ')']);
9687
+ function parseBareURLPath(ctx) {
9659
9688
  const startPos = ctx.savePosition();
9689
+ const firstTok = ctx.peek();
9660
9690
  let path = '';
9661
- while (!ctx.isAtEnd() && !isTerminator(ctx)) {
9662
- path += ctx.advance().value;
9691
+ let prev = null;
9692
+ while (!ctx.isAtEnd()) {
9693
+ const tok = ctx.peek();
9694
+ if (prev && tok.start !== prev.end)
9695
+ break;
9696
+ if (tok.value === '$' && ctx.peekAt(1)?.value === '{') {
9697
+ ctx.advance();
9698
+ let last = ctx.advance();
9699
+ let depth = 1;
9700
+ while (!ctx.isAtEnd() && depth > 0) {
9701
+ last = ctx.advance();
9702
+ if (last.value === '{')
9703
+ depth++;
9704
+ else if (last.value === '}')
9705
+ depth--;
9706
+ }
9707
+ path += ctx.getInputSlice(tok.start, last.end);
9708
+ prev = last;
9709
+ continue;
9710
+ }
9711
+ if (URL_HARD_STOPS.has(tok.value))
9712
+ break;
9713
+ prev = ctx.advance();
9714
+ path += prev.value;
9663
9715
  }
9664
9716
  if (!path || path === '/') {
9665
9717
  ctx.restorePosition(startPos);
9666
9718
  return null;
9667
9719
  }
9668
- return {
9669
- type: 'literal',
9670
- value: path,
9671
- raw: path,
9672
- start: startPos,
9673
- end: ctx.savePosition(),
9720
+ const span = {
9721
+ start: firstTok.start,
9722
+ end: prev ? prev.end : firstTok.end,
9723
+ line: firstTok.line,
9724
+ column: firstTok.column,
9674
9725
  };
9726
+ if (path.includes('${')) {
9727
+ return { type: 'templateLiteral', value: path, ...span };
9728
+ }
9729
+ return { type: 'literal', value: path, raw: path, ...span };
9675
9730
  }
9676
9731
  function parseFetchCommand(ctx, commandToken) {
9677
9732
  const modifiers = {};
@@ -9902,10 +9957,10 @@ function parseTellCommand(ctx, identifierNode) {
9902
9957
  catch {
9903
9958
  break;
9904
9959
  }
9905
- if (ctx.match(KEYWORDS$1.AND)) {
9960
+ if (ctx.match(KEYWORDS$1.AND) || ctx.match(KEYWORDS$1.THEN)) {
9906
9961
  continue;
9907
9962
  }
9908
- if (ctx.check(KEYWORDS$1.THEN) || ctx.check(KEYWORDS$1.ELSE) || ctx.check(KEYWORDS$1.END)) {
9963
+ if (ctx.check(KEYWORDS$1.ELSE) || ctx.check(KEYWORDS$1.END)) {
9909
9964
  break;
9910
9965
  }
9911
9966
  if (ctx.checkIsCommand()) {
@@ -10108,6 +10163,7 @@ class Parser {
10108
10163
  const result = this.parseInternal();
10109
10164
  if (this.errors.length > 0) {
10110
10165
  result.errors = [...this.errors];
10166
+ result.recovered = true;
10111
10167
  }
10112
10168
  return result;
10113
10169
  }
@@ -12139,6 +12195,9 @@ class Parser {
12139
12195
  this.advance();
12140
12196
  const cmd = this.parseCommand();
12141
12197
  commands.push(cmd);
12198
+ if (this.match('then', 'and', ',')) {
12199
+ continue;
12200
+ }
12142
12201
  }
12143
12202
  else {
12144
12203
  break;