@vesk/vesk-cli 0.2.46 → 0.2.48

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 (2) hide show
  1. package/dist/cli.js +523 -338
  2. package/package.json +5 -5
package/dist/cli.js CHANGED
@@ -2400,13 +2400,13 @@ function normText(el) {
2400
2400
  }
2401
2401
  function collectElements(rootEl) {
2402
2402
  const out = [];
2403
- (function walk7(n) {
2403
+ (function walk8(n) {
2404
2404
  const kids = n.childNodes;
2405
2405
  for (let i = 0; i < kids.length; i++) {
2406
2406
  const c = kids[i];
2407
2407
  if (c.nodeType === 1) {
2408
2408
  out.push(c);
2409
- walk7(c);
2409
+ walk8(c);
2410
2410
  }
2411
2411
  }
2412
2412
  })(rootEl);
@@ -19045,14 +19045,40 @@ function depsFresh(cachedVal) {
19045
19045
  }
19046
19046
  return true;
19047
19047
  }
19048
- function readSsrSource(absPath) {
19048
+ function evict(cache2) {
19049
+ if (cache2.size <= BUILD_CACHE_MAX) return;
19050
+ let dropped = 0;
19051
+ for (const key of cache2.keys()) {
19052
+ cache2.delete(key);
19053
+ if (++dropped >= BUILD_CACHE_EVICT) break;
19054
+ }
19055
+ }
19056
+ function readSourceCached(absPath) {
19057
+ let mtimeMs;
19058
+ try {
19059
+ mtimeMs = statSync(absPath).mtimeMs;
19060
+ } catch {
19061
+ return null;
19062
+ }
19063
+ const hit = rawSourceCache.get(absPath);
19064
+ if (hit && hit.mtimeMs === mtimeMs) return hit.raw;
19049
19065
  let raw2;
19050
19066
  try {
19051
19067
  raw2 = readFileSync2(absPath, "utf-8");
19052
- } catch (err) {
19053
- console.warn(`[vesk] SSR: failed to read ${absPath}: ${err?.message ?? String(err)}`);
19068
+ } catch {
19069
+ return null;
19070
+ }
19071
+ rawSourceCache.set(absPath, { mtimeMs, raw: raw2 });
19072
+ evict(rawSourceCache);
19073
+ return raw2;
19074
+ }
19075
+ function readSsrSource(absPath) {
19076
+ const cachedRaw = readSourceCached(absPath);
19077
+ if (cachedRaw === null) {
19078
+ console.warn(`[vesk] SSR: failed to read ${absPath}`);
19054
19079
  return null;
19055
19080
  }
19081
+ const raw2 = cachedRaw;
19056
19082
  let ast = null;
19057
19083
  try {
19058
19084
  ast = parse4(raw2, { filename: absPath });
@@ -19712,23 +19738,40 @@ function collectModuleBundled(absPath, collector) {
19712
19738
  collector.modules.push({ key, code: `module.exports = ${raw2};`, dir, deps: {} });
19713
19739
  return key;
19714
19740
  }
19715
- const src2 = readSsrSource(absPath);
19716
- if (!src2 || !src2.ast) {
19717
- const raw2 = src2 ? src2.raw : "// unreadable during build\nmodule.exports = {};";
19718
- collector.modules.push({ key, code: raw2, dir, deps: {} });
19719
- return key;
19741
+ let mtimeMs = -1;
19742
+ try {
19743
+ mtimeMs = statSync(absPath).mtimeMs;
19744
+ } catch {
19745
+ }
19746
+ const cached = mtimeMs >= 0 ? bundledCodeCache.get(absPath) : void 0;
19747
+ let code;
19748
+ let specifiers;
19749
+ if (cached && cached.mtimeMs === mtimeMs) {
19750
+ code = cached.code;
19751
+ specifiers = cached.specifiers;
19752
+ } else {
19753
+ const src2 = readSsrSource(absPath);
19754
+ if (!src2 || !src2.ast) {
19755
+ const raw2 = src2 ? src2.raw : "// unreadable during build\nmodule.exports = {};";
19756
+ collector.modules.push({ key, code: raw2, dir, deps: {} });
19757
+ return key;
19758
+ }
19759
+ let stripped = src2.ast;
19760
+ if (hasTsSyntax(src2.ast)) stripped = stripTsTypes(src2.ast);
19761
+ stripped.body = (stripped.body || []).filter((n) => n ? !isTypeOnlyStatement(n) : false);
19762
+ specifiers = [...collectModuleSpecifiers(src2.ast)];
19763
+ code = esmToCjs(stripped.body);
19764
+ bundledCodeCache.set(absPath, { mtimeMs, code, specifiers });
19765
+ evict(bundledCodeCache);
19720
19766
  }
19721
- let stripped = src2.ast;
19722
- if (hasTsSyntax(src2.ast)) stripped = stripTsTypes(src2.ast);
19723
- stripped.body = (stripped.body || []).filter((n) => n ? !isTypeOnlyStatement(n) : false);
19724
19767
  const deps = {};
19725
- for (const spec of collectModuleSpecifiers(src2.ast)) {
19768
+ for (const spec of specifiers) {
19726
19769
  if (!isRelativeSpec(spec)) continue;
19727
19770
  const depPath = resolveSsrModule(spec, dir);
19728
19771
  if (!depPath) continue;
19729
19772
  deps[spec] = collectModuleBundled(depPath, collector);
19730
19773
  }
19731
- collector.modules.push({ key, code: esmToCjs(stripped.body), dir, deps });
19774
+ collector.modules.push({ key, code, dir, deps });
19732
19775
  return key;
19733
19776
  }
19734
19777
  function collectModuleBundle(importStrs, fromDir, collector) {
@@ -19748,7 +19791,7 @@ function collectModuleBundle(importStrs, fromDir, collector) {
19748
19791
  }
19749
19792
  return bindings;
19750
19793
  }
19751
- var RUNTIME_PREFIXES, EXTENSIONS, BUILTIN_PREFIX, BUILTIN_CACHE, MODULE_CACHE, MAX_CACHE_ENTRIES, depStack, EVALUATING, EMPTY_ALIASES, ALIAS_CACHE, exportCounter;
19794
+ var RUNTIME_PREFIXES, EXTENSIONS, BUILTIN_PREFIX, BUILTIN_CACHE, MODULE_CACHE, MAX_CACHE_ENTRIES, depStack, rawSourceCache, BUILD_CACHE_MAX, BUILD_CACHE_EVICT, EVALUATING, EMPTY_ALIASES, ALIAS_CACHE, exportCounter, bundledCodeCache;
19752
19795
  var init_module_imports = __esm({
19753
19796
  "../compiler/src/module-imports.ts"() {
19754
19797
  "use strict";
@@ -19762,10 +19805,14 @@ var init_module_imports = __esm({
19762
19805
  MODULE_CACHE = /* @__PURE__ */ new Map();
19763
19806
  MAX_CACHE_ENTRIES = 256;
19764
19807
  depStack = [];
19808
+ rawSourceCache = /* @__PURE__ */ new Map();
19809
+ BUILD_CACHE_MAX = 8192;
19810
+ BUILD_CACHE_EVICT = 2048;
19765
19811
  EVALUATING = /* @__PURE__ */ new Map();
19766
19812
  EMPTY_ALIASES = { exact: /* @__PURE__ */ new Map(), wildcard: [] };
19767
19813
  ALIAS_CACHE = /* @__PURE__ */ new Map();
19768
19814
  exportCounter = 0;
19815
+ bundledCodeCache = /* @__PURE__ */ new Map();
19769
19816
  }
19770
19817
  });
19771
19818
 
@@ -28693,273 +28740,6 @@ var init_esbuild_fallback = __esm({
28693
28740
  }
28694
28741
  });
28695
28742
 
28696
- // ../compiler/src/server-head.ts
28697
- function isHtmlNameChar(ch) {
28698
- const code = ch.charCodeAt(0);
28699
- return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || ch === "-";
28700
- }
28701
- function isAttrBoundaryChar(ch) {
28702
- return isWhitespaceChar(ch) || ch === "=" || ch === "/" || ch === ">";
28703
- }
28704
- function isValueBoundaryChar(ch) {
28705
- return isWhitespaceChar(ch) || ch === "/" || ch === ">";
28706
- }
28707
- function evaluateLocals(comp, props) {
28708
- const locals2 = {};
28709
- for (const node of comp.body) {
28710
- if (node instanceof RuntimeStatement && node.ast) {
28711
- const stmt = node.ast;
28712
- if (stmt.type === "VariableDeclaration") {
28713
- for (const decl of stmt.declarations) {
28714
- if (decl.id.type === "Identifier" && decl.init && node.source) {
28715
- const name = decl.id.name;
28716
- const initSrc = node.source.slice(decl.init.start, decl.init.end);
28717
- try {
28718
- const fn = new Function("props", "return (" + initSrc + ")");
28719
- locals2[name] = fn(props);
28720
- } catch {
28721
- }
28722
- }
28723
- }
28724
- }
28725
- }
28726
- }
28727
- return locals2;
28728
- }
28729
- function headElementKey(node, props, locals2) {
28730
- if (!(node instanceof StaticNode)) return null;
28731
- const tag = node.tag;
28732
- if (tag === "title") return "title";
28733
- if (tag === "base") return "base";
28734
- const attrMap = new Map(node.attributes.map((a) => [a.name, a.value]));
28735
- for (const child of node.children) {
28736
- if (child instanceof DynamicBinding && child.kind === "attribute" && child.target && child.target !== "ref") {
28737
- try {
28738
- attrMap.set(child.target, String(tryEvalExpr(child.expression.raw, props, locals2)));
28739
- } catch {
28740
- }
28741
- }
28742
- }
28743
- if (tag === "meta") {
28744
- if (attrMap.has("name")) return `meta[name=${attrMap.get("name")}]`;
28745
- if (attrMap.has("property")) return `meta[property=${attrMap.get("property")}]`;
28746
- if (attrMap.has("charset")) return "meta[charset]";
28747
- if (attrMap.has("http-equiv")) return `meta[http-equiv=${attrMap.get("http-equiv")}]`;
28748
- return null;
28749
- }
28750
- if (tag === "link") {
28751
- if (attrMap.has("href")) return `link[href=${attrMap.get("href")}]`;
28752
- if (attrMap.has("id")) return `link[id=${attrMap.get("id")}]`;
28753
- return null;
28754
- }
28755
- if (tag === "script") {
28756
- if (attrMap.has("src")) return `script[src=${attrMap.get("src")}]`;
28757
- return null;
28758
- }
28759
- if (tag === "style") return null;
28760
- return null;
28761
- }
28762
- function headIsReconcilable(tag, attrMap) {
28763
- if (!HEAD_RECONCILE_TAGS.has(tag)) return false;
28764
- if (tag === "meta" && attrMap.has("charset")) return false;
28765
- return true;
28766
- }
28767
- function irNodeToHeadHtml(node, props, locals2 = {}, reconcileable = false) {
28768
- if (node instanceof StaticNode) {
28769
- const attrMap = new Map(node.attributes.map((a) => [a.name, a.value]));
28770
- for (const child of node.children) {
28771
- if (child instanceof DynamicBinding && child.kind === "attribute" && child.target && child.target !== "ref") {
28772
- try {
28773
- const val = tryEvalExpr(child.expression.raw, props, locals2);
28774
- attrMap.set(child.target, String(val));
28775
- } catch {
28776
- }
28777
- }
28778
- }
28779
- const marker = reconcileable && headIsReconcilable(node.tag, attrMap) ? ` ${HEAD_RECONCILE_MARKER}` : "";
28780
- const attrs = [...attrMap.entries()].map(([k, v]) => ` ${k}="${escapeHtml(v)}"`).join("");
28781
- if (node.selfClosing) return `<${node.tag}${attrs}${marker} />`;
28782
- const inner = node.children.filter((c) => !(c instanceof DynamicBinding && c.kind === "attribute" && c.target !== "ref")).map((c) => irNodeToHeadHtml(c, props, locals2, false)).join("");
28783
- return `<${node.tag}${attrs}${marker}>${inner}</${node.tag}>`;
28784
- }
28785
- if (node instanceof TextNode) return node.value;
28786
- if (node instanceof DynamicBinding) {
28787
- try {
28788
- const val = tryEvalExpr(node.expression.raw, props, locals2);
28789
- return escapeHtml(String(val));
28790
- } catch {
28791
- return "";
28792
- }
28793
- }
28794
- return "";
28795
- }
28796
- function renderHeadHtml(comp, props = {}) {
28797
- const locals2 = evaluateLocals(comp, props);
28798
- const seen = /* @__PURE__ */ new Set();
28799
- const parts = [];
28800
- for (const node of comp.body) {
28801
- if (node instanceof HeadBlock) {
28802
- for (const child of node.children) {
28803
- const key = headElementKey(child, props, locals2);
28804
- if (key !== null && seen.has(key)) continue;
28805
- if (key !== null) seen.add(key);
28806
- parts.push(irNodeToHeadHtml(child, props, locals2, true));
28807
- }
28808
- }
28809
- }
28810
- return parts.join("\n");
28811
- }
28812
- function scanHeadTag(html, lt) {
28813
- let i = lt + 1;
28814
- if (html[i] === "/") i++;
28815
- const nameStart = i;
28816
- while (i < html.length && isHtmlNameChar(html[i])) i++;
28817
- const tag = html.slice(nameStart, i).toLowerCase();
28818
- if (!tag) return null;
28819
- const attrs = /* @__PURE__ */ new Map();
28820
- let selfClosing = false;
28821
- while (i < html.length) {
28822
- while (i < html.length && isWhitespaceChar(html[i])) i++;
28823
- if (html[i] === ">") {
28824
- i++;
28825
- break;
28826
- }
28827
- if (html[i] === "/" && html[i + 1] === ">") {
28828
- selfClosing = true;
28829
- i += 2;
28830
- break;
28831
- }
28832
- if (i >= html.length || html[i] === ">" || html[i] === "/") continue;
28833
- const aStart = i;
28834
- while (i < html.length && !isAttrBoundaryChar(html[i])) i++;
28835
- const aName = html.slice(aStart, i).toLowerCase();
28836
- while (i < html.length && isWhitespaceChar(html[i])) i++;
28837
- let value = "";
28838
- if (html[i] === "=") {
28839
- i++;
28840
- while (i < html.length && isWhitespaceChar(html[i])) i++;
28841
- const q = html[i];
28842
- if (q === '"' || q === "'") {
28843
- i++;
28844
- const vStart = i;
28845
- while (i < html.length && html[i] !== q) i++;
28846
- value = html.slice(vStart, i);
28847
- if (i < html.length) i++;
28848
- } else {
28849
- const vStart = i;
28850
- while (i < html.length && !isValueBoundaryChar(html[i])) i++;
28851
- value = html.slice(vStart, i);
28852
- }
28853
- }
28854
- if (aName) attrs.set(aName, value);
28855
- }
28856
- let raw2 = html.slice(lt, i);
28857
- const nonVoidTags = /* @__PURE__ */ new Set(["title", "script", "style", "noscript"]);
28858
- if (!selfClosing && nonVoidTags.has(tag)) {
28859
- const closeTag = html.indexOf("</" + tag, i);
28860
- if (closeTag !== -1) {
28861
- const end = html.indexOf(">", closeTag);
28862
- if (end !== -1) {
28863
- raw2 = html.slice(lt, end + 1);
28864
- i = end + 1;
28865
- }
28866
- }
28867
- }
28868
- return { raw: raw2, tag, attrs, selfClosing, end: i };
28869
- }
28870
- function parseHeadTags(html) {
28871
- const entries = [];
28872
- let i = 0;
28873
- while (i < html.length) {
28874
- const lt = html.indexOf("<", i);
28875
- if (lt === -1) break;
28876
- if (html.startsWith("<!--", lt)) {
28877
- const close = html.indexOf("-->", lt + 4);
28878
- i = close === -1 ? html.length : close + 3;
28879
- continue;
28880
- }
28881
- const entry = scanHeadTag(html, lt);
28882
- if (!entry) break;
28883
- entries.push(entry);
28884
- i = entry.end;
28885
- }
28886
- return entries;
28887
- }
28888
- function mergeHeadHtml(pageHead, layoutHead) {
28889
- const extractKey = (entry) => {
28890
- if (entry.tag === "title") return "title";
28891
- if (entry.tag === "base") {
28892
- const h = entry.attrs.get("href");
28893
- return h !== void 0 ? `base[href=${h}]` : "base";
28894
- }
28895
- if (entry.tag === "meta") {
28896
- const n = entry.attrs.get("name");
28897
- if (n !== void 0) return `meta[name=${n}]`;
28898
- const p = entry.attrs.get("property");
28899
- if (p !== void 0) return `meta[property=${p}]`;
28900
- if (entry.attrs.has("charset")) return "meta[charset]";
28901
- return null;
28902
- }
28903
- if (entry.tag === "link") {
28904
- const h = entry.attrs.get("href");
28905
- if (h !== void 0) return `link[href=${h}]`;
28906
- return null;
28907
- }
28908
- if (entry.tag === "script") {
28909
- const s = entry.attrs.get("src");
28910
- if (s !== void 0) return `script[src=${s}]`;
28911
- return null;
28912
- }
28913
- return null;
28914
- };
28915
- const layoutEntries = parseHeadTags(layoutHead);
28916
- const pageEntries = parseHeadTags(pageHead);
28917
- const merged = /* @__PURE__ */ new Map();
28918
- for (const tag of layoutEntries) {
28919
- const key = extractKey(tag);
28920
- if (key) merged.set(key, { html: tag.raw, source: "layout" });
28921
- }
28922
- const conflicts = [];
28923
- for (const tag of pageEntries) {
28924
- const key = extractKey(tag);
28925
- if (key) {
28926
- if (merged.has(key) && merged.get(key).source === "page") {
28927
- conflicts.push({ key, message: `Sibling conflict for <head> key "${key}":
28928
- ${merged.get(key).html}
28929
- ${tag.raw}` });
28930
- }
28931
- merged.set(key, { html: tag.raw, source: "page" });
28932
- }
28933
- }
28934
- const order = ["title", "base", "meta", "link", "script", "style"];
28935
- const sorted = [...merged.values()].sort((a, b) => {
28936
- const ak = [...merged.entries()].find((e) => e[1] === a)?.[0] || "";
28937
- const bk = [...merged.entries()].find((e) => e[1] === b)?.[0] || "";
28938
- const ai = order.findIndex((o) => ak.startsWith(o));
28939
- const bi = order.findIndex((o) => bk.startsWith(o));
28940
- return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi);
28941
- });
28942
- const unkeyed = [];
28943
- for (const e of [...layoutEntries, ...pageEntries]) {
28944
- if (extractKey(e) === null && !unkeyed.includes(e.raw)) unkeyed.push(e.raw);
28945
- }
28946
- return {
28947
- html: [...sorted.map((e) => e.html), ...unkeyed].join("\n"),
28948
- conflicts
28949
- };
28950
- }
28951
- var HEAD_RECONCILE_MARKER, HEAD_RECONCILE_TAGS;
28952
- var init_server_head = __esm({
28953
- "../compiler/src/server-head.ts"() {
28954
- "use strict";
28955
- init_ir();
28956
- init_server_utils();
28957
- init_scan();
28958
- HEAD_RECONCILE_MARKER = "data-vesk-head";
28959
- HEAD_RECONCILE_TAGS = /* @__PURE__ */ new Set(["title", "meta", "link", "base", "style"]);
28960
- }
28961
- });
28962
-
28963
28743
  // ../compiler/src/actions.ts
28964
28744
  import { walk as walk3 } from "zimmerframe";
28965
28745
  import { print as print4 } from "esrap";
@@ -31275,6 +31055,409 @@ var init_client_codegen = __esm({
31275
31055
  }
31276
31056
  });
31277
31057
 
31058
+ // ../compiler/src/server-head.ts
31059
+ import { walk as walk5 } from "zimmerframe";
31060
+ function isHtmlNameChar(ch) {
31061
+ const code = ch.charCodeAt(0);
31062
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || ch === "-";
31063
+ }
31064
+ function isAttrBoundaryChar(ch) {
31065
+ return isWhitespaceChar(ch) || ch === "=" || ch === "/" || ch === ">";
31066
+ }
31067
+ function isValueBoundaryChar(ch) {
31068
+ return isWhitespaceChar(ch) || ch === "/" || ch === ">";
31069
+ }
31070
+ function headCell(value) {
31071
+ const cell = {
31072
+ __vskHeadValue: value,
31073
+ toString() {
31074
+ return String(cell.__vskHeadValue);
31075
+ },
31076
+ // Present so `+count` / `String(count)` on the cell itself still yields the
31077
+ // value; the return type is widened because `valueOf` must return `this`.
31078
+ valueOf() {
31079
+ return cell;
31080
+ }
31081
+ };
31082
+ return cell;
31083
+ }
31084
+ function headEvalScope(ctx2) {
31085
+ return { ...ctx2.scope, ...ctx2.locals, ...headRuntimeShims() };
31086
+ }
31087
+ function evalHeadExpression(expression, ctx2) {
31088
+ const code = transformTracked(expression, ctx2.tracked);
31089
+ return tryEvalExpr(code, ctx2.props, headEvalScope(ctx2));
31090
+ }
31091
+ function evalWithScope(raw2, props, scope2) {
31092
+ const names = Object.keys(scope2);
31093
+ const fn = new Function("props", ...names, "return (" + raw2 + ")");
31094
+ return fn(props, ...names.map((n) => scope2[n]));
31095
+ }
31096
+ function identifiersOf(ast, into) {
31097
+ if (!ast || typeof ast !== "object") return;
31098
+ walk5(ast, null, {
31099
+ Identifier(n, context) {
31100
+ const parent = context.path.at(-1);
31101
+ if (parent) {
31102
+ if (parent.type === "MemberExpression" && !parent.computed && parent.property === n) return context.next();
31103
+ if (parent.type === "Property" && parent.key === n) return context.next();
31104
+ }
31105
+ into.add(n.name);
31106
+ return context.next();
31107
+ }
31108
+ });
31109
+ }
31110
+ function collectHeadExprs(node, out) {
31111
+ if (node instanceof StaticNode) {
31112
+ for (const child of node.children) {
31113
+ if (child instanceof DynamicBinding) out.push(child.expression);
31114
+ else collectHeadExprs(child, out);
31115
+ }
31116
+ }
31117
+ }
31118
+ function declaredNames(comp) {
31119
+ const out = /* @__PURE__ */ new Map();
31120
+ for (const node of comp.body) {
31121
+ if (node instanceof TrackDecl) {
31122
+ const cellName = node.rawName || node.name;
31123
+ let initAst = null;
31124
+ try {
31125
+ initAst = parse4(node.init);
31126
+ } catch {
31127
+ }
31128
+ const entry = { kind: "track", initSrc: node.init, initAst, names: [cellName] };
31129
+ out.set(cellName, entry);
31130
+ if (node.name !== cellName) {
31131
+ out.set(node.name, entry);
31132
+ entry.names.push(node.name);
31133
+ }
31134
+ } else if (node instanceof RuntimeStatement && node.ast) {
31135
+ const stmt = node.ast;
31136
+ if (stmt.type !== "VariableDeclaration") continue;
31137
+ for (const decl of stmt.declarations) {
31138
+ if (decl.id.type !== "Identifier" || !decl.init || !node.source) continue;
31139
+ out.set(decl.id.name, {
31140
+ kind: "const",
31141
+ initSrc: node.source.slice(decl.init.start, decl.init.end),
31142
+ initAst: decl.init,
31143
+ names: [decl.id.name]
31144
+ });
31145
+ }
31146
+ }
31147
+ }
31148
+ return out;
31149
+ }
31150
+ function headNeededNames(comp) {
31151
+ const wanted = /* @__PURE__ */ new Set();
31152
+ for (const node of comp.body) {
31153
+ if (!(node instanceof HeadBlock)) continue;
31154
+ const exprs = [];
31155
+ for (const child of node.children) collectHeadExprs(child, exprs);
31156
+ for (const e of exprs) identifiersOf(e.ast, wanted);
31157
+ }
31158
+ const declared = declaredNames(comp);
31159
+ const needed = /* @__PURE__ */ new Set();
31160
+ const queue = [...wanted].filter((n) => declared.has(n));
31161
+ while (queue.length > 0) {
31162
+ const name = queue.shift();
31163
+ if (needed.has(name)) continue;
31164
+ needed.add(name);
31165
+ const entry = declared.get(name);
31166
+ if (!entry) continue;
31167
+ const deps = /* @__PURE__ */ new Set();
31168
+ identifiersOf(entry.initAst, deps);
31169
+ for (const d of deps) {
31170
+ if (declared.has(d) && !needed.has(d)) queue.push(d);
31171
+ }
31172
+ }
31173
+ return needed;
31174
+ }
31175
+ function evaluateLocals(comp, props, scope2 = {}, tracked2 = /* @__PURE__ */ new Map(), needed = null) {
31176
+ const locals2 = {};
31177
+ const wanted = (name) => needed === null || needed.has(name);
31178
+ for (const node of comp.body) {
31179
+ if (node instanceof TrackDecl) {
31180
+ const cellName = node.rawName || node.name;
31181
+ if (!wanted(cellName) && !wanted(node.name)) continue;
31182
+ const init = transformTrackedInit(node.init, tracked2);
31183
+ let value;
31184
+ try {
31185
+ value = evalWithScope(init, props, { ...scope2, ...locals2, ...headRuntimeShims() });
31186
+ } catch {
31187
+ value = void 0;
31188
+ }
31189
+ const cell = headCell(value);
31190
+ if (node.name !== cellName) locals2[node.name] = cell;
31191
+ locals2[cellName] = cell;
31192
+ continue;
31193
+ }
31194
+ if (node instanceof RuntimeStatement && node.ast) {
31195
+ const stmt = node.ast;
31196
+ if (stmt.type === "VariableDeclaration") {
31197
+ for (const decl of stmt.declarations) {
31198
+ if (decl.id.type === "Identifier" && decl.init && node.source) {
31199
+ const name = decl.id.name;
31200
+ if (!wanted(name)) continue;
31201
+ const initSrc = node.source.slice(decl.init.start, decl.init.end);
31202
+ try {
31203
+ locals2[name] = evalWithScope(initSrc, props, {
31204
+ ...scope2,
31205
+ ...locals2,
31206
+ ...headRuntimeShims()
31207
+ });
31208
+ } catch {
31209
+ }
31210
+ }
31211
+ }
31212
+ }
31213
+ }
31214
+ }
31215
+ return locals2;
31216
+ }
31217
+ function headElementKey(node, ctx2) {
31218
+ if (!(node instanceof StaticNode)) return null;
31219
+ const tag = node.tag;
31220
+ if (tag === "title") return "title";
31221
+ if (tag === "base") return "base";
31222
+ const attrMap = new Map(node.attributes.map((a) => [a.name, a.value]));
31223
+ for (const child of node.children) {
31224
+ if (child instanceof DynamicBinding && child.kind === "attribute" && child.target && child.target !== "ref") {
31225
+ try {
31226
+ attrMap.set(child.target, String(evalHeadExpression(child.expression, ctx2)));
31227
+ } catch {
31228
+ }
31229
+ }
31230
+ }
31231
+ if (tag === "meta") {
31232
+ if (attrMap.has("name")) return `meta[name=${attrMap.get("name")}]`;
31233
+ if (attrMap.has("property")) return `meta[property=${attrMap.get("property")}]`;
31234
+ if (attrMap.has("charset")) return "meta[charset]";
31235
+ if (attrMap.has("http-equiv")) return `meta[http-equiv=${attrMap.get("http-equiv")}]`;
31236
+ return null;
31237
+ }
31238
+ if (tag === "link") {
31239
+ if (attrMap.has("href")) return `link[href=${attrMap.get("href")}]`;
31240
+ if (attrMap.has("id")) return `link[id=${attrMap.get("id")}]`;
31241
+ return null;
31242
+ }
31243
+ if (tag === "script") {
31244
+ if (attrMap.has("src")) return `script[src=${attrMap.get("src")}]`;
31245
+ return null;
31246
+ }
31247
+ if (tag === "style") return null;
31248
+ return null;
31249
+ }
31250
+ function headIsReconcilable(tag, attrMap) {
31251
+ if (!HEAD_RECONCILE_TAGS.has(tag)) return false;
31252
+ if (tag === "meta" && attrMap.has("charset")) return false;
31253
+ return true;
31254
+ }
31255
+ function irNodeToHeadHtml(node, ctx2, reconcileable = false) {
31256
+ if (node instanceof StaticNode) {
31257
+ const attrMap = new Map(node.attributes.map((a) => [a.name, a.value]));
31258
+ for (const child of node.children) {
31259
+ if (child instanceof DynamicBinding && child.kind === "attribute" && child.target && child.target !== "ref") {
31260
+ try {
31261
+ attrMap.set(child.target, String(evalHeadExpression(child.expression, ctx2)));
31262
+ } catch {
31263
+ }
31264
+ }
31265
+ }
31266
+ const marker = reconcileable && headIsReconcilable(node.tag, attrMap) ? ` ${HEAD_RECONCILE_MARKER}` : "";
31267
+ const attrs = [...attrMap.entries()].map(([k, v]) => ` ${k}="${escapeHtml(v)}"`).join("");
31268
+ if (node.selfClosing) return `<${node.tag}${attrs}${marker} />`;
31269
+ const inner = node.children.filter((c) => !(c instanceof DynamicBinding && c.kind === "attribute" && c.target !== "ref")).map((c) => irNodeToHeadHtml(c, ctx2, false)).join("");
31270
+ return `<${node.tag}${attrs}${marker}>${inner}</${node.tag}>`;
31271
+ }
31272
+ if (node instanceof TextNode) return node.value;
31273
+ if (node instanceof DynamicBinding) {
31274
+ try {
31275
+ return escapeHtml(String(evalHeadExpression(node.expression, ctx2)));
31276
+ } catch {
31277
+ return "";
31278
+ }
31279
+ }
31280
+ return "";
31281
+ }
31282
+ function renderHeadHtml(comp, props = {}, scope2 = {}) {
31283
+ const tracked2 = collectTrackedNames(comp.body);
31284
+ const needed = headNeededNames(comp);
31285
+ const locals2 = evaluateLocals(comp, props, scope2, tracked2, needed);
31286
+ const ctx2 = { props, locals: locals2, tracked: tracked2, scope: scope2 };
31287
+ const seen = /* @__PURE__ */ new Set();
31288
+ const parts = [];
31289
+ for (const node of comp.body) {
31290
+ if (node instanceof HeadBlock) {
31291
+ for (const child of node.children) {
31292
+ const key = headElementKey(child, ctx2);
31293
+ if (key !== null && seen.has(key)) continue;
31294
+ if (key !== null) seen.add(key);
31295
+ parts.push(irNodeToHeadHtml(child, ctx2, true));
31296
+ }
31297
+ }
31298
+ }
31299
+ return parts.join("\n");
31300
+ }
31301
+ function scanHeadTag(html, lt) {
31302
+ let i = lt + 1;
31303
+ if (html[i] === "/") i++;
31304
+ const nameStart = i;
31305
+ while (i < html.length && isHtmlNameChar(html[i])) i++;
31306
+ const tag = html.slice(nameStart, i).toLowerCase();
31307
+ if (!tag) return null;
31308
+ const attrs = /* @__PURE__ */ new Map();
31309
+ let selfClosing = false;
31310
+ while (i < html.length) {
31311
+ while (i < html.length && isWhitespaceChar(html[i])) i++;
31312
+ if (html[i] === ">") {
31313
+ i++;
31314
+ break;
31315
+ }
31316
+ if (html[i] === "/" && html[i + 1] === ">") {
31317
+ selfClosing = true;
31318
+ i += 2;
31319
+ break;
31320
+ }
31321
+ if (i >= html.length || html[i] === ">" || html[i] === "/") continue;
31322
+ const aStart = i;
31323
+ while (i < html.length && !isAttrBoundaryChar(html[i])) i++;
31324
+ const aName = html.slice(aStart, i).toLowerCase();
31325
+ while (i < html.length && isWhitespaceChar(html[i])) i++;
31326
+ let value = "";
31327
+ if (html[i] === "=") {
31328
+ i++;
31329
+ while (i < html.length && isWhitespaceChar(html[i])) i++;
31330
+ const q = html[i];
31331
+ if (q === '"' || q === "'") {
31332
+ i++;
31333
+ const vStart = i;
31334
+ while (i < html.length && html[i] !== q) i++;
31335
+ value = html.slice(vStart, i);
31336
+ if (i < html.length) i++;
31337
+ } else {
31338
+ const vStart = i;
31339
+ while (i < html.length && !isValueBoundaryChar(html[i])) i++;
31340
+ value = html.slice(vStart, i);
31341
+ }
31342
+ }
31343
+ if (aName) attrs.set(aName, value);
31344
+ }
31345
+ let raw2 = html.slice(lt, i);
31346
+ const nonVoidTags = /* @__PURE__ */ new Set(["title", "script", "style", "noscript"]);
31347
+ if (!selfClosing && nonVoidTags.has(tag)) {
31348
+ const closeTag = html.indexOf("</" + tag, i);
31349
+ if (closeTag !== -1) {
31350
+ const end = html.indexOf(">", closeTag);
31351
+ if (end !== -1) {
31352
+ raw2 = html.slice(lt, end + 1);
31353
+ i = end + 1;
31354
+ }
31355
+ }
31356
+ }
31357
+ return { raw: raw2, tag, attrs, selfClosing, end: i };
31358
+ }
31359
+ function parseHeadTags(html) {
31360
+ const entries = [];
31361
+ let i = 0;
31362
+ while (i < html.length) {
31363
+ const lt = html.indexOf("<", i);
31364
+ if (lt === -1) break;
31365
+ if (html.startsWith("<!--", lt)) {
31366
+ const close = html.indexOf("-->", lt + 4);
31367
+ i = close === -1 ? html.length : close + 3;
31368
+ continue;
31369
+ }
31370
+ const entry = scanHeadTag(html, lt);
31371
+ if (!entry) break;
31372
+ entries.push(entry);
31373
+ i = entry.end;
31374
+ }
31375
+ return entries;
31376
+ }
31377
+ function mergeHeadHtml(pageHead, layoutHead) {
31378
+ const extractKey = (entry) => {
31379
+ if (entry.tag === "title") return "title";
31380
+ if (entry.tag === "base") {
31381
+ const h = entry.attrs.get("href");
31382
+ return h !== void 0 ? `base[href=${h}]` : "base";
31383
+ }
31384
+ if (entry.tag === "meta") {
31385
+ const n = entry.attrs.get("name");
31386
+ if (n !== void 0) return `meta[name=${n}]`;
31387
+ const p = entry.attrs.get("property");
31388
+ if (p !== void 0) return `meta[property=${p}]`;
31389
+ if (entry.attrs.has("charset")) return "meta[charset]";
31390
+ return null;
31391
+ }
31392
+ if (entry.tag === "link") {
31393
+ const h = entry.attrs.get("href");
31394
+ if (h !== void 0) return `link[href=${h}]`;
31395
+ return null;
31396
+ }
31397
+ if (entry.tag === "script") {
31398
+ const s = entry.attrs.get("src");
31399
+ if (s !== void 0) return `script[src=${s}]`;
31400
+ return null;
31401
+ }
31402
+ return null;
31403
+ };
31404
+ const layoutEntries = parseHeadTags(layoutHead);
31405
+ const pageEntries = parseHeadTags(pageHead);
31406
+ const merged = /* @__PURE__ */ new Map();
31407
+ for (const tag of layoutEntries) {
31408
+ const key = extractKey(tag);
31409
+ if (key) merged.set(key, { html: tag.raw, source: "layout" });
31410
+ }
31411
+ const conflicts = [];
31412
+ for (const tag of pageEntries) {
31413
+ const key = extractKey(tag);
31414
+ if (key) {
31415
+ if (merged.has(key) && merged.get(key).source === "page") {
31416
+ conflicts.push({ key, message: `Sibling conflict for <head> key "${key}":
31417
+ ${merged.get(key).html}
31418
+ ${tag.raw}` });
31419
+ }
31420
+ merged.set(key, { html: tag.raw, source: "page" });
31421
+ }
31422
+ }
31423
+ const order = ["title", "base", "meta", "link", "script", "style"];
31424
+ const sorted = [...merged.values()].sort((a, b) => {
31425
+ const ak = [...merged.entries()].find((e) => e[1] === a)?.[0] || "";
31426
+ const bk = [...merged.entries()].find((e) => e[1] === b)?.[0] || "";
31427
+ const ai = order.findIndex((o) => ak.startsWith(o));
31428
+ const bi = order.findIndex((o) => bk.startsWith(o));
31429
+ return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi);
31430
+ });
31431
+ const unkeyed = [];
31432
+ for (const e of [...layoutEntries, ...pageEntries]) {
31433
+ if (extractKey(e) === null && !unkeyed.includes(e.raw)) unkeyed.push(e.raw);
31434
+ }
31435
+ return {
31436
+ html: [...sorted.map((e) => e.html), ...unkeyed].join("\n"),
31437
+ conflicts
31438
+ };
31439
+ }
31440
+ var headRuntimeShims, HEAD_RECONCILE_MARKER, HEAD_RECONCILE_TAGS;
31441
+ var init_server_head = __esm({
31442
+ "../compiler/src/server-head.ts"() {
31443
+ "use strict";
31444
+ init_ir();
31445
+ init_server_utils();
31446
+ init_scan();
31447
+ init_parser();
31448
+ init_client_codegen();
31449
+ headRuntimeShims = () => ({
31450
+ track: (init) => headCell(init),
31451
+ derived: (fn) => headCell(typeof fn === "function" ? fn() : fn),
31452
+ get: (cell) => cell && typeof cell === "object" && "__vskHeadValue" in cell ? cell.__vskHeadValue : cell,
31453
+ peek: (cell) => cell && typeof cell === "object" && "__vskHeadValue" in cell ? cell.__vskHeadValue : cell,
31454
+ untrack: (fn) => typeof fn === "function" ? fn() : fn
31455
+ });
31456
+ HEAD_RECONCILE_MARKER = "data-vesk-head";
31457
+ HEAD_RECONCILE_TAGS = /* @__PURE__ */ new Set(["title", "meta", "link", "base", "style"]);
31458
+ }
31459
+ });
31460
+
31278
31461
  // ../compiler/src/server-jsgen.ts
31279
31462
  function sanitizeMarkerName(name) {
31280
31463
  return String(name).split("--").join("-").split("<").join("").split(">").join("");
@@ -32050,7 +32233,9 @@ function renderPage(source, componentName, props = {}, registry = /* @__PURE__ *
32050
32233
  }
32051
32234
  return {
32052
32235
  body: bodyHtml2,
32053
- head: renderHeadHtml(targetComp, ssrProps),
32236
+ // The component's own scope, so head expressions that read an import
32237
+ // resolve (see renderHeadHtml).
32238
+ head: renderHeadHtml(targetComp, ssrProps, scopedVesk(renderFn, __vesk)),
32054
32239
  props: ssrProps
32055
32240
  };
32056
32241
  })();
@@ -32061,7 +32246,7 @@ function renderPage(source, componentName, props = {}, registry = /* @__PURE__ *
32061
32246
  } finally {
32062
32247
  delete globalThis.__vsk_ssr;
32063
32248
  }
32064
- const headHtml = targetComp ? renderHeadHtml(targetComp, ssrProps) : "";
32249
+ const headHtml = targetComp ? renderHeadHtml(targetComp, ssrProps, scopedVesk(renderFn, __vesk)) : "";
32065
32250
  const pending = globalThis[`__vsk_ssr_promises_${renderToken}`];
32066
32251
  if (pending && pending.length > 0) {
32067
32252
  return (async () => {
@@ -32376,7 +32561,7 @@ function renderPageStream(source, componentName, props = {}, registry = /* @__PU
32376
32561
  }
32377
32562
  let streamHeadHtml = null;
32378
32563
  if (targetComp) {
32379
- let headHtml = renderHeadHtml(targetComp, ssrProps);
32564
+ let headHtml = renderHeadHtml(targetComp, ssrProps, scopedVesk(renderFn, __vesk));
32380
32565
  if (options.pageHead) {
32381
32566
  const merged = mergeHeadHtml(options.pageHead, headHtml);
32382
32567
  headHtml = merged.html;
@@ -33491,7 +33676,7 @@ async function generateSsgRoutes(routeTree, appDir, outDir, plugins, headExtra,
33491
33676
  return null;
33492
33677
  }
33493
33678
  }
33494
- async function walk7(nodes) {
33679
+ async function walk8(nodes) {
33495
33680
  for (const node of nodes) {
33496
33681
  if (node.page) {
33497
33682
  const pagePath = resolve15(appDir, node.sourceDir, "page.vsk");
@@ -33534,10 +33719,10 @@ async function generateSsgRoutes(routeTree, appDir, outDir, plugins, headExtra,
33534
33719
  }
33535
33720
  }
33536
33721
  }
33537
- await walk7(node.children || []);
33722
+ await walk8(node.children || []);
33538
33723
  }
33539
33724
  }
33540
- await walk7(routeTree);
33725
+ await walk8(routeTree);
33541
33726
  return results;
33542
33727
  }
33543
33728
  function generateSitemap(_routeTree, ssrRoutes, prerenderedRoutes, { siteUrl = "http://localhost:3000" } = {}) {
@@ -33553,15 +33738,15 @@ function generateSitemap(_routeTree, ssrRoutes, prerenderedRoutes, { siteUrl = "
33553
33738
  for (const r of prerenderedRoutes) {
33554
33739
  addUrl(r.path, "0.80", "weekly");
33555
33740
  }
33556
- function walk7(nodes) {
33741
+ function walk8(nodes) {
33557
33742
  for (const node of nodes) {
33558
33743
  if (node.page && !node.fullPath.includes(":")) {
33559
33744
  addUrl(node.fullPath, "0.64", "daily");
33560
33745
  }
33561
- walk7(node.children || []);
33746
+ walk8(node.children || []);
33562
33747
  }
33563
33748
  }
33564
- walk7(ssrRoutes);
33749
+ walk8(ssrRoutes);
33565
33750
  let xml = '<?xml version="1.0" encoding="UTF-8"?>\n';
33566
33751
  xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n';
33567
33752
  for (const u of urls) {
@@ -33688,7 +33873,7 @@ async function processImage(srcPath, outDir, baseName) {
33688
33873
  }
33689
33874
  function collectImageRefs(appDir) {
33690
33875
  const refs = [];
33691
- function walk7(dir) {
33876
+ function walk8(dir) {
33692
33877
  let entries;
33693
33878
  try {
33694
33879
  entries = readdirSync4(dir);
@@ -33701,7 +33886,7 @@ function collectImageRefs(appDir) {
33701
33886
  if (st.isDirectory()) {
33702
33887
  if (entry.startsWith("."))
33703
33888
  continue;
33704
- walk7(full);
33889
+ walk8(full);
33705
33890
  } else if (entry === "page.vsk") {
33706
33891
  const src2 = readFileSync18(full, "utf-8");
33707
33892
  const imgRegex = /<Image\s+src=["']([^"']+)["']/g;
@@ -33712,7 +33897,7 @@ function collectImageRefs(appDir) {
33712
33897
  }
33713
33898
  }
33714
33899
  }
33715
- walk7(appDir);
33900
+ walk8(appDir);
33716
33901
  return refs;
33717
33902
  }
33718
33903
  async function optimizeImages(appDir, outDir) {
@@ -34344,18 +34529,18 @@ function writePrerenderedStatic(prerenderedRoutes, platformStaticDir) {
34344
34529
  function listStaticDir(dir) {
34345
34530
  const out = [];
34346
34531
  if (!existsSync21(dir)) return out;
34347
- function walk7(d, prefix) {
34532
+ function walk8(d, prefix) {
34348
34533
  for (const entry of readdirSync6(d)) {
34349
34534
  const full = join14(d, entry);
34350
34535
  const rel = prefix ? `${prefix}/${entry}` : entry;
34351
34536
  if (statSync11(full).isDirectory()) {
34352
- walk7(full, rel);
34537
+ walk8(full, rel);
34353
34538
  } else {
34354
34539
  out.push({ rel, buffer: readFileSync20(full) });
34355
34540
  }
34356
34541
  }
34357
34542
  }
34358
- walk7(dir, "");
34543
+ walk8(dir, "");
34359
34544
  return out;
34360
34545
  }
34361
34546
  function mimeFor(path) {
@@ -39022,7 +39207,7 @@ import * as ts8 from "typescript";
39022
39207
  function walkProjectFiles(projectRoot) {
39023
39208
  const code = [];
39024
39209
  const js = [];
39025
- const walk7 = (dir) => {
39210
+ const walk8 = (dir) => {
39026
39211
  let entries = [];
39027
39212
  try {
39028
39213
  entries = readdirSync14(dir);
@@ -39040,7 +39225,7 @@ function walkProjectFiles(projectRoot) {
39040
39225
  if (st.isDirectory()) {
39041
39226
  if (SKIP_DIRS.has(e))
39042
39227
  continue;
39043
- walk7(p);
39228
+ walk8(p);
39044
39229
  } else if (e.endsWith(".vsk")) {
39045
39230
  code.push(p);
39046
39231
  } else if (e.endsWith(".ts") || e.endsWith(".tsx")) {
@@ -39054,7 +39239,7 @@ function walkProjectFiles(projectRoot) {
39054
39239
  }
39055
39240
  }
39056
39241
  };
39057
- walk7(projectRoot);
39242
+ walk8(projectRoot);
39058
39243
  return { code, js };
39059
39244
  }
39060
39245
  function isUnder(dir, file) {
@@ -40859,13 +41044,13 @@ function hydrateInvoke(planExpr) {
40859
41044
  function buildParamExtraction(node, urlParts) {
40860
41045
  const parts = [];
40861
41046
  let partIdx = Math.max(0, urlParts.length - 1);
40862
- function walk7(n) {
41047
+ function walk8(n) {
40863
41048
  if (n.fullPath === "/") {
40864
- for (const child of n.children || []) walk7(child);
41049
+ for (const child of n.children || []) walk8(child);
40865
41050
  return;
40866
41051
  }
40867
41052
  if (n.isGroup) {
40868
- for (const child of n.children || []) walk7(child);
41053
+ for (const child of n.children || []) walk8(child);
40869
41054
  return;
40870
41055
  }
40871
41056
  if (partIdx >= urlParts.length) return;
@@ -40879,15 +41064,15 @@ function buildParamExtraction(node, urlParts) {
40879
41064
  const paramName = n.path.startsWith(":") ? n.path.slice(1) : "param";
40880
41065
  parts.push(`${JSON.stringify(paramName)}: urlParts[${partIdx}]`);
40881
41066
  partIdx++;
40882
- for (const child of n.children || []) walk7(child);
41067
+ for (const child of n.children || []) walk8(child);
40883
41068
  return;
40884
41069
  }
40885
41070
  if (n.path === urlParts[partIdx]) {
40886
41071
  partIdx++;
40887
- for (const child of n.children || []) walk7(child);
41072
+ for (const child of n.children || []) walk8(child);
40888
41073
  }
40889
41074
  }
40890
- walk7(node);
41075
+ walk8(node);
40891
41076
  return parts;
40892
41077
  }
40893
41078
  function generateSsrFunction(routeNode, appDir, outDir, componentMap, options) {
@@ -43582,7 +43767,7 @@ async function build2(appDir, options) {
43582
43767
  await bundleRuntime(appDir, outDir);
43583
43768
  const ssrRoutes = [];
43584
43769
  const actionMap = {};
43585
- function walk7(nodes, ancestorLayouts = []) {
43770
+ function walk8(nodes, ancestorLayouts = []) {
43586
43771
  for (const node of nodes) {
43587
43772
  const isStandalone = node.standalone === true;
43588
43773
  let childAncestorLayouts = isStandalone ? [] : ancestorLayouts;
@@ -43626,10 +43811,10 @@ async function build2(appDir, options) {
43626
43811
  ssrRoutes.push(node);
43627
43812
  console.error(`vesk build: ssr \u2192 server/functions/${name}.js (${node.fullPath})${mwCode ? " [mw]" : ""}`);
43628
43813
  }
43629
- walk7(node.children || [], childAncestorLayouts);
43814
+ walk8(node.children || [], childAncestorLayouts);
43630
43815
  }
43631
43816
  }
43632
- walk7(routeTree);
43817
+ walk8(routeTree);
43633
43818
  markPhase("server runtime + ssr functions");
43634
43819
  const apiRoutes = [];
43635
43820
  function walkApi(nodes) {
@@ -43776,7 +43961,7 @@ import { WebSocketServer as WebSocketServer2 } from "ws";
43776
43961
 
43777
43962
  // ../compiler/dist/strip-ts.js
43778
43963
  init_parser();
43779
- import { walk as walk5 } from "zimmerframe";
43964
+ import { walk as walk6 } from "zimmerframe";
43780
43965
  import { print as print6 } from "esrap";
43781
43966
  import ts6 from "esrap/languages/ts";
43782
43967
  var TS_NODE_TYPES2 = /* @__PURE__ */ new Set([
@@ -43818,7 +44003,7 @@ function isTypeOnlySpecifier2(node) {
43818
44003
  }
43819
44004
  function hasTsSyntax2(ast) {
43820
44005
  let found = false;
43821
- walk5(ast, null, {
44006
+ walk6(ast, null, {
43822
44007
  _(node, context) {
43823
44008
  if (TS_NODE_TYPES2.has(node.type)) {
43824
44009
  found = true;
@@ -43856,7 +44041,7 @@ function isTypeOnlyStatement2(node) {
43856
44041
  return TYPE_ONLY_STATEMENTS2.has(node.type);
43857
44042
  }
43858
44043
  function stripTsTypes2(ast) {
43859
- return walk5(ast, null, {
44044
+ return walk6(ast, null, {
43860
44045
  TSAsExpression(node, context) {
43861
44046
  return context.visit(node.expression);
43862
44047
  },
@@ -44112,7 +44297,7 @@ init_tokens();
44112
44297
  init_vsk_imports();
44113
44298
  init_md_inline();
44114
44299
  init_strip_ts();
44115
- import { walk as walk6 } from "zimmerframe";
44300
+ import { walk as walk7 } from "zimmerframe";
44116
44301
  import { print as print7 } from "esrap";
44117
44302
  import ts7 from "esrap/languages/ts";
44118
44303
  import tsx2 from "esrap/languages/tsx";
@@ -44228,7 +44413,7 @@ function transformTracked2(irNode, tracked2) {
44228
44413
  return printAst2(stripTsTypes(ast));
44229
44414
  }
44230
44415
  const stripped = stripTsTypes(ast);
44231
- const transformed = walk6(stripped, tracked2, {
44416
+ const transformed = walk7(stripped, tracked2, {
44232
44417
  AssignmentExpression(node, context) {
44233
44418
  if (node.left.type === "Identifier") {
44234
44419
  const info = context.state.get(node.left.name);
@@ -44341,7 +44526,7 @@ function collectTrackedDeps2(value, tracked2) {
44341
44526
  return [];
44342
44527
  const found = [];
44343
44528
  const seen = /* @__PURE__ */ new Set();
44344
- walk6(ast, tracked2, {
44529
+ walk7(ast, tracked2, {
44345
44530
  Identifier(node, context) {
44346
44531
  const parent = context.path.at(-1);
44347
44532
  if (parent) {
@@ -44893,7 +45078,7 @@ function isReactiveExpression2(node, tracked2) {
44893
45078
  if (!ast)
44894
45079
  return false;
44895
45080
  let reactive = false;
44896
- walk6(ast, tracked2, {
45081
+ walk7(ast, tracked2, {
44897
45082
  Identifier(n, context) {
44898
45083
  if (reactive)
44899
45084
  return;
@@ -45583,7 +45768,7 @@ function emitForLoop2(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget)
45583
45768
  const seen = /* @__PURE__ */ new Set();
45584
45769
  const condAst = node.condition?.ast;
45585
45770
  if (condAst) {
45586
- walk6(condAst, tracked2, {
45771
+ walk7(condAst, tracked2, {
45587
45772
  Identifier(n, context) {
45588
45773
  const parent2 = context.path.at(-1);
45589
45774
  if (parent2) {
@@ -46261,7 +46446,7 @@ function astHasBinding2(ast, names) {
46261
46446
  if (!ast)
46262
46447
  return false;
46263
46448
  let found = false;
46264
- walk6(ast, null, {
46449
+ walk7(ast, null, {
46265
46450
  Identifier(node, context) {
46266
46451
  if (names.has(node.name))
46267
46452
  found = true;
@@ -46515,7 +46700,7 @@ function scanComponents(componentsDir) {
46515
46700
  const map = /* @__PURE__ */ new Map();
46516
46701
  if (!existsSync23(componentsDir))
46517
46702
  return map;
46518
- function walk7(dir, prefix) {
46703
+ function walk8(dir, prefix) {
46519
46704
  let entries;
46520
46705
  try {
46521
46706
  entries = readdirSync7(dir);
@@ -46532,7 +46717,7 @@ function scanComponents(componentsDir) {
46532
46717
  }
46533
46718
  if (stat.isDirectory()) {
46534
46719
  if (!entry.startsWith("_")) {
46535
- walk7(full, prefix ? prefix + capitalize(entry) : capitalize(entry));
46720
+ walk8(full, prefix ? prefix + capitalize(entry) : capitalize(entry));
46536
46721
  }
46537
46722
  } else if (entry.endsWith(".vsk")) {
46538
46723
  const name = prefix ? prefix + capitalize(entry.slice(0, -4)) : entry.slice(0, -4);
@@ -46542,7 +46727,7 @@ function scanComponents(componentsDir) {
46542
46727
  }
46543
46728
  }
46544
46729
  }
46545
- walk7(componentsDir, "");
46730
+ walk8(componentsDir, "");
46546
46731
  return map;
46547
46732
  }
46548
46733
  function scanDirectory(rootDir, dir, parentPath, options) {
@@ -46694,7 +46879,7 @@ function extractComponentName(dir, type, rootDir) {
46694
46879
  }
46695
46880
  function collectSources(tree) {
46696
46881
  const map = /* @__PURE__ */ new Map();
46697
- function walk7(nodes) {
46882
+ function walk8(nodes) {
46698
46883
  for (const node of nodes) {
46699
46884
  if (node.page)
46700
46885
  map.set(node.page, join15(node.sourceDir, "page.vsk"));
@@ -46710,10 +46895,10 @@ function collectSources(tree) {
46710
46895
  map.set(node.offline, join15(node.sourceDir, "offline.vsk"));
46711
46896
  if (node.network)
46712
46897
  map.set(node.network, join15(node.sourceDir, "network.vsk"));
46713
- walk7(node.children);
46898
+ walk8(node.children);
46714
46899
  }
46715
46900
  }
46716
- walk7(tree);
46901
+ walk8(tree);
46717
46902
  return map;
46718
46903
  }
46719
46904
  function matchUrl(tree, pathname) {
@@ -47208,16 +47393,16 @@ function parseCookies2(str3) {
47208
47393
  function collectMiddlewareChain(routeTree, url, appDir) {
47209
47394
  const parts = url.split("/").filter(Boolean);
47210
47395
  const chain = [];
47211
- function walk7(nodes, depth) {
47396
+ function walk8(nodes, depth) {
47212
47397
  for (const node of nodes) {
47213
47398
  if (node.isGroup) {
47214
- if (walk7(node.children, depth))
47399
+ if (walk8(node.children, depth))
47215
47400
  return true;
47216
47401
  continue;
47217
47402
  }
47218
47403
  if (node.fullPath === "/") {
47219
47404
  collectForNode(node);
47220
- return walk7(node.children, depth);
47405
+ return walk8(node.children, depth);
47221
47406
  }
47222
47407
  if (depth >= parts.length) {
47223
47408
  if (node.page) {
@@ -47255,16 +47440,16 @@ function collectMiddlewareChain(routeTree, url, appDir) {
47255
47440
  function tryCollectAndRecurse(node, depth) {
47256
47441
  collectForNode(node);
47257
47442
  if (node.children.length > 0) {
47258
- return walk7(node.children, depth + 1);
47443
+ return walk8(node.children, depth + 1);
47259
47444
  }
47260
47445
  return !!node.page;
47261
47446
  }
47262
47447
  const root3 = routeTree.find((n) => n.fullPath === "/");
47263
47448
  if (root3) {
47264
47449
  collectForNode(root3);
47265
- walk7(root3.children, 0);
47450
+ walk8(root3.children, 0);
47266
47451
  } else {
47267
- walk7(routeTree, 0);
47452
+ walk8(routeTree, 0);
47268
47453
  }
47269
47454
  return chain;
47270
47455
  }
@@ -50575,7 +50760,7 @@ function hasIdentifierAst(source, name) {
50575
50760
  if (!ast)
50576
50761
  return source.includes(name);
50577
50762
  let found = false;
50578
- function walk7(node) {
50763
+ function walk8(node) {
50579
50764
  if (!node || typeof node !== "object" || found)
50580
50765
  return;
50581
50766
  if (node.type === "Identifier" && node.name === name) {
@@ -50586,12 +50771,12 @@ function hasIdentifierAst(source, name) {
50586
50771
  const v = node[k];
50587
50772
  if (Array.isArray(v))
50588
50773
  for (const el of v)
50589
- walk7(el);
50774
+ walk8(el);
50590
50775
  else if (v && typeof v.type === "string")
50591
- walk7(v);
50776
+ walk8(v);
50592
50777
  }
50593
50778
  }
50594
- walk7(ast);
50779
+ walk8(ast);
50595
50780
  return found;
50596
50781
  }
50597
50782
  async function addPluginToConfig2(projectDir, pkg) {
@@ -54426,14 +54611,14 @@ function chainForPath(routeTree, pathname) {
54426
54611
  }
54427
54612
  function pageSourcesFor(appDirPath, routeTree) {
54428
54613
  const out = [];
54429
- function walk7(nodes) {
54614
+ function walk8(nodes) {
54430
54615
  for (const node of nodes) {
54431
54616
  if (node.page) out.push(resolve37(appDirPath, node.sourceDir, "page.vsk"));
54432
54617
  if (node.layout) out.push(resolve37(appDirPath, node.sourceDir, "layout.vsk"));
54433
- walk7(node.children);
54618
+ walk8(node.children);
54434
54619
  }
54435
54620
  }
54436
- walk7(routeTree);
54621
+ walk8(routeTree);
54437
54622
  return out;
54438
54623
  }
54439
54624
  function walkVskFiles(dir, out, seen) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vesk/vesk-cli",
3
- "version": "0.2.46",
3
+ "version": "0.2.48",
4
4
  "type": "module",
5
5
  "description": "Vesk — compiler-first framework for the post-VDOM web. vesk dev, vesk build.",
6
6
  "bin": {
@@ -8,10 +8,10 @@
8
8
  },
9
9
  "main": "./dist/cli.js",
10
10
  "dependencies": {
11
- "@vesk/adapter": "^0.2.46",
12
- "@vesk/compiler": "^0.2.46",
13
- "@vesk/plugin-tailwind": "^0.2.46",
14
- "@vesk/runtime": "^0.2.46",
11
+ "@vesk/adapter": "^0.2.48",
12
+ "@vesk/compiler": "^0.2.48",
13
+ "@vesk/plugin-tailwind": "^0.2.48",
14
+ "@vesk/runtime": "^0.2.48",
15
15
  "esrap": "^2.3.0",
16
16
  "typescript": "^5.8.0",
17
17
  "ws": "^8.18.0",