@lokascript/compilation-service 2.2.1 → 2.3.1

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/http.cjs CHANGED
@@ -171,7 +171,7 @@ function tokenize$1(input) {
171
171
  const isKeywordContext = prevToken && prevToken.kind === TokenKind.IDENTIFIER && SELECTOR_CONTEXT_KEYWORDS.has(prevToken.value.toLowerCase());
172
172
  const isCSSSelectorContext = !prevToken || prevToken.kind === TokenKind.OPERATOR && prevToken.value !== ")" && prevToken.value !== "]" || isCommandContext || isKeywordContext || prevToken.value === "(" || prevToken.value === "[" || prevToken.value === "{" || prevToken.value === "," || prevToken.value === ";";
173
173
  const isAdjacentToPrev = prevToken && prevToken.end === tokenizer.position;
174
- if (isCSSSelectorContext && !isAdjacentToPrev && isAlpha(peek(tokenizer))) {
174
+ if (isCSSSelectorContext && !isAdjacentToPrev && (isAlpha(peek(tokenizer)) || peek(tokenizer) === "{")) {
175
175
  tokenizeCSSSelector(tokenizer);
176
176
  continue;
177
177
  }
@@ -387,6 +387,17 @@ function tokenizeCSSSelector(tokenizer) {
387
387
  const start = tokenizer.position;
388
388
  const prefix2 = advance(tokenizer);
389
389
  let value = prefix2;
390
+ if (tokenizer.position < tokenizer.input.length && tokenizer.input[tokenizer.position] === "{") {
391
+ value += advance(tokenizer);
392
+ while (tokenizer.position < tokenizer.input.length) {
393
+ const ch = tokenizer.input[tokenizer.position];
394
+ value += advance(tokenizer);
395
+ if (ch === "}")
396
+ break;
397
+ }
398
+ addToken(tokenizer, TokenKind.SELECTOR, value, start);
399
+ return;
400
+ }
390
401
  while (tokenizer.position < tokenizer.input.length) {
391
402
  const char = tokenizer.input[tokenizer.position];
392
403
  if (isAlphaNumeric(char) || char === "-" || char === "_" || char === ":") {
@@ -1263,31 +1274,14 @@ function parseTriggerCommand(ctx, identifierNode) {
1263
1274
  });
1264
1275
  }
1265
1276
  }
1266
- while (!isCommandBoundary(ctx)) {
1267
- allArgs.push(ctx.parsePrimary());
1268
- }
1269
- let operationIndex = -1;
1270
- let operationKeyword = "on";
1271
- for (let i = 0; i < allArgs.length; i++) {
1272
- const arg = allArgs[i];
1273
- const argRecord = arg;
1274
- const argValue = argRecord.name || argRecord.value;
1275
- if ((arg.type === "identifier" || arg.type === "literal" || arg.type === "keyword") && (argValue === "on" || argValue === "to")) {
1276
- operationIndex = i;
1277
- operationKeyword = argValue;
1278
- break;
1277
+ const finalArgs = [...allArgs];
1278
+ if (ctx.check("on") || ctx.check("to")) {
1279
+ const keyword = ctx.advance().value;
1280
+ finalArgs.push(ctx.createIdentifier(keyword));
1281
+ while (!isCommandBoundary(ctx)) {
1282
+ finalArgs.push(ctx.parsePrimary());
1279
1283
  }
1280
1284
  }
1281
- const finalArgs = [];
1282
- if (operationIndex === -1) {
1283
- finalArgs.push(...allArgs);
1284
- } else {
1285
- const eventArgs = allArgs.slice(0, operationIndex);
1286
- const targetArgs = allArgs.slice(operationIndex + 1);
1287
- finalArgs.push(...eventArgs);
1288
- finalArgs.push(ctx.createIdentifier(operationKeyword));
1289
- finalArgs.push(...targetArgs);
1290
- }
1291
1285
  return CommandNodeBuilder.fromIdentifier(identifierNode).withArgs(...finalArgs).endingAt(ctx.getPosition()).build();
1292
1286
  }
1293
1287
  function parseHaltCommand(ctx, identifierNode) {
@@ -1915,8 +1909,9 @@ function parseSwapCommand(ctx, identifierNode) {
1915
1909
  }
1916
1910
  function parseWaitCommand(ctx, commandToken) {
1917
1911
  const args = [];
1918
- if (ctx.checkTimeExpression() || ctx.checkLiteral()) {
1919
- const timeExpr = ctx.parsePrimary();
1912
+ const isExpressionStart = ctx.checkTimeExpression() || ctx.checkLiteral() || ctx.checkContextVar() || ctx.check("(") || ctx.checkIdentifierLike() && !ctx.check("for") && !isCommandBoundary(ctx);
1913
+ if (isExpressionStart) {
1914
+ const timeExpr = ctx.parseExpression();
1920
1915
  args.push(timeExpr);
1921
1916
  return CommandNodeBuilder.from(commandToken).withArgs(...args).blocking().endingAt(ctx.getPosition()).build();
1922
1917
  }
@@ -2084,43 +2079,24 @@ function parsePropertyOfTarget(ctx, startPosition) {
2084
2079
  return null;
2085
2080
  const thePosition = ctx.savePosition();
2086
2081
  ctx.advance();
2087
- const nextToken = ctx.peek();
2088
- const tokenAfterNext = ctx.peekAt(1);
2089
- if (nextToken && tokenAfterNext && tokenAfterNext.value === KEYWORDS$1.OF) {
2090
- const propertyToken = ctx.advance();
2091
- if (ctx.check(KEYWORDS$1.OF)) {
2092
- ctx.advance();
2093
- const targetToken = ctx.advance();
2094
- const isIdSelector2 = targetToken.value.startsWith("#");
2095
- return {
2096
- type: "propertyOfExpression",
2097
- property: {
2098
- type: "identifier",
2099
- name: propertyToken.value,
2100
- start: propertyToken.start,
2101
- end: propertyToken.end
2102
- },
2103
- target: {
2104
- type: isIdSelector2 ? "idSelector" : "cssSelector",
2105
- value: targetToken.value,
2106
- start: targetToken.start,
2107
- end: targetToken.end
2108
- },
2109
- start: startPosition,
2110
- end: ctx.savePosition()
2111
- };
2112
- }
2113
- ctx.restorePosition(startPosition);
2082
+ const propertyExpr = ctx.parseExpression();
2083
+ if (!propertyExpr) {
2084
+ ctx.restorePosition(thePosition);
2114
2085
  return null;
2115
2086
  }
2116
- if (nextToken && tokenAfterNext && tokenAfterNext.value === KEYWORDS$1.TO) {
2117
- const variableToken = ctx.advance();
2118
- return {
2119
- type: "identifier",
2120
- name: variableToken.value,
2121
- start: variableToken.start,
2122
- end: variableToken.end
2123
- };
2087
+ const exprAny = propertyExpr;
2088
+ if (exprAny.type === "binaryExpression" && exprAny.operator === KEYWORDS$1.OF) {
2089
+ const property = exprAny.left;
2090
+ const target = exprAny.right;
2091
+ return createPropertyOfExpression(property, target, {
2092
+ start: property.start ?? 0,
2093
+ end: target.end ?? 0,
2094
+ line: property.line ?? 1,
2095
+ column: property.column ?? 1
2096
+ });
2097
+ }
2098
+ if (ctx.check(KEYWORDS$1.TO)) {
2099
+ return propertyExpr;
2124
2100
  }
2125
2101
  ctx.restorePosition(thePosition);
2126
2102
  return null;
@@ -2444,6 +2420,68 @@ function parseFetchNakedNamedArgs(ctx) {
2444
2420
  column: startPos.column
2445
2421
  };
2446
2422
  }
2423
+ function findJsEndBoundary(ctx, startPos) {
2424
+ const input = ctx.getInputSlice(startPos);
2425
+ if (!input) {
2426
+ return startPos;
2427
+ }
2428
+ let i = 0;
2429
+ while (i < input.length) {
2430
+ const ch = input[i];
2431
+ if (ch === "'" || ch === "\u2019" || ch === "\u2018") {
2432
+ i++;
2433
+ while (i < input.length && input[i] !== ch) {
2434
+ if (input[i] === "\\")
2435
+ i++;
2436
+ i++;
2437
+ }
2438
+ i++;
2439
+ continue;
2440
+ }
2441
+ if (ch === '"') {
2442
+ i++;
2443
+ while (i < input.length && input[i] !== '"') {
2444
+ if (input[i] === "\\")
2445
+ i++;
2446
+ i++;
2447
+ }
2448
+ i++;
2449
+ continue;
2450
+ }
2451
+ if (ch === "`") {
2452
+ i++;
2453
+ while (i < input.length && input[i] !== "`") {
2454
+ if (input[i] === "\\")
2455
+ i++;
2456
+ i++;
2457
+ }
2458
+ i++;
2459
+ continue;
2460
+ }
2461
+ if (ch === "/" && i + 1 < input.length && input[i + 1] === "/") {
2462
+ i += 2;
2463
+ while (i < input.length && input[i] !== "\n")
2464
+ i++;
2465
+ continue;
2466
+ }
2467
+ if (ch === "/" && i + 1 < input.length && input[i + 1] === "*") {
2468
+ i += 2;
2469
+ while (i < input.length && !(input[i] === "*" && i + 1 < input.length && input[i + 1] === "/"))
2470
+ i++;
2471
+ i += 2;
2472
+ continue;
2473
+ }
2474
+ if ((ch === "e" || ch === "E") && i + 3 <= input.length && input.slice(i, i + 3).toLowerCase() === "end") {
2475
+ const before = i === 0 || !/[a-zA-Z0-9_]/.test(input[i - 1]);
2476
+ const after = i + 3 >= input.length || !/[a-zA-Z0-9_]/.test(input[i + 3]);
2477
+ if (before && after) {
2478
+ return startPos + i;
2479
+ }
2480
+ }
2481
+ i++;
2482
+ }
2483
+ return startPos + input.length;
2484
+ }
2447
2485
  function parseJsCommand(ctx, identifierNode) {
2448
2486
  const parameters = [];
2449
2487
  if (ctx.match("(")) {
@@ -2456,11 +2494,12 @@ function parseJsCommand(ctx, identifierNode) {
2456
2494
  ctx.consume(")", "Expected ) after js parameters");
2457
2495
  }
2458
2496
  const jsCodeStart = ctx.peek().start;
2459
- while (!ctx.check(KEYWORDS$1.END) && !ctx.isAtEnd()) {
2497
+ const jsCodeEnd = findJsEndBoundary(ctx, jsCodeStart);
2498
+ while (!ctx.isAtEnd() && !ctx.check(KEYWORDS$1.END)) {
2499
+ if (ctx.peek().start >= jsCodeEnd)
2500
+ break;
2460
2501
  ctx.advance();
2461
2502
  }
2462
- const endToken = ctx.peek();
2463
- const jsCodeEnd = endToken.start;
2464
2503
  ctx.consume(KEYWORDS$1.END, "Expected end after js code body");
2465
2504
  const rawSlice = ctx.getInputSlice(jsCodeStart, jsCodeEnd);
2466
2505
  const code = rawSlice.trim();
@@ -25443,7 +25482,7 @@ var init_dist = __esm({
25443
25482
  }
25444
25483
  } else {
25445
25484
  const commandName = expr.name.toLowerCase();
25446
- if (commandName === "wait" && this.checkTimeExpression()) {
25485
+ if (commandName === "wait" && (this.checkTimeExpression() || this.checkNumber() || this.checkIdentifier() || this.checkContextVar() || this.check("("))) {
25447
25486
  const command2 = this.createCommandFromIdentifier(expr);
25448
25487
  if (command2) {
25449
25488
  expr = command2;
@@ -26553,9 +26592,7 @@ var init_dist = __esm({
26553
26592
  while (!this.isAtEnd() && !this.check("end")) {
26554
26593
  if (this.match("on")) {
26555
26594
  const handlerPos = this.getPosition();
26556
- const eventToken = this.peek();
26557
- const eventName = eventToken.value;
26558
- this.advance();
26595
+ const eventName = this.parseEventNameWithNamespace("Expected event name after 'on'");
26559
26596
  const eventArgs = [];
26560
26597
  if (this.check("(")) {
26561
26598
  this.advance();
@@ -28398,6 +28435,8 @@ var init_dist = __esm({
28398
28435
  return this.evaluateIdSelector(node, context);
28399
28436
  case "attributeAccess":
28400
28437
  return this.evaluateAttributeAccess(node, context);
28438
+ case "asExpression":
28439
+ return this.evaluateAsExpression(node, context);
28401
28440
  default:
28402
28441
  throw new Error(`Unsupported AST node type for evaluation: ${node.type}`);
28403
28442
  }
@@ -28673,6 +28712,14 @@ var init_dist = __esm({
28673
28712
  }
28674
28713
  return `@${node.attributeName}`;
28675
28714
  }
28715
+ async evaluateAsExpression(node, context) {
28716
+ const value = await this.evaluate(node.expression, context);
28717
+ const asExpr = this.expressionRegistry.get("as");
28718
+ if (asExpr) {
28719
+ return asExpr.evaluate(context, value, node.targetType);
28720
+ }
28721
+ throw new Error(`Conversion type 'as' not registered`);
28722
+ }
28676
28723
  getAvailableExpressions() {
28677
28724
  return Array.from(this.expressionRegistry.keys());
28678
28725
  }
@@ -33172,6 +33219,8 @@ var init_dist = __esm({
33172
33219
  this.behaviorAPI = {
33173
33220
  has: (name) => this.behaviorRegistry.has(name),
33174
33221
  get: (name) => this.behaviorRegistry.get(name),
33222
+ set: (name, definition) => this.behaviorRegistry.set(name, definition),
33223
+ resolve: null,
33175
33224
  install: async (behaviorName, element, parameters) => {
33176
33225
  return await this.installBehaviorOnElement(behaviorName, element, parameters);
33177
33226
  }
@@ -33635,9 +33684,14 @@ var init_dist = __esm({
33635
33684
  }
33636
33685
  async installBehaviorOnElement(behaviorName, element, parameters) {
33637
33686
  debug.runtime(`BEHAVIOR: installBehaviorOnElement called: ${behaviorName}`);
33638
- const behavior = this.behaviorRegistry.get(behaviorName);
33639
- if (!behavior)
33640
- throw new Error(`Behavior "${behaviorName}" not found`);
33687
+ let behavior = this.behaviorRegistry.get(behaviorName);
33688
+ if (!behavior) {
33689
+ if (this.behaviorAPI.resolve && this.behaviorAPI.resolve(behaviorName)) {
33690
+ behavior = this.behaviorRegistry.get(behaviorName);
33691
+ }
33692
+ if (!behavior)
33693
+ throw new Error(`Behavior "${behaviorName}" not found`);
33694
+ }
33641
33695
  if (behavior.type === "imperative" && typeof behavior.install === "function") {
33642
33696
  debug.runtime(`BEHAVIOR: Installing imperative behavior '${behaviorName}'`);
33643
33697
  behavior.install(element, parameters);
@@ -34762,11 +34816,28 @@ var init_dist = __esm({
34762
34816
  const obj = targetArg.object, prop = targetArg.property;
34763
34817
  if (obj?.type === "selector")
34764
34818
  targetSelector = obj.value;
34765
- else if (obj?.type === "identifier")
34766
- targetSelector = obj.name;
34819
+ else if (obj?.type === "identifier") {
34820
+ const objName = obj.name;
34821
+ if (objName === "my" || objName === "me" || objName === "I") {
34822
+ if (context.me && prop?.name) {
34823
+ return {
34824
+ value,
34825
+ targets: [context.me],
34826
+ position: "replace",
34827
+ memberPath: prop.name
34828
+ };
34829
+ }
34830
+ } else if (objName === "its" || objName === "it") {
34831
+ const ev = await evaluator.evaluate(targetArg, context);
34832
+ if (typeof ev === "string")
34833
+ targetSelector = ev;
34834
+ } else {
34835
+ targetSelector = objName;
34836
+ }
34837
+ }
34767
34838
  if (targetSelector && prop?.name)
34768
34839
  memberPath = prop.name;
34769
- else {
34840
+ else if (!targetSelector && !memberPath) {
34770
34841
  const ev = await evaluator.evaluate(targetArg, context);
34771
34842
  if (typeof ev === "string")
34772
34843
  targetSelector = ev;
@@ -36485,7 +36556,9 @@ var init_dist = __esm({
36485
36556
  return { type: "property", element: firstValue[0], property: "textContent", value: value2 };
36486
36557
  }
36487
36558
  if (typeof firstValue !== "string") {
36488
- throw new Error("set command target must be a string or object literal");
36559
+ const isMember = firstArg?.type === "memberExpression" || firstArg?.type === "propertyAccess";
36560
+ const hint = isMember ? ` (a property chain evaluated to ${firstValue === null ? "null" : typeof firstValue} \u2014 check that all intermediate objects exist)` : "";
36561
+ throw new Error(`set command target must be a string or object literal${hint}`);
36489
36562
  }
36490
36563
  const value = await this.extractValue(raw, evaluator, context);
36491
36564
  return { type: "variable", name: firstValue, value };
@@ -39250,12 +39323,18 @@ var init_dist = __esm({
39250
39323
  const behaviorRegistry = context.locals.get("_behaviors");
39251
39324
  if (behaviorRegistry && typeof behaviorRegistry === "object") {
39252
39325
  const registry = behaviorRegistry;
39253
- return registry.has(behaviorName);
39326
+ if (registry.has(behaviorName))
39327
+ return true;
39328
+ if (registry.resolve && registry.resolve(behaviorName))
39329
+ return true;
39254
39330
  }
39255
39331
  if (typeof globalThis !== "undefined") {
39256
39332
  const hyperscriptGlobal = globalThis._hyperscript;
39257
39333
  if (hyperscriptGlobal?.behaviors) {
39258
- return hyperscriptGlobal.behaviors.has(behaviorName);
39334
+ if (hyperscriptGlobal.behaviors.has(behaviorName))
39335
+ return true;
39336
+ if (hyperscriptGlobal.behaviors.resolve && hyperscriptGlobal.behaviors.resolve(behaviorName))
39337
+ return true;
39259
39338
  }
39260
39339
  }
39261
39340
  return false;