@stacksjs/stx 0.2.110 → 0.2.111

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.
@@ -269,12 +269,17 @@ function expressionUsesOnlyContextVars(expr, context) {
269
269
  if (ch === "$" && exprWithoutStrings[ti + 1] === "{") {
270
270
  tplDepth++;
271
271
  ti++;
272
+ tplResult += " ";
272
273
  continue;
273
274
  }
274
275
  if (ch === "}" && tplDepth > 0) {
275
276
  tplDepth--;
276
277
  continue;
277
278
  }
279
+ if (tplDepth > 0) {
280
+ tplResult += ch;
281
+ continue;
282
+ }
278
283
  continue;
279
284
  }
280
285
  tplResult += ch;
@@ -378,7 +383,7 @@ export function processExpressions(template, context, filePath, options) {
378
383
  return "";
379
384
  try {
380
385
  const value = evaluateExpression(expr, context);
381
- if (value === void 0 && hasSignals && !expressionUsesOnlyContextVars(trimmedExpr, context))
386
+ if (hasSignals && !expressionUsesOnlyContextVars(trimmedExpr, context))
382
387
  return match;
383
388
  if (value === void 0 && context.__stx_buildMode === "compile" && !hasSignals)
384
389
  return createPlaceholder("expr", trimmedExpr);
package/dist/includes.js CHANGED
@@ -542,7 +542,7 @@ export async function processIncludes(template, context, filePath, options, depe
542
542
  if (options.debug)
543
543
  console.warn(`[stx] partial ES import extraction skipped for ${includeFilePath}:`, err instanceof Error ? err.message : err);
544
544
  }
545
- const templateMatch = workingContent.match(/<template\b(?![^>]*(?:\b(?:id|x-for|x-if|@for|@if|:for|:if)\s*=|\s#[\w-]|\bv-slot|\bslot\s*=))[^>]*>([\s\S]*?)<\/template>/i);
545
+ const templateMatch = workingContent.match(/<template\b(?![^>]*(?:\b(?:id|x-for|x-if|x-else|@for|@if|@else|:for|:if|:else)\s*=|\s#[\w-]|\bv-slot|\bslot\s*=))[^>]*>([\s\S]*?)<\/template>/i);
546
546
  if (templateMatch)
547
547
  workingContent = templateMatch[1].trim();
548
548
  const styleMatch = partialContent.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "").match(/<style\b([^>]*)>([\s\S]*?)<\/style>/i);
@@ -11,6 +11,21 @@ export declare function extractParenthesizedExpression(source: string, startPos:
11
11
  endPos: number
12
12
  } | null;
13
13
  export declare function extractParenthesizedExpressionDetailed(source: string, startPos: number): ExtractParenResult;
14
+ /**
15
+ * Whether `pos` in `source` falls INSIDE an HTML tag (`<...>`) — i.e. the nearest
16
+ * angle bracket looking backwards is an unclosed `<`.
17
+ *
18
+ * Directive tokens (`@if`/`@elseif`/`@else`/`@endif`) only ever occur in text
19
+ * content, never inside a tag. The reactive-signal pass, however, rewrites a
20
+ * NESTED reactive conditional into HTML-attribute markers BEFORE this server pass
21
+ * runs — e.g. `@if (isPro())A@else B@endif` becomes
22
+ * `<template @if="isPro()">A</template><template @else>B</template>`. Without this
23
+ * guard the branch scanner matches that `@else` ATTRIBUTE as the enclosing server
24
+ * `@if`'s top-level `@else`, mismatching branch/`@endif` boundaries and corrupting
25
+ * the rest of the template. Skipping tag-interior tokens keeps the two passes from
26
+ * disagreeing on what is a directive.
27
+ */
28
+ export declare function isInsideTag(source: string, pos: number): boolean;
14
29
  /**
15
30
  * Find the matching end tag for a directive, handling nested instances
16
31
  *
@@ -14,6 +14,12 @@ export function extractParenthesizedExpressionDetailed(source, startPos) {
14
14
  return { ok: !1, reason: "unclosed-paren", pos };
15
15
  return { ok: !0, expression: source.slice(pos + 1, closePos), endPos: closePos + 1 };
16
16
  }
17
+ export function isInsideTag(source, pos) {
18
+ const lastOpen = source.lastIndexOf("<", pos);
19
+ if (lastOpen === -1)
20
+ return !1;
21
+ return lastOpen > source.lastIndexOf(">", pos);
22
+ }
17
23
  export function findMatchingEndTag(source, startName, endName, startPos) {
18
24
  let depth = 1, pos = startPos;
19
25
  const openPattern = new RegExp(`@${startName}\\s*\\(`, "g"), closePattern = new RegExp(`@${endName}(?![a-z])`, "g");
@@ -52,6 +58,10 @@ export function parseConditionalBlock(source, startPos) {
52
58
  break;
53
59
  currentPos = atIdx;
54
60
  const remaining = fullContent.substring(atIdx);
61
+ if (isInsideTag(fullContent, atIdx)) {
62
+ currentPos++;
63
+ continue;
64
+ }
55
65
  if (/^@if\s*\(/.test(remaining)) {
56
66
  nestedDepth++;
57
67
  currentPos++;