@lokascript/compilation-service 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.
@@ -24,7 +24,7 @@ function convertCoreASTToAOT(node) {
24
24
  return node;
25
25
  }
26
26
  async function createCoreParserAdapter() {
27
- const core = await import("./dist-MNOHSQR3.js");
27
+ const core = await import("./dist-RYFD45WA.js");
28
28
  const api = core.hyperscript ?? core.default ?? core;
29
29
  if (!api?.compileSync) {
30
30
  throw new Error(
@@ -46,4 +46,4 @@ export {
46
46
  convertCoreASTToAOT,
47
47
  createCoreParserAdapter
48
48
  };
49
- //# sourceMappingURL=chunk-54DRG7ML.js.map
49
+ //# sourceMappingURL=chunk-DFBBRFZA.js.map
@@ -2768,7 +2768,7 @@ var CompilationService = class _CompilationService {
2768
2768
  initValidation({
2769
2769
  validateSemanticResult: semantic.validateSemanticResult
2770
2770
  });
2771
- const aot = await import("./dist-3Y3WFOKC.js");
2771
+ const aot = await import("./dist-2SCMFZ5O.js");
2772
2772
  const compiler = aot.createCompiler();
2773
2773
  initBridge(
2774
2774
  {
@@ -3326,4 +3326,4 @@ export {
3326
3326
  SvelteRenderer,
3327
3327
  CompilationService
3328
3328
  };
3329
- //# sourceMappingURL=chunk-TN7NTIUI.js.map
3329
+ //# sourceMappingURL=chunk-JTNX5Y3D.js.map
@@ -2,11 +2,11 @@ import {
2
2
  CoreParserAdapter,
3
3
  convertCoreASTToAOT,
4
4
  createCoreParserAdapter
5
- } from "./chunk-54DRG7ML.js";
5
+ } from "./chunk-DFBBRFZA.js";
6
6
  import "./chunk-GBPMR66W.js";
7
7
  export {
8
8
  CoreParserAdapter,
9
9
  convertCoreASTToAOT,
10
10
  createCoreParserAdapter
11
11
  };
12
- //# sourceMappingURL=core-parser-adapter-VCJB52SO-J6I45WLU.js.map
12
+ //# sourceMappingURL=core-parser-adapter-VCJB52SO-EPO6NENW.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CoreParserAdapter,
3
3
  createCoreParserAdapter
4
- } from "./chunk-54DRG7ML.js";
4
+ } from "./chunk-DFBBRFZA.js";
5
5
  import {
6
6
  SemanticParserAdapter,
7
7
  createSemanticAdapter
@@ -4217,7 +4217,7 @@ async function compileHyperscript(code, options) {
4217
4217
  async function createMultilingualCompiler() {
4218
4218
  const compiler = new AOTCompiler();
4219
4219
  try {
4220
- const { createCoreParserAdapter: createCoreParserAdapter2 } = await import("./core-parser-adapter-VCJB52SO-J6I45WLU.js");
4220
+ const { createCoreParserAdapter: createCoreParserAdapter2 } = await import("./core-parser-adapter-VCJB52SO-EPO6NENW.js");
4221
4221
  compiler.setParser(await createCoreParserAdapter2());
4222
4222
  } catch {
4223
4223
  }
@@ -4270,4 +4270,4 @@ export {
4270
4270
  sanitizeSelector,
4271
4271
  scanFiles
4272
4272
  };
4273
- //# sourceMappingURL=dist-3Y3WFOKC.js.map
4273
+ //# sourceMappingURL=dist-2SCMFZ5O.js.map
@@ -498,13 +498,13 @@ function tokenize$1(input) {
498
498
  continue;
499
499
  }
500
500
  if (char === "{") {
501
- addToken(tokenizer, TokenKind.OPERATOR, "{");
502
501
  advance(tokenizer);
502
+ addToken(tokenizer, TokenKind.OPERATOR, "{");
503
503
  continue;
504
504
  }
505
505
  if (char === "}") {
506
- addToken(tokenizer, TokenKind.OPERATOR, "}");
507
506
  advance(tokenizer);
507
+ addToken(tokenizer, TokenKind.OPERATOR, "}");
508
508
  continue;
509
509
  }
510
510
  if (char === "[") {
@@ -512,22 +512,22 @@ function tokenize$1(input) {
512
512
  const isEventCondition = prevToken && prevToken.kind === TokenKind.IDENTIFIER && DOM_EVENTS.has(prevToken.value) && tokenizer.tokens.length >= 2 && tokenizer.tokens[tokenizer.tokens.length - 2]?.value === "on";
513
513
  const isMemberAccess = prevToken && (prevToken.kind === TokenKind.IDENTIFIER || prevToken.value === ")" || prevToken.value === "]") && !isEventCondition;
514
514
  if (isMemberAccess) {
515
- addToken(tokenizer, TokenKind.OPERATOR, "[");
516
515
  advance(tokenizer);
516
+ addToken(tokenizer, TokenKind.OPERATOR, "[");
517
517
  } else {
518
518
  if (isEventCondition) {
519
- addToken(tokenizer, TokenKind.SYMBOL, "[");
520
519
  advance(tokenizer);
520
+ addToken(tokenizer, TokenKind.SYMBOL, "[");
521
521
  } else {
522
- addToken(tokenizer, TokenKind.OPERATOR, "[");
523
522
  advance(tokenizer);
523
+ addToken(tokenizer, TokenKind.OPERATOR, "[");
524
524
  }
525
525
  }
526
526
  continue;
527
527
  }
528
528
  if (char === "]") {
529
- addToken(tokenizer, TokenKind.OPERATOR, "]");
530
529
  advance(tokenizer);
530
+ addToken(tokenizer, TokenKind.OPERATOR, "]");
531
531
  continue;
532
532
  }
533
533
  if (char === "$") {
@@ -2825,7 +2825,6 @@ var MULTI_WORD_PATTERNS = [
2825
2825
  keywords: ["a", "an", "from", "called"],
2826
2826
  syntax: "make (a|an) <type> [from <args>] [called <name>]"
2827
2827
  },
2828
- { command: "send", keywords: ["to"], syntax: "send <event> to <target>" },
2829
2828
  { command: "throw", keywords: [], syntax: "throw <error>" }
2830
2829
  ];
2831
2830
  function getMultiWordPattern(commandName) {
@@ -3120,7 +3119,13 @@ function parseTriggerCommand(ctx, identifierNode) {
3120
3119
  finalArgs.push(ctx.createIdentifier(keyword));
3121
3120
  continue;
3122
3121
  }
3123
- finalArgs.push(ctx.parsePrimary());
3122
+ const before = ctx.savePosition();
3123
+ const expr = ctx.parsePrimary();
3124
+ if (expr)
3125
+ finalArgs.push(expr);
3126
+ if (ctx.savePosition() === before) {
3127
+ ctx.advance();
3128
+ }
3124
3129
  }
3125
3130
  return CommandNodeBuilder.fromIdentifier(identifierNode).withArgs(...finalArgs).endingAt(ctx.getPosition()).build();
3126
3131
  }
@@ -3320,11 +3325,64 @@ function parseRepeatCommand(ctx, commandToken) {
3320
3325
  }
3321
3326
  return builder.endingAt(ctx.getPosition()).build();
3322
3327
  }
3328
+ function parseIfBranchCommands(ctx, stopAtElse) {
3329
+ const commands = [];
3330
+ const atTerminator = () => ctx.check(KEYWORDS$1.END) || stopAtElse && ctx.check(KEYWORDS$1.ELSE);
3331
+ while (!ctx.isAtEnd() && !atTerminator()) {
3332
+ if (isComment(ctx.peek())) {
3333
+ ctx.advance();
3334
+ continue;
3335
+ }
3336
+ if (!ctx.checkIsCommand() && !ctx.isCommand(ctx.peek().value))
3337
+ break;
3338
+ ctx.advance();
3339
+ const cmd = ctx.parseCommand();
3340
+ if (cmd) {
3341
+ commands.push(cmd);
3342
+ }
3343
+ if (ctx.check(KEYWORDS$1.THEN) || ctx.check(KEYWORDS$1.AND) || ctx.check(",")) {
3344
+ ctx.advance();
3345
+ }
3346
+ }
3347
+ return commands;
3348
+ }
3349
+ var OPERAND_INTRODUCERS = /* @__PURE__ */ new Set([
3350
+ "is",
3351
+ "am",
3352
+ "are",
3353
+ "not",
3354
+ "no",
3355
+ "and",
3356
+ "or",
3357
+ "==",
3358
+ "===",
3359
+ "!=",
3360
+ "!==",
3361
+ "<",
3362
+ ">",
3363
+ "<=",
3364
+ ">=",
3365
+ "+",
3366
+ "-",
3367
+ "*",
3368
+ "/",
3369
+ "mod"
3370
+ ]);
3371
+ function isBodyCommandStart(ctx, prevToken, token) {
3372
+ if (prevToken === null) {
3373
+ return false;
3374
+ }
3375
+ if (OPERAND_INTRODUCERS.has(prevToken.value?.toLowerCase?.() ?? "")) {
3376
+ return false;
3377
+ }
3378
+ return ctx.checkIsCommand() || ctx.isCommand(token.value?.toLowerCase());
3379
+ }
3323
3380
  function parseIfCommand(ctx, commandToken) {
3324
3381
  const args = [];
3325
3382
  let hasThen = false;
3326
3383
  const savedPosForThen = ctx.savePosition();
3327
3384
  const maxThenLookahead = 500;
3385
+ let prevForThen = null;
3328
3386
  for (let i = 0; i < maxThenLookahead && !ctx.isAtEnd(); i++) {
3329
3387
  const token = ctx.peek();
3330
3388
  if (token.value === KEYWORDS$1.THEN) {
@@ -3334,6 +3392,12 @@ function parseIfCommand(ctx, commandToken) {
3334
3392
  if (token.value === KEYWORDS$1.END || token.value === KEYWORDS$1.BEHAVIOR || token.value === KEYWORDS$1.DEF || token.value === KEYWORDS$1.ON) {
3335
3393
  break;
3336
3394
  }
3395
+ if (token.line !== void 0 && token.line !== commandToken.line && isBodyCommandStart(ctx, prevForThen, token)) {
3396
+ break;
3397
+ }
3398
+ if (!isComment(token)) {
3399
+ prevForThen = token;
3400
+ }
3337
3401
  ctx.advance();
3338
3402
  }
3339
3403
  ctx.restorePosition(savedPosForThen);
@@ -3342,9 +3406,14 @@ function parseIfCommand(ctx, commandToken) {
3342
3406
  const savedPosition = ctx.savePosition();
3343
3407
  const ifStatementLine = commandToken.line;
3344
3408
  const maxLookahead = 100;
3409
+ let firstCommandOnIfLine = false;
3410
+ let prevToken = null;
3345
3411
  while (!ctx.isAtEnd() && ctx.current - savedPosition < maxLookahead) {
3346
3412
  const token = ctx.peek();
3347
3413
  const tokenValue = token.value?.toLowerCase();
3414
+ if (firstCommandOnIfLine && token.line !== void 0 && token.line !== ifStatementLine) {
3415
+ break;
3416
+ }
3348
3417
  if (tokenValue === KEYWORDS$1.BEHAVIOR || tokenValue === KEYWORDS$1.DEF || tokenValue === KEYWORDS$1.ON) {
3349
3418
  break;
3350
3419
  }
@@ -3354,11 +3423,15 @@ function parseIfCommand(ctx, commandToken) {
3354
3423
  }
3355
3424
  break;
3356
3425
  }
3357
- if (ctx.checkIsCommand() || ctx.isCommand(tokenValue)) {
3426
+ if (isBodyCommandStart(ctx, prevToken, token)) {
3358
3427
  if (token.line !== void 0 && token.line !== ifStatementLine) {
3359
3428
  hasImplicitMultiLineEnd = true;
3360
3429
  break;
3361
3430
  }
3431
+ firstCommandOnIfLine = true;
3432
+ }
3433
+ if (!isComment(token)) {
3434
+ prevToken = token;
3362
3435
  }
3363
3436
  ctx.advance();
3364
3437
  }
@@ -3372,7 +3445,9 @@ function parseIfCommand(ctx, commandToken) {
3372
3445
  const conditionTokens = [];
3373
3446
  const maxIterations = 20;
3374
3447
  let iterations = 0;
3375
- while (!ctx.isAtEnd() && !ctx.checkIsCommand() && !ctx.isCommand(ctx.peek().value) && !ctx.check(KEYWORDS$1.THEN) && iterations < maxIterations) {
3448
+ let firstConditionParse = true;
3449
+ while (!ctx.isAtEnd() && !ctx.check(KEYWORDS$1.THEN) && (firstConditionParse || !ctx.checkIsCommand() && !ctx.isCommand(ctx.peek().value)) && iterations < maxIterations) {
3450
+ firstConditionParse = false;
3376
3451
  const beforePos = ctx.savePosition();
3377
3452
  conditionTokens.push(ctx.parseLogicalAnd());
3378
3453
  if (ctx.savePosition() === beforePos) {
@@ -3397,21 +3472,8 @@ function parseIfCommand(ctx, commandToken) {
3397
3472
  }
3398
3473
  args.push(condition);
3399
3474
  if (isMultiLine) {
3400
- if (hasThen) {
3401
- ctx.advance();
3402
- }
3403
- const thenCommands = [];
3404
- while (!ctx.isAtEnd() && !ctx.check(KEYWORDS$1.ELSE) && !ctx.check(KEYWORDS$1.END)) {
3405
- if (ctx.checkIsCommand() || ctx.isCommand(ctx.peek().value)) {
3406
- ctx.advance();
3407
- const cmd = ctx.parseCommand();
3408
- if (cmd) {
3409
- thenCommands.push(cmd);
3410
- }
3411
- } else {
3412
- break;
3413
- }
3414
- }
3475
+ consumeOptionalKeyword(ctx, KEYWORDS$1.THEN);
3476
+ const thenCommands = parseIfBranchCommands(ctx, true);
3415
3477
  if (thenCommands.length === 0 && ctx.isAtEnd()) {
3416
3478
  throw new Error("Expected command after 'then' in if statement - incomplete conditional");
3417
3479
  }
@@ -3436,18 +3498,7 @@ function parseIfCommand(ctx, commandToken) {
3436
3498
  }));
3437
3499
  consumedElseIf = true;
3438
3500
  } else {
3439
- const elseCommands = [];
3440
- while (!ctx.isAtEnd() && !ctx.check(KEYWORDS$1.END)) {
3441
- if (ctx.checkIsCommand() || ctx.isCommand(ctx.peek().value)) {
3442
- ctx.advance();
3443
- const cmd = ctx.parseCommand();
3444
- if (cmd) {
3445
- elseCommands.push(cmd);
3446
- }
3447
- } else {
3448
- break;
3449
- }
3450
- }
3501
+ const elseCommands = parseIfBranchCommands(ctx, false);
3451
3502
  args.push(createBlock(elseCommands, {
3452
3503
  start: commandToken.start,
3453
3504
  end: ctx.getPosition().end,
@@ -4177,21 +4228,6 @@ var GO_KEYWORDS = /* @__PURE__ */ new Set([
4177
4228
  "back",
4178
4229
  "forward"
4179
4230
  ]);
4180
- var GO_URL_STOP = /* @__PURE__ */ new Set([
4181
- "in",
4182
- "then",
4183
- "and",
4184
- "else",
4185
- "end",
4186
- "otherwise",
4187
- "when",
4188
- "where",
4189
- "catch",
4190
- "finally"
4191
- ]);
4192
- function isGoURLTerminator(ctx) {
4193
- return ctx.isAtEnd() || GO_URL_STOP.has(ctx.peek().value);
4194
- }
4195
4231
  function stringNode(value, tok) {
4196
4232
  return {
4197
4233
  type: "string",
@@ -4213,7 +4249,7 @@ function parseGoCommand(ctx, identifierNode) {
4213
4249
  continue;
4214
4250
  }
4215
4251
  if (isNakedURLStart(ctx)) {
4216
- const url = parseBareURLPath(ctx, isGoURLTerminator);
4252
+ const url = parseBareURLPath(ctx);
4217
4253
  if (url) {
4218
4254
  args.push(url);
4219
4255
  continue;
@@ -4336,12 +4372,6 @@ function parseMultiWordCommand(ctx, commandToken, commandName) {
4336
4372
  }
4337
4373
  return builder.build();
4338
4374
  }
4339
- function isFetchURLTerminator(ctx) {
4340
- if (ctx.isAtEnd())
4341
- return true;
4342
- const val = ctx.peek().value;
4343
- return ["as", "with", "{", "then", "end", "else", "otherwise", ")"].includes(val) || isCommandBoundary(ctx);
4344
- }
4345
4375
  function isNakedURLStart(ctx) {
4346
4376
  const tok = ctx.peek();
4347
4377
  if (tok.value === "/")
@@ -4352,23 +4382,50 @@ function isNakedURLStart(ctx) {
4352
4382
  }
4353
4383
  return false;
4354
4384
  }
4355
- function parseBareURLPath(ctx, isTerminator = isFetchURLTerminator) {
4385
+ var URL_HARD_STOPS = /* @__PURE__ */ new Set(["{", ")"]);
4386
+ function parseBareURLPath(ctx) {
4356
4387
  const startPos = ctx.savePosition();
4388
+ const firstTok = ctx.peek();
4357
4389
  let path = "";
4358
- while (!ctx.isAtEnd() && !isTerminator(ctx)) {
4359
- path += ctx.advance().value;
4390
+ let prev = null;
4391
+ while (!ctx.isAtEnd()) {
4392
+ const tok = ctx.peek();
4393
+ if (prev && tok.start !== prev.end)
4394
+ break;
4395
+ if (tok.value === "$" && ctx.peekAt(1)?.value === "{") {
4396
+ ctx.advance();
4397
+ let last = ctx.advance();
4398
+ let depth = 1;
4399
+ while (!ctx.isAtEnd() && depth > 0) {
4400
+ last = ctx.advance();
4401
+ if (last.value === "{")
4402
+ depth++;
4403
+ else if (last.value === "}")
4404
+ depth--;
4405
+ }
4406
+ path += ctx.getInputSlice(tok.start, last.end);
4407
+ prev = last;
4408
+ continue;
4409
+ }
4410
+ if (URL_HARD_STOPS.has(tok.value))
4411
+ break;
4412
+ prev = ctx.advance();
4413
+ path += prev.value;
4360
4414
  }
4361
4415
  if (!path || path === "/") {
4362
4416
  ctx.restorePosition(startPos);
4363
4417
  return null;
4364
4418
  }
4365
- return {
4366
- type: "literal",
4367
- value: path,
4368
- raw: path,
4369
- start: startPos,
4370
- end: ctx.savePosition()
4419
+ const span = {
4420
+ start: firstTok.start,
4421
+ end: prev ? prev.end : firstTok.end,
4422
+ line: firstTok.line,
4423
+ column: firstTok.column
4371
4424
  };
4425
+ if (path.includes("${")) {
4426
+ return { type: "templateLiteral", value: path, ...span };
4427
+ }
4428
+ return { type: "literal", value: path, raw: path, ...span };
4372
4429
  }
4373
4430
  function parseFetchCommand(ctx, commandToken) {
4374
4431
  const modifiers = {};
@@ -4590,10 +4647,10 @@ function parseTellCommand(ctx, identifierNode) {
4590
4647
  } catch {
4591
4648
  break;
4592
4649
  }
4593
- if (ctx.match(KEYWORDS$1.AND)) {
4650
+ if (ctx.match(KEYWORDS$1.AND) || ctx.match(KEYWORDS$1.THEN)) {
4594
4651
  continue;
4595
4652
  }
4596
- if (ctx.check(KEYWORDS$1.THEN) || ctx.check(KEYWORDS$1.ELSE) || ctx.check(KEYWORDS$1.END)) {
4653
+ if (ctx.check(KEYWORDS$1.ELSE) || ctx.check(KEYWORDS$1.END)) {
4597
4654
  break;
4598
4655
  }
4599
4656
  if (ctx.checkIsCommand()) {
@@ -4768,6 +4825,7 @@ var Parser = class _Parser {
4768
4825
  const result = this.parseInternal();
4769
4826
  if (this.errors.length > 0) {
4770
4827
  result.errors = [...this.errors];
4828
+ result.recovered = true;
4771
4829
  }
4772
4830
  return result;
4773
4831
  }
@@ -6611,6 +6669,9 @@ var Parser = class _Parser {
6611
6669
  this.advance();
6612
6670
  const cmd = this.parseCommand();
6613
6671
  commands.push(cmd);
6672
+ if (this.match("then", "and", ",")) {
6673
+ continue;
6674
+ }
6614
6675
  } else {
6615
6676
  break;
6616
6677
  }
@@ -12251,6 +12312,25 @@ function isImplicitCommand(val) {
12251
12312
  return val !== null && typeof val === "object" && "command" in val && "selector" in val;
12252
12313
  }
12253
12314
  var eventRecursionDepth = /* @__PURE__ */ new WeakMap();
12315
+ function collectIdentifierNames(node, out = /* @__PURE__ */ new Set()) {
12316
+ if (node === null || typeof node !== "object")
12317
+ return out;
12318
+ if (Array.isArray(node)) {
12319
+ for (const item of node)
12320
+ collectIdentifierNames(item, out);
12321
+ return out;
12322
+ }
12323
+ const obj = node;
12324
+ if (obj.type === "identifier" && typeof obj.name === "string") {
12325
+ out.add(obj.name);
12326
+ }
12327
+ for (const key of Object.keys(obj)) {
12328
+ if (key === "start" || key === "end" || key === "line" || key === "column")
12329
+ continue;
12330
+ collectIdentifierNames(obj[key], out);
12331
+ }
12332
+ return out;
12333
+ }
12254
12334
  var RuntimeBase = class _RuntimeBase {
12255
12335
  constructor(options) {
12256
12336
  this.autoCleanupObserver = null;
@@ -12440,6 +12520,9 @@ var RuntimeBase = class _RuntimeBase {
12440
12520
  case "behavior": {
12441
12521
  return await this.executeBehaviorDefinition(node, context);
12442
12522
  }
12523
+ case "def": {
12524
+ return this.installFunction(node, context);
12525
+ }
12443
12526
  case "Program": {
12444
12527
  return await this.executeProgram(node, context);
12445
12528
  }
@@ -12649,22 +12732,69 @@ var RuntimeBase = class _RuntimeBase {
12649
12732
  };
12650
12733
  return this.processCommand(commandNode, context);
12651
12734
  }
12735
+ installFunction(node, context) {
12736
+ const runtime = this;
12737
+ const params = node.params ?? [];
12738
+ const body = node.body ?? [];
12739
+ const errorHandler = node.errorHandler;
12740
+ const finallyHandler = node.finallyHandler;
12741
+ const errorSymbol = node.errorSymbol;
12742
+ const fn = async (...args) => {
12743
+ const fnContext = {
12744
+ ...context,
12745
+ locals: new Map(context.locals)
12746
+ };
12747
+ params.forEach((name, i) => {
12748
+ if (name)
12749
+ fnContext.locals.set(name, args[i]);
12750
+ });
12751
+ const run = async (commands) => {
12752
+ const result = await runtime.executeCommandSequenceWithResult(commands, fnContext);
12753
+ if (!isOk(result))
12754
+ throw asControlFlowError(result.error);
12755
+ return result.value;
12756
+ };
12757
+ if (!errorHandler && !finallyHandler) {
12758
+ return await run(body);
12759
+ }
12760
+ try {
12761
+ return await run(body);
12762
+ } catch (e) {
12763
+ if (!errorHandler || isControlFlowError(e))
12764
+ throw e;
12765
+ if (errorSymbol)
12766
+ fnContext.locals.set(errorSymbol, e);
12767
+ return await run(errorHandler);
12768
+ } finally {
12769
+ if (finallyHandler) {
12770
+ await run(finallyHandler);
12771
+ }
12772
+ }
12773
+ };
12774
+ context.globals.set(node.name, fn);
12775
+ }
12652
12776
  async executeProgram(node, context) {
12653
12777
  if (!node.statements || !Array.isArray(node.statements))
12654
12778
  return;
12655
12779
  let lastResult = void 0;
12656
12780
  const eventHandlers = [];
12781
+ const defs = [];
12657
12782
  const initBlocks = [];
12658
12783
  const otherStatements = [];
12659
12784
  for (const statement of node.statements) {
12660
12785
  if (statement.type === "eventHandler") {
12661
12786
  eventHandlers.push(statement);
12787
+ } else if (statement.type === "def") {
12788
+ defs.push(statement);
12662
12789
  } else if (statement.type === "initBlock") {
12663
12790
  initBlocks.push(statement);
12664
12791
  } else {
12665
12792
  otherStatements.push(statement);
12666
12793
  }
12667
12794
  }
12795
+ for (const def of defs) {
12796
+ this.execute(def, context);
12797
+ }
12668
12798
  for (const handler of eventHandlers) {
12669
12799
  try {
12670
12800
  await this.execute(handler, context);
@@ -12851,7 +12981,7 @@ var RuntimeBase = class _RuntimeBase {
12851
12981
  debug.runtime(`BEHAVIOR: Finished installing ${behaviorName}`);
12852
12982
  }
12853
12983
  async executeEventHandler(node, context) {
12854
- const { event, events, commands, target, args, selector, attributeName, watchTarget, modifiers, errorSymbol, errorHandler, finallyHandler } = node;
12984
+ const { event, events, commands, target, args, selector, condition, attributeName, watchTarget, modifiers, errorSymbol, errorHandler, finallyHandler } = node;
12855
12985
  const eventNames = events && events.length > 0 ? events : [event];
12856
12986
  debug.runtime(`BEHAVIOR: executeEventHandler: event='${event}', target='${target}'`);
12857
12987
  let targets = [];
@@ -12925,7 +13055,8 @@ var RuntimeBase = class _RuntimeBase {
12925
13055
  }
12926
13056
  return;
12927
13057
  }
12928
- const baseEventHandler = _RuntimeBase.createEventHandler(this, commands, context, selector, args, { errorSymbol, errorHandler, finallyHandler });
13058
+ const applicableCondition = eventNames.length === 1 ? condition : void 0;
13059
+ const baseEventHandler = _RuntimeBase.createEventHandler(this, commands, context, selector, args, { errorSymbol, errorHandler, finallyHandler }, applicableCondition);
12929
13060
  let eventHandler;
12930
13061
  let debounceCleanup = null;
12931
13062
  if (modifiers) {
@@ -13023,7 +13154,7 @@ var RuntimeBase = class _RuntimeBase {
13023
13154
  }
13024
13155
  }
13025
13156
  }
13026
- static createEventHandler(runtime, commands, context, selector, args, errorBlocks) {
13157
+ static createEventHandler(runtime, commands, context, selector, args, errorBlocks, condition) {
13027
13158
  return async (domEvent) => {
13028
13159
  const currentDepth = eventRecursionDepth.get(domEvent) ?? 0;
13029
13160
  if (currentDepth >= 100) {
@@ -13058,6 +13189,24 @@ var RuntimeBase = class _RuntimeBase {
13058
13189
  eventContext.locals.set(argName, value);
13059
13190
  }
13060
13191
  }
13192
+ if (condition) {
13193
+ const eventProps = domEvent;
13194
+ for (const name of collectIdentifierNames(condition)) {
13195
+ if (!eventContext.locals.has(name) && name in eventProps) {
13196
+ eventContext.locals.set(name, eventProps[name]);
13197
+ }
13198
+ }
13199
+ let filterResult;
13200
+ try {
13201
+ filterResult = await runtime.evaluateExpression(condition, eventContext);
13202
+ } catch (e) {
13203
+ debug.runtime(`Event filter threw; skipping handler body:`, e);
13204
+ return;
13205
+ }
13206
+ if (!filterResult) {
13207
+ return;
13208
+ }
13209
+ }
13061
13210
  const runCommands = async (toRun) => {
13062
13211
  for (const command2 of toRun) {
13063
13212
  try {
@@ -79084,9 +79233,11 @@ function compileSync(code, options) {
79084
79233
  const parseResult = parse$1(code, parserOptions);
79085
79234
  const timeMs = performance.now() - startTime;
79086
79235
  if (parseResult.success && parseResult.node) {
79236
+ const recovered = parseResult.errors ?? [];
79087
79237
  const result = {
79088
79238
  ok: true,
79089
79239
  ast: parseResult.node,
79240
+ ...recovered.length > 0 ? { errors: recovered.map(toCompileError) } : {},
79090
79241
  meta: {
79091
79242
  parser: usesSemanticParser ? "semantic" : "traditional",
79092
79243
  language: lang,
@@ -79205,9 +79356,10 @@ async function evalCode(code, context, options) {
79205
79356
  }
79206
79357
  async function validate(code, options) {
79207
79358
  const result = await compileAsync(code, options);
79359
+ const errors = result.errors ?? [];
79208
79360
  return {
79209
- valid: result.ok,
79210
- errors: result.errors
79361
+ valid: result.ok && errors.length === 0,
79362
+ errors: errors.length > 0 ? errors : void 0
79211
79363
  };
79212
79364
  }
79213
79365
  function createContextWithParent(element, parent) {
@@ -86479,4 +86631,4 @@ export {
86479
86631
  toCoreAST,
86480
86632
  validatePartialContent
86481
86633
  };
86482
- //# sourceMappingURL=dist-MNOHSQR3.js.map
86634
+ //# sourceMappingURL=dist-RYFD45WA.js.map