@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
@@ -1,2 +1,2 @@
1
- let t=null;async function n(){if(!t)try{t=await import("./browser-modular-D2BHzZFB.js").then(function(t){return t.m})}catch{throw Error("@lokascript/framework is required for LSE support. Install it: npm install @lokascript/framework")}return t}function r(){if(t)return!0;try{return require.resolve("@lokascript/framework"),!0}catch{return!1}}async function a(t,r){return(await n()).parseExplicit(t,r)}async function o(t){return(await n()).isExplicitSyntax(t)}async function i(t){return(await n()).renderExplicit(t)}async function e(t){return(await n()).fromInterchangeNode(t)}async function c(t){return(await n()).toProtocolJSON(t)}async function u(t){return(await n()).fromProtocolJSON(t)}async function s(t){return(await n()).validateProtocolJSON(t)}async function f(t){return(await n()).toEnvelopeJSON(t)}async function l(t){return(await n()).fromEnvelopeJSON(t)}async function w(t){return(await n()).isEnvelope(t)}async function p(t){return(await n()).semanticNodeToRuntimeAST(t)}export{l as fromEnvelopeJSON,e as fromInterchangeNode,u as fromProtocolJSON,w as isEnvelope,o as isExplicitSyntax,r as isLSEAvailable,a as parseExplicit,i as renderExplicit,p as semanticNodeToRuntimeAST,f as toEnvelopeJSON,c as toProtocolJSON,s as validateProtocolJSON};
2
- //# sourceMappingURL=index-DXgJaDj-.js.map
1
+ let t=null;async function n(){if(!t)try{t=await import("./browser-modular-6HT1r2AH.js").then(function(t){return t.m})}catch{throw Error("@lokascript/framework is required for LSE support. Install it: npm install @lokascript/framework")}return t}function r(){if(t)return!0;try{return require.resolve("@lokascript/framework"),!0}catch{return!1}}async function a(t,r){return(await n()).parseExplicit(t,r)}async function o(t){return(await n()).isExplicitSyntax(t)}async function i(t){return(await n()).renderExplicit(t)}async function e(t){return(await n()).fromInterchangeNode(t)}async function c(t){return(await n()).toProtocolJSON(t)}async function u(t){return(await n()).fromProtocolJSON(t)}async function s(t){return(await n()).validateProtocolJSON(t)}async function f(t){return(await n()).toEnvelopeJSON(t)}async function l(t){return(await n()).fromEnvelopeJSON(t)}async function w(t){return(await n()).isEnvelope(t)}async function p(t){return(await n()).semanticNodeToRuntimeAST(t)}export{l as fromEnvelopeJSON,e as fromInterchangeNode,u as fromProtocolJSON,w as isEnvelope,o as isExplicitSyntax,r as isLSEAvailable,a as parseExplicit,i as renderExplicit,p as semanticNodeToRuntimeAST,f as toEnvelopeJSON,c as toProtocolJSON,s as validateProtocolJSON};
2
+ //# sourceMappingURL=index-B8jwvuj_.js.map
@@ -6312,13 +6312,13 @@ function tokenize(input) {
6312
6312
  continue;
6313
6313
  }
6314
6314
  if (char === '{') {
6315
- addToken(tokenizer, TokenKind.OPERATOR, '{');
6316
6315
  advance(tokenizer);
6316
+ addToken(tokenizer, TokenKind.OPERATOR, '{');
6317
6317
  continue;
6318
6318
  }
6319
6319
  if (char === '}') {
6320
- addToken(tokenizer, TokenKind.OPERATOR, '}');
6321
6320
  advance(tokenizer);
6321
+ addToken(tokenizer, TokenKind.OPERATOR, '}');
6322
6322
  continue;
6323
6323
  }
6324
6324
  if (char === '[') {
@@ -6334,24 +6334,24 @@ function tokenize(input) {
6334
6334
  prevToken.value === ']') &&
6335
6335
  !isEventCondition;
6336
6336
  if (isMemberAccess) {
6337
- addToken(tokenizer, TokenKind.OPERATOR, '[');
6338
6337
  advance(tokenizer);
6338
+ addToken(tokenizer, TokenKind.OPERATOR, '[');
6339
6339
  }
6340
6340
  else {
6341
6341
  if (isEventCondition) {
6342
- addToken(tokenizer, TokenKind.SYMBOL, '[');
6343
6342
  advance(tokenizer);
6343
+ addToken(tokenizer, TokenKind.SYMBOL, '[');
6344
6344
  }
6345
6345
  else {
6346
- addToken(tokenizer, TokenKind.OPERATOR, '[');
6347
6346
  advance(tokenizer);
6347
+ addToken(tokenizer, TokenKind.OPERATOR, '[');
6348
6348
  }
6349
6349
  }
6350
6350
  continue;
6351
6351
  }
6352
6352
  if (char === ']') {
6353
- addToken(tokenizer, TokenKind.OPERATOR, ']');
6354
6353
  advance(tokenizer);
6354
+ addToken(tokenizer, TokenKind.OPERATOR, ']');
6355
6355
  continue;
6356
6356
  }
6357
6357
  if (char === '$') {
@@ -7980,7 +7980,6 @@ const MULTI_WORD_PATTERNS = [
7980
7980
  keywords: ['a', 'an', 'from', 'called'],
7981
7981
  syntax: 'make (a|an) <type> [from <args>] [called <name>]',
7982
7982
  },
7983
- { command: 'send', keywords: ['to'], syntax: 'send <event> to <target>' },
7984
7983
  { command: 'throw', keywords: [], syntax: 'throw <error>' },
7985
7984
  ];
7986
7985
  function getMultiWordPattern(commandName) {
@@ -8281,7 +8280,13 @@ function parseTriggerCommand(ctx, identifierNode) {
8281
8280
  finalArgs.push(ctx.createIdentifier(keyword));
8282
8281
  continue;
8283
8282
  }
8284
- finalArgs.push(ctx.parsePrimary());
8283
+ const before = ctx.savePosition();
8284
+ const expr = ctx.parsePrimary();
8285
+ if (expr)
8286
+ finalArgs.push(expr);
8287
+ if (ctx.savePosition() === before) {
8288
+ ctx.advance();
8289
+ }
8285
8290
  }
8286
8291
  return CommandNodeBuilder.fromIdentifier(identifierNode)
8287
8292
  .withArgs(...finalArgs)
@@ -8500,11 +8505,64 @@ function parseRepeatCommand(ctx, commandToken) {
8500
8505
  }
8501
8506
  return builder.endingAt(ctx.getPosition()).build();
8502
8507
  }
8508
+ function parseIfBranchCommands(ctx, stopAtElse) {
8509
+ const commands = [];
8510
+ const atTerminator = () => ctx.check(KEYWORDS$1.END) || (stopAtElse && ctx.check(KEYWORDS$1.ELSE));
8511
+ while (!ctx.isAtEnd() && !atTerminator()) {
8512
+ if (isComment(ctx.peek())) {
8513
+ ctx.advance();
8514
+ continue;
8515
+ }
8516
+ if (!ctx.checkIsCommand() && !ctx.isCommand(ctx.peek().value))
8517
+ break;
8518
+ ctx.advance();
8519
+ const cmd = ctx.parseCommand();
8520
+ if (cmd) {
8521
+ commands.push(cmd);
8522
+ }
8523
+ if (ctx.check(KEYWORDS$1.THEN) || ctx.check(KEYWORDS$1.AND) || ctx.check(',')) {
8524
+ ctx.advance();
8525
+ }
8526
+ }
8527
+ return commands;
8528
+ }
8529
+ const OPERAND_INTRODUCERS = new Set([
8530
+ 'is',
8531
+ 'am',
8532
+ 'are',
8533
+ 'not',
8534
+ 'no',
8535
+ 'and',
8536
+ 'or',
8537
+ '==',
8538
+ '===',
8539
+ '!=',
8540
+ '!==',
8541
+ '<',
8542
+ '>',
8543
+ '<=',
8544
+ '>=',
8545
+ '+',
8546
+ '-',
8547
+ '*',
8548
+ '/',
8549
+ 'mod',
8550
+ ]);
8551
+ function isBodyCommandStart(ctx, prevToken, token) {
8552
+ if (prevToken === null) {
8553
+ return false;
8554
+ }
8555
+ if (OPERAND_INTRODUCERS.has(prevToken.value?.toLowerCase?.() ?? '')) {
8556
+ return false;
8557
+ }
8558
+ return ctx.checkIsCommand() || ctx.isCommand(token.value?.toLowerCase());
8559
+ }
8503
8560
  function parseIfCommand(ctx, commandToken) {
8504
8561
  const args = [];
8505
8562
  let hasThen = false;
8506
8563
  const savedPosForThen = ctx.savePosition();
8507
8564
  const maxThenLookahead = 500;
8565
+ let prevForThen = null;
8508
8566
  for (let i = 0; i < maxThenLookahead && !ctx.isAtEnd(); i++) {
8509
8567
  const token = ctx.peek();
8510
8568
  if (token.value === KEYWORDS$1.THEN) {
@@ -8517,6 +8575,14 @@ function parseIfCommand(ctx, commandToken) {
8517
8575
  token.value === KEYWORDS$1.ON) {
8518
8576
  break;
8519
8577
  }
8578
+ if (token.line !== undefined &&
8579
+ token.line !== commandToken.line &&
8580
+ isBodyCommandStart(ctx, prevForThen, token)) {
8581
+ break;
8582
+ }
8583
+ if (!isComment(token)) {
8584
+ prevForThen = token;
8585
+ }
8520
8586
  ctx.advance();
8521
8587
  }
8522
8588
  ctx.restorePosition(savedPosForThen);
@@ -8525,9 +8591,14 @@ function parseIfCommand(ctx, commandToken) {
8525
8591
  const savedPosition = ctx.savePosition();
8526
8592
  const ifStatementLine = commandToken.line;
8527
8593
  const maxLookahead = 100;
8594
+ let firstCommandOnIfLine = false;
8595
+ let prevToken = null;
8528
8596
  while (!ctx.isAtEnd() && ctx.current - savedPosition < maxLookahead) {
8529
8597
  const token = ctx.peek();
8530
8598
  const tokenValue = token.value?.toLowerCase();
8599
+ if (firstCommandOnIfLine && token.line !== undefined && token.line !== ifStatementLine) {
8600
+ break;
8601
+ }
8531
8602
  if (tokenValue === KEYWORDS$1.BEHAVIOR ||
8532
8603
  tokenValue === KEYWORDS$1.DEF ||
8533
8604
  tokenValue === KEYWORDS$1.ON) {
@@ -8539,11 +8610,15 @@ function parseIfCommand(ctx, commandToken) {
8539
8610
  }
8540
8611
  break;
8541
8612
  }
8542
- if (ctx.checkIsCommand() || ctx.isCommand(tokenValue)) {
8613
+ if (isBodyCommandStart(ctx, prevToken, token)) {
8543
8614
  if (token.line !== undefined && token.line !== ifStatementLine) {
8544
8615
  hasImplicitMultiLineEnd = true;
8545
8616
  break;
8546
8617
  }
8618
+ firstCommandOnIfLine = true;
8619
+ }
8620
+ if (!isComment(token)) {
8621
+ prevToken = token;
8547
8622
  }
8548
8623
  ctx.advance();
8549
8624
  }
@@ -8558,11 +8633,12 @@ function parseIfCommand(ctx, commandToken) {
8558
8633
  const conditionTokens = [];
8559
8634
  const maxIterations = 20;
8560
8635
  let iterations = 0;
8636
+ let firstConditionParse = true;
8561
8637
  while (!ctx.isAtEnd() &&
8562
- !ctx.checkIsCommand() &&
8563
- !ctx.isCommand(ctx.peek().value) &&
8564
8638
  !ctx.check(KEYWORDS$1.THEN) &&
8639
+ (firstConditionParse || (!ctx.checkIsCommand() && !ctx.isCommand(ctx.peek().value))) &&
8565
8640
  iterations < maxIterations) {
8641
+ firstConditionParse = false;
8566
8642
  const beforePos = ctx.savePosition();
8567
8643
  conditionTokens.push(ctx.parseLogicalAnd());
8568
8644
  if (ctx.savePosition() === beforePos) {
@@ -8589,22 +8665,8 @@ function parseIfCommand(ctx, commandToken) {
8589
8665
  }
8590
8666
  args.push(condition);
8591
8667
  if (isMultiLine) {
8592
- if (hasThen) {
8593
- ctx.advance();
8594
- }
8595
- const thenCommands = [];
8596
- while (!ctx.isAtEnd() && !ctx.check(KEYWORDS$1.ELSE) && !ctx.check(KEYWORDS$1.END)) {
8597
- if (ctx.checkIsCommand() || ctx.isCommand(ctx.peek().value)) {
8598
- ctx.advance();
8599
- const cmd = ctx.parseCommand();
8600
- if (cmd) {
8601
- thenCommands.push(cmd);
8602
- }
8603
- }
8604
- else {
8605
- break;
8606
- }
8607
- }
8668
+ consumeOptionalKeyword(ctx, KEYWORDS$1.THEN);
8669
+ const thenCommands = parseIfBranchCommands(ctx, true);
8608
8670
  if (thenCommands.length === 0 && ctx.isAtEnd()) {
8609
8671
  throw new Error("Expected command after 'then' in if statement - incomplete conditional");
8610
8672
  }
@@ -8630,19 +8692,7 @@ function parseIfCommand(ctx, commandToken) {
8630
8692
  consumedElseIf = true;
8631
8693
  }
8632
8694
  else {
8633
- const elseCommands = [];
8634
- while (!ctx.isAtEnd() && !ctx.check(KEYWORDS$1.END)) {
8635
- if (ctx.checkIsCommand() || ctx.isCommand(ctx.peek().value)) {
8636
- ctx.advance();
8637
- const cmd = ctx.parseCommand();
8638
- if (cmd) {
8639
- elseCommands.push(cmd);
8640
- }
8641
- }
8642
- else {
8643
- break;
8644
- }
8645
- }
8695
+ const elseCommands = parseIfBranchCommands(ctx, false);
8646
8696
  args.push(createBlock(elseCommands, {
8647
8697
  start: commandToken.start,
8648
8698
  end: ctx.getPosition().end,
@@ -9464,21 +9514,6 @@ const GO_KEYWORDS = new Set([
9464
9514
  'back',
9465
9515
  'forward',
9466
9516
  ]);
9467
- const GO_URL_STOP = new Set([
9468
- 'in',
9469
- 'then',
9470
- 'and',
9471
- 'else',
9472
- 'end',
9473
- 'otherwise',
9474
- 'when',
9475
- 'where',
9476
- 'catch',
9477
- 'finally',
9478
- ]);
9479
- function isGoURLTerminator(ctx) {
9480
- return ctx.isAtEnd() || GO_URL_STOP.has(ctx.peek().value);
9481
- }
9482
9517
  function stringNode(value, tok) {
9483
9518
  return {
9484
9519
  type: 'string',
@@ -9500,7 +9535,7 @@ function parseGoCommand(ctx, identifierNode) {
9500
9535
  continue;
9501
9536
  }
9502
9537
  if (isNakedURLStart(ctx)) {
9503
- const url = parseBareURLPath(ctx, isGoURLTerminator);
9538
+ const url = parseBareURLPath(ctx);
9504
9539
  if (url) {
9505
9540
  args.push(url);
9506
9541
  continue;
@@ -9640,13 +9675,6 @@ function parseMultiWordCommand(ctx, commandToken, commandName) {
9640
9675
  }
9641
9676
  return builder.build();
9642
9677
  }
9643
- function isFetchURLTerminator(ctx) {
9644
- if (ctx.isAtEnd())
9645
- return true;
9646
- const val = ctx.peek().value;
9647
- return (['as', 'with', '{', 'then', 'end', 'else', 'otherwise', ')'].includes(val) ||
9648
- isCommandBoundary(ctx));
9649
- }
9650
9678
  function isNakedURLStart(ctx) {
9651
9679
  const tok = ctx.peek();
9652
9680
  if (tok.value === '/')
@@ -9657,23 +9685,50 @@ function isNakedURLStart(ctx) {
9657
9685
  }
9658
9686
  return false;
9659
9687
  }
9660
- function parseBareURLPath(ctx, isTerminator = isFetchURLTerminator) {
9688
+ const URL_HARD_STOPS = new Set(['{', ')']);
9689
+ function parseBareURLPath(ctx) {
9661
9690
  const startPos = ctx.savePosition();
9691
+ const firstTok = ctx.peek();
9662
9692
  let path = '';
9663
- while (!ctx.isAtEnd() && !isTerminator(ctx)) {
9664
- path += ctx.advance().value;
9693
+ let prev = null;
9694
+ while (!ctx.isAtEnd()) {
9695
+ const tok = ctx.peek();
9696
+ if (prev && tok.start !== prev.end)
9697
+ break;
9698
+ if (tok.value === '$' && ctx.peekAt(1)?.value === '{') {
9699
+ ctx.advance();
9700
+ let last = ctx.advance();
9701
+ let depth = 1;
9702
+ while (!ctx.isAtEnd() && depth > 0) {
9703
+ last = ctx.advance();
9704
+ if (last.value === '{')
9705
+ depth++;
9706
+ else if (last.value === '}')
9707
+ depth--;
9708
+ }
9709
+ path += ctx.getInputSlice(tok.start, last.end);
9710
+ prev = last;
9711
+ continue;
9712
+ }
9713
+ if (URL_HARD_STOPS.has(tok.value))
9714
+ break;
9715
+ prev = ctx.advance();
9716
+ path += prev.value;
9665
9717
  }
9666
9718
  if (!path || path === '/') {
9667
9719
  ctx.restorePosition(startPos);
9668
9720
  return null;
9669
9721
  }
9670
- return {
9671
- type: 'literal',
9672
- value: path,
9673
- raw: path,
9674
- start: startPos,
9675
- end: ctx.savePosition(),
9722
+ const span = {
9723
+ start: firstTok.start,
9724
+ end: prev ? prev.end : firstTok.end,
9725
+ line: firstTok.line,
9726
+ column: firstTok.column,
9676
9727
  };
9728
+ if (path.includes('${')) {
9729
+ return { type: 'templateLiteral', value: path, ...span };
9730
+ }
9731
+ return { type: 'literal', value: path, raw: path, ...span };
9677
9732
  }
9678
9733
  function parseFetchCommand(ctx, commandToken) {
9679
9734
  const modifiers = {};
@@ -9904,10 +9959,10 @@ function parseTellCommand(ctx, identifierNode) {
9904
9959
  catch {
9905
9960
  break;
9906
9961
  }
9907
- if (ctx.match(KEYWORDS$1.AND)) {
9962
+ if (ctx.match(KEYWORDS$1.AND) || ctx.match(KEYWORDS$1.THEN)) {
9908
9963
  continue;
9909
9964
  }
9910
- if (ctx.check(KEYWORDS$1.THEN) || ctx.check(KEYWORDS$1.ELSE) || ctx.check(KEYWORDS$1.END)) {
9965
+ if (ctx.check(KEYWORDS$1.ELSE) || ctx.check(KEYWORDS$1.END)) {
9911
9966
  break;
9912
9967
  }
9913
9968
  if (ctx.checkIsCommand()) {
@@ -10110,6 +10165,7 @@ class Parser {
10110
10165
  const result = this.parseInternal();
10111
10166
  if (this.errors.length > 0) {
10112
10167
  result.errors = [...this.errors];
10168
+ result.recovered = true;
10113
10169
  }
10114
10170
  return result;
10115
10171
  }
@@ -12141,6 +12197,9 @@ class Parser {
12141
12197
  this.advance();
12142
12198
  const cmd = this.parseCommand();
12143
12199
  commands.push(cmd);
12200
+ if (this.match('then', 'and', ',')) {
12201
+ continue;
12202
+ }
12144
12203
  }
12145
12204
  else {
12146
12205
  break;