@vesk/vesk-cli 0.2.42 → 0.2.44

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 +1786 -608
  2. package/package.json +5 -5
package/dist/cli.js CHANGED
@@ -184,6 +184,39 @@ var init_errors = __esm({
184
184
  tip: isBuiltin ? `"${name}" is a Vesk built-in. Use it directly \u2014 no manual import needed.` : ""
185
185
  });
186
186
  }
187
+ /**
188
+ * A `.vsk` namespace is resolved at the JSX-tag level: `<ns.Icon />` looks
189
+ * the component up in the registry by its exported name, exactly like
190
+ * `import { Icon }`, and no module object is ever built. The two forms that
191
+ * genuinely need a real module object are reported here.
192
+ *
193
+ * - `nested` — `<ns.Sub.Icon />`. A `.vsk` module's exports are flat
194
+ * component names, so there is no object to walk into.
195
+ * - `value` — `ns.max` read as a value. Component tags resolve; plain value
196
+ * reads do not, because nothing binds `ns` at runtime.
197
+ */
198
+ static vskNamespaceMember(context = {}) {
199
+ const nested = context.form === "nested";
200
+ return new _VeskError(
201
+ nested ? "A `.vsk` namespace is flat, so `<ns.Sub.Icon />` cannot be resolved." : "A `.vsk` namespace resolves component tags only, so `ns.value` is not available.",
202
+ {
203
+ ...context,
204
+ code: context.code || "V0410",
205
+ suggestions: nested ? [
206
+ "Import the component by name: import { Icon } from './icons.vsk'",
207
+ "Import from the module that owns Sub: import * as Sub from './sub.vsk'"
208
+ ] : [
209
+ "Import the value by name: import { MAX } from './constants.vsk'",
210
+ "Move the value into a .ts module and import it from there \u2014 those are real ES modules with live bindings."
211
+ ],
212
+ nextSteps: [
213
+ "A `.vsk` tag resolves by component name in the global registry, not by module exports, so `import * as ns` + `<ns.Icon />` needs no module object.",
214
+ nested ? "Re-export with a flat name (`export { Icon }`) or import the component directly." : "Re-export the value under a flat name and import it directly, or keep the value in a .ts module."
215
+ ],
216
+ tip: "`<ns.Icon />` works; only nested paths and value reads need a real module namespace."
217
+ }
218
+ );
219
+ }
187
220
  static classDecl(context = {}) {
188
221
  return new _VeskError(
189
222
  "class declarations are not supported inside Vesk components.",
@@ -367,13 +400,30 @@ var init_ir = __esm({
367
400
  staticProps;
368
401
  loadFn;
369
402
  topLevelCode;
370
- constructor(components, imports = [], importedNames = /* @__PURE__ */ new Set(), staticProps = null, loadFn = null, topLevelCode = []) {
403
+ /**
404
+ * Same-file specifier exports (`export { A }`, `export { A as B }`) as
405
+ * `{ local, exported }` pairs. These are NOT emitted as JS: components live
406
+ * in the component registry rather than as top-level bindings, so a raw
407
+ * `export { A }` would reference an undefined identifier. The pairs become
408
+ * registry alias entries so the exported name is importable.
409
+ */
410
+ exportAliases;
411
+ /**
412
+ * Module specifiers re-exported from this file (`export * from './x.vsk'`,
413
+ * `export { A } from './x.vsk'`, `export * as ns from './x.vsk'`). The
414
+ * statements themselves are dropped — the target file is compiled and
415
+ * merged into this one's component registry instead.
416
+ */
417
+ reexportSources;
418
+ constructor(components, imports = [], importedNames = /* @__PURE__ */ new Set(), staticProps = null, loadFn = null, topLevelCode = [], exportAliases = [], reexportSources = []) {
371
419
  this.components = components;
372
420
  this.imports = imports;
373
421
  this.importedNames = importedNames;
374
422
  this.staticProps = staticProps;
375
423
  this.loadFn = loadFn;
376
424
  this.topLevelCode = topLevelCode;
425
+ this.exportAliases = exportAliases;
426
+ this.reexportSources = reexportSources;
377
427
  }
378
428
  };
379
429
  ComponentIR = class {
@@ -1982,6 +2032,16 @@ function startRequest(handle2, skipCache) {
1982
2032
  if (getInflight().get(key) === prom2) getInflight().delete(key);
1983
2033
  });
1984
2034
  } else {
2035
+ const ownerToken = g().__vsk_ssr_token || void 0;
2036
+ if (ownerToken) {
2037
+ prom2.then(
2038
+ (data2) => {
2039
+ setSsrData(key, data2, ownerToken);
2040
+ },
2041
+ () => {
2042
+ }
2043
+ );
2044
+ }
1985
2045
  attachSettle(handle2, prom2);
1986
2046
  }
1987
2047
  trackSsrPromise(prom2);
@@ -3440,10 +3500,10 @@ function flattenLayoutChain(tree, pathParts, result = []) {
3440
3500
  if (matched) {
3441
3501
  const consumeCount = node.isCatchAll ? pathParts.length : segCount;
3442
3502
  const remaining = pathParts.slice(consumeCount);
3443
- const isLeaf = remaining.length === 0 || remaining.every((p) => p === "");
3503
+ const isLeaf2 = remaining.length === 0 || remaining.every((p) => p === "");
3444
3504
  if (node.standalone) result.length = 0;
3445
3505
  result.push(node);
3446
- if (isLeaf) {
3506
+ if (isLeaf2) {
3447
3507
  break;
3448
3508
  } else if ((node.children || []).length > 0) {
3449
3509
  flattenLayoutChain(node.children || [], remaining, result);
@@ -16853,9 +16913,9 @@ function looksLikeTypeAssertionAt(input, pos) {
16853
16913
  while (i < input.length && isIdentCharCode(input.charCodeAt(i))) i++;
16854
16914
  const name = input.slice(nameStart, i);
16855
16915
  if (HTML_TAGS.has(name) || VOID_ELEMENTS.has(name)) return false;
16856
- const isPrimitive = TS_PRIMITIVE_TYPES.has(name);
16916
+ const isPrimitive2 = TS_PRIMITIVE_TYPES.has(name);
16857
16917
  const isCapitalized = name[0] >= "A" && name[0] <= "Z";
16858
- if (!isPrimitive && !isCapitalized) return false;
16918
+ if (!isPrimitive2 && !isCapitalized) return false;
16859
16919
  if (input.charCodeAt(i) === 60) {
16860
16920
  let depth = 0;
16861
16921
  let j = i;
@@ -16904,6 +16964,15 @@ function matchKeywordSequence(input, words) {
16904
16964
  const c = input.charCodeAt(p);
16905
16965
  return isWsChar(c) || c === 123;
16906
16966
  }
16967
+ function withStandaloneTokens(fn) {
16968
+ const prev = standaloneTokens;
16969
+ standaloneTokens = true;
16970
+ try {
16971
+ return fn();
16972
+ } finally {
16973
+ standaloneTokens = prev;
16974
+ }
16975
+ }
16907
16976
  function VeskParserPlugin(config = {}) {
16908
16977
  return (Parser3) => {
16909
16978
  const tt = Parser3.tokTypes || types$1;
@@ -16919,6 +16988,10 @@ function VeskParserPlugin(config = {}) {
16919
16988
  constructor(options, input) {
16920
16989
  super(options, input);
16921
16990
  }
16991
+ /** True when JSX tags are recognised without parser-driven componentDepth. */
16992
+ #jsxAllowed() {
16993
+ return this.#componentDepth > 0 || standaloneTokens;
16994
+ }
16922
16995
  #isBlockContext() {
16923
16996
  const ctx2 = this.curContext();
16924
16997
  return ctx2 && (ctx2.token === "{" || ctx2.token === "function");
@@ -17148,7 +17221,7 @@ function VeskParserPlugin(config = {}) {
17148
17221
  }
17149
17222
  return super.readToken(this.input.codePointAt(this.pos));
17150
17223
  }
17151
- if (this.#componentDepth > 0 && code === 60 && this.#isBlockContext()) {
17224
+ if (this.#jsxAllowed() && code === 60 && this.#isBlockContext()) {
17152
17225
  const next = this.input.charCodeAt(this.pos + 1);
17153
17226
  const startsNewStatement = this.hasPrecedingLineBreak();
17154
17227
  const inType = this.inType;
@@ -17599,7 +17672,7 @@ function VeskParserPlugin(config = {}) {
17599
17672
  return VeskParser;
17600
17673
  };
17601
17674
  }
17602
- var VOID_ELEMENTS, TS_PRIMITIVE_TYPES, HTML_TAGS;
17675
+ var VOID_ELEMENTS, TS_PRIMITIVE_TYPES, HTML_TAGS, standaloneTokens;
17603
17676
  var init_vesk_plugin = __esm({
17604
17677
  "../compiler/src/vesk-plugin.ts"() {
17605
17678
  "use strict";
@@ -17622,6 +17695,7 @@ var init_vesk_plugin = __esm({
17622
17695
  ]);
17623
17696
  TS_PRIMITIVE_TYPES = /* @__PURE__ */ new Set(["number", "string", "boolean", "any", "unknown", "never", "void", "object", "symbol", "bigint", "undefined", "null"]);
17624
17697
  HTML_TAGS = /* @__PURE__ */ new Set(["a", "abbr", "address", "area", "article", "aside", "audio", "b", "base", "bdi", "bdo", "blockquote", "body", "br", "button", "canvas", "caption", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "label", "legend", "li", "link", "main", "map", "mark", "menu", "meta", "meter", "nav", "noscript", "object", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "script", "section", "select", "slot", "small", "source", "span", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "u", "ul", "var", "video", "wbr"]);
17698
+ standaloneTokens = false;
17625
17699
  }
17626
17700
  });
17627
17701
 
@@ -17993,6 +18067,340 @@ var init_scan = __esm({
17993
18067
  }
17994
18068
  });
17995
18069
 
18070
+ // ../compiler/src/tokens.ts
18071
+ function tokenizeCode(code) {
18072
+ return withStandaloneTokens(() => {
18073
+ try {
18074
+ const ParserClass = createBaseParser();
18075
+ const tok = ParserClass.tokenizer(code, {
18076
+ ecmaVersion: "latest",
18077
+ sourceType: "module"
18078
+ });
18079
+ const out = [];
18080
+ let t;
18081
+ while ((t = tok.getToken()) && t.type && t.type.label !== "eof") {
18082
+ out.push({
18083
+ label: t.type.label,
18084
+ value: typeof t.value === "string" ? t.value : "",
18085
+ start: t.start,
18086
+ end: t.end
18087
+ });
18088
+ }
18089
+ return out;
18090
+ } catch {
18091
+ return null;
18092
+ }
18093
+ });
18094
+ }
18095
+ function containsIdentifier(code, name) {
18096
+ const tokens = tokenizeCode(code);
18097
+ if (tokens !== null) {
18098
+ for (const t of tokens) {
18099
+ if ((t.label === "name" || t.label === "jsxName") && t.value === name) return true;
18100
+ }
18101
+ return false;
18102
+ }
18103
+ return manualContainsIdentifier(code, name);
18104
+ }
18105
+ function isIdentifierImported(code, name) {
18106
+ const tokens = tokenizeCode(code);
18107
+ if (tokens !== null) {
18108
+ for (let i = 0; i < tokens.length; i++) {
18109
+ if (tokens[i].label !== "import") continue;
18110
+ let j = i + 1;
18111
+ while (j < tokens.length && tokens[j].label !== ";" && !(tokens[j].label === "name" && tokens[j].value === "from")) {
18112
+ j++;
18113
+ }
18114
+ for (let k = i + 1; k < j; k++) {
18115
+ if ((tokens[k].label === "name" || tokens[k].label === "jsxName") && tokens[k].value === name) return true;
18116
+ }
18117
+ i = j;
18118
+ }
18119
+ return false;
18120
+ }
18121
+ return manualIsIdentifierImported(code, name);
18122
+ }
18123
+ function extractImportNames(importText) {
18124
+ const tokens = tokenizeCode(importText);
18125
+ if (tokens !== null) {
18126
+ const names = [];
18127
+ let i = 0;
18128
+ while (i < tokens.length && tokens[i].label !== "import") i++;
18129
+ if (i >= tokens.length) return names;
18130
+ i++;
18131
+ if (i < tokens.length && tokens[i].label === "name" && tokens[i].value === "type") i++;
18132
+ if (i < tokens.length && tokens[i].label === "{") {
18133
+ i++;
18134
+ while (i < tokens.length && tokens[i].label !== "}") {
18135
+ const t = tokens[i];
18136
+ if (t.label === "name") {
18137
+ if (t.value === "type" || t.value === "typeof") {
18138
+ i++;
18139
+ continue;
18140
+ }
18141
+ let name = t.value;
18142
+ if (i + 2 < tokens.length && tokens[i + 1].label === "name" && tokens[i + 1].value === "as" && tokens[i + 2].label === "name") {
18143
+ name = tokens[i + 2].value;
18144
+ i += 2;
18145
+ }
18146
+ names.push(name);
18147
+ }
18148
+ i++;
18149
+ }
18150
+ return names;
18151
+ }
18152
+ if (i < tokens.length && tokens[i].label === "*") {
18153
+ while (i < tokens.length && tokens[i].label !== "name") i++;
18154
+ if (i < tokens.length) names.push(tokens[i].value);
18155
+ } else if (i < tokens.length && tokens[i].label === "name") {
18156
+ names.push(tokens[i].value);
18157
+ }
18158
+ return names;
18159
+ }
18160
+ return manualExtractImportNames(importText);
18161
+ }
18162
+ function importModuleTarget(importText) {
18163
+ const tokens = tokenizeCode(importText);
18164
+ if (tokens === null) return null;
18165
+ for (let i = tokens.length - 1; i >= 0; i--) {
18166
+ if (tokens[i].label === "string") return tokens[i].value;
18167
+ }
18168
+ return null;
18169
+ }
18170
+ function manualContainsIdentifier(code, name) {
18171
+ let i = 0;
18172
+ while (i < code.length) {
18173
+ const c = code[i];
18174
+ if (c === '"' || c === "'" || c === "`") {
18175
+ i = skipString(code, i);
18176
+ continue;
18177
+ }
18178
+ if (c === "/" && (code[i + 1] === "/" || code[i + 1] === "*")) {
18179
+ i = skipComment(code, i);
18180
+ continue;
18181
+ }
18182
+ if (isIdentStart(c) && code.slice(i, i + name.length) === name) {
18183
+ const after = i + name.length;
18184
+ if ((after >= code.length || !isIdentChar(code[after])) && (i === 0 || !isIdentChar(code[i - 1]))) return true;
18185
+ }
18186
+ i++;
18187
+ }
18188
+ return false;
18189
+ }
18190
+ function manualIsIdentifierImported(code, name) {
18191
+ let i = 0;
18192
+ while (i < code.length) {
18193
+ const c = code[i];
18194
+ if (c === '"' || c === "'" || c === "`") {
18195
+ i = skipString(code, i);
18196
+ continue;
18197
+ }
18198
+ if (c === "/" && (code[i + 1] === "/" || code[i + 1] === "*")) {
18199
+ i = skipComment(code, i);
18200
+ continue;
18201
+ }
18202
+ if (isIdentStart(c)) {
18203
+ let j = i + 1;
18204
+ while (j < code.length && isIdentChar(code[j])) j++;
18205
+ const word = code.slice(i, j);
18206
+ if (word === "import") {
18207
+ let k = j;
18208
+ while (k < code.length) {
18209
+ if (code[k] === ";" || code[k] === "\n") break;
18210
+ if (code[k] === '"' || code[k] === "'" || code[k] === "`") {
18211
+ k = skipString(code, k);
18212
+ continue;
18213
+ }
18214
+ if (isIdentStart(code[k]) && code.slice(k, k + name.length) === name) {
18215
+ const a = k + name.length;
18216
+ if ((a >= code.length || !isIdentChar(code[a])) && (k === 0 || !isIdentChar(code[k - 1]))) return true;
18217
+ }
18218
+ k++;
18219
+ }
18220
+ }
18221
+ i = j;
18222
+ continue;
18223
+ }
18224
+ i++;
18225
+ }
18226
+ return false;
18227
+ }
18228
+ function manualExtractImportNames(importText) {
18229
+ const names = [];
18230
+ const open = importText.indexOf("{");
18231
+ if (open !== -1) {
18232
+ const close = importText.indexOf("}", open + 1);
18233
+ if (close !== -1) {
18234
+ let i2 = open + 1;
18235
+ while (i2 < close) {
18236
+ const c = importText[i2];
18237
+ if (c === '"' || c === "'" || c === "`") {
18238
+ i2 = skipString(importText, i2);
18239
+ continue;
18240
+ }
18241
+ if (isIdentStart(c)) {
18242
+ let j = i2 + 1;
18243
+ while (j < close && isIdentChar(importText[j])) j++;
18244
+ let word = importText.slice(i2, j);
18245
+ if (word === "type" || word === "typeof") {
18246
+ i2 = j;
18247
+ continue;
18248
+ }
18249
+ let k = skipWhitespace(importText, j);
18250
+ if (importText.slice(k, k + 2) === "as" && !isIdentChar(importText[k + 2])) {
18251
+ let m = skipWhitespace(importText, k + 2);
18252
+ if (isIdentStart(importText[m])) {
18253
+ let n = m + 1;
18254
+ while (n < close && isIdentChar(importText[n])) n++;
18255
+ word = importText.slice(m, n);
18256
+ }
18257
+ }
18258
+ names.push(word);
18259
+ i2 = j;
18260
+ continue;
18261
+ }
18262
+ i2++;
18263
+ }
18264
+ return names;
18265
+ }
18266
+ }
18267
+ let i = 0;
18268
+ while (i < importText.length && !isIdentStart(importText[i])) i++;
18269
+ while (i < importText.length && isIdentChar(importText[i])) i++;
18270
+ i = skipWhitespace(importText, i);
18271
+ if (importText[i] === "*") {
18272
+ i = skipWhitespace(importText, i + 1);
18273
+ if (importText.slice(i, i + 2) === "as") i = skipWhitespace(importText, i + 2);
18274
+ if (isIdentStart(importText[i])) {
18275
+ let j = i + 1;
18276
+ while (j < importText.length && isIdentChar(importText[j])) j++;
18277
+ names.push(importText.slice(i, j));
18278
+ }
18279
+ } else if (isIdentStart(importText[i])) {
18280
+ let j = i + 1;
18281
+ while (j < importText.length && isIdentChar(importText[j])) j++;
18282
+ names.push(importText.slice(i, j));
18283
+ }
18284
+ return names;
18285
+ }
18286
+ function hasTopLevelValueDeclaration(code, name) {
18287
+ const tokens = tokenizeCode(code);
18288
+ if (tokens === null) return false;
18289
+ const declWords = ["const", "let", "var", "function", "class"];
18290
+ for (let i = 1; i < tokens.length; i++) {
18291
+ if (tokens[i].label !== "name" || tokens[i].value !== name) continue;
18292
+ const prev = tokens[i - 1];
18293
+ if (!prev || !declWords.includes(prev.value)) continue;
18294
+ if (i >= 2) {
18295
+ const pp2 = tokens[i - 2];
18296
+ if (pp2 && pp2.label === "name" && pp2.value === "export") continue;
18297
+ }
18298
+ return true;
18299
+ }
18300
+ return false;
18301
+ }
18302
+ function findSpecifierExports(code) {
18303
+ const tokens = tokenizeCode(code);
18304
+ if (tokens === null) return [];
18305
+ const out = [];
18306
+ for (let i = 0; i < tokens.length; i++) {
18307
+ if (tokens[i].label !== "export") continue;
18308
+ if (!tokens[i + 1] || tokens[i + 1].label !== "{") continue;
18309
+ let k = i + 2;
18310
+ let depth = 1;
18311
+ for (; k < tokens.length; k++) {
18312
+ const lbl = tokens[k].label;
18313
+ if (lbl === "string") {
18314
+ continue;
18315
+ }
18316
+ if (lbl === "{") depth++;
18317
+ else if (lbl === "}") {
18318
+ depth--;
18319
+ if (depth === 0) break;
18320
+ }
18321
+ }
18322
+ let isReexport = false;
18323
+ for (let j = k + 1; j < tokens.length; j++) {
18324
+ const lbl = tokens[j].label;
18325
+ if (lbl === "string") {
18326
+ isReexport = true;
18327
+ break;
18328
+ }
18329
+ if (lbl === ";" || lbl === "export" || lbl === "import" || lbl === "}") break;
18330
+ }
18331
+ if (depth !== 0 || isReexport) continue;
18332
+ const pairs = readSpecifierPairs(code, tokens[i + 1].end, tokens[k].end);
18333
+ if (pairs === null) continue;
18334
+ const stmtEnd = tokens[k].end;
18335
+ for (const [local, exported] of pairs) out.push({ local, exported, start: tokens[i].start, end: stmtEnd });
18336
+ i = k;
18337
+ }
18338
+ return out;
18339
+ }
18340
+ function readSpecifierPairs(code, from, to) {
18341
+ const tokens = tokenizeCode(`(${code.slice(from, to)})`);
18342
+ if (tokens === null || tokens.length < 2) return null;
18343
+ const pairs = [];
18344
+ let i = 1;
18345
+ while (i < tokens.length) {
18346
+ const local = tokens[i];
18347
+ if (!local || local.label === ")" || local.label === ";") break;
18348
+ if (local.label !== "name") return null;
18349
+ const asTok = tokens[i + 1];
18350
+ if (asTok && asTok.label === "name" && asTok.value === "as") {
18351
+ const exported = tokens[i + 2];
18352
+ if (!exported || exported.label !== "name") return null;
18353
+ pairs.push([local.value, exported.value]);
18354
+ i += 3;
18355
+ } else {
18356
+ pairs.push([local.value, local.value]);
18357
+ i += 1;
18358
+ }
18359
+ const sep8 = tokens[i];
18360
+ if (!sep8 || sep8.label !== ",") break;
18361
+ i += 1;
18362
+ }
18363
+ return pairs.length > 0 ? pairs : null;
18364
+ }
18365
+ function collectTrackDeclMarkers(node, out) {
18366
+ if (!node || typeof node !== "object") return;
18367
+ if (Array.isArray(node)) {
18368
+ for (const child of node) collectTrackDeclMarkers(child, out);
18369
+ return;
18370
+ }
18371
+ if (node.type === "ArrayPattern" && node.lazy === true && typeof node.start === "number") {
18372
+ out.add(node.start - 1);
18373
+ return;
18374
+ }
18375
+ for (const key of Object.keys(node)) {
18376
+ const value = node[key];
18377
+ if (value && typeof value === "object") collectTrackDeclMarkers(value, out);
18378
+ }
18379
+ }
18380
+ function stripTrackDeclMarkers(text, base, node) {
18381
+ const offsets = /* @__PURE__ */ new Set();
18382
+ collectTrackDeclMarkers(node, offsets);
18383
+ if (offsets.size === 0) return text;
18384
+ const sorted = [...offsets].sort((a, b) => a - b);
18385
+ let out = "";
18386
+ let prev = 0;
18387
+ for (const offset2 of sorted) {
18388
+ const i = offset2 - base;
18389
+ if (i < prev || i >= text.length) continue;
18390
+ out += text.slice(prev, i) + " ";
18391
+ prev = i + 1;
18392
+ }
18393
+ return out + text.slice(prev);
18394
+ }
18395
+ var init_tokens = __esm({
18396
+ "../compiler/src/tokens.ts"() {
18397
+ "use strict";
18398
+ init_parser();
18399
+ init_vesk_plugin();
18400
+ init_scan();
18401
+ }
18402
+ });
18403
+
17996
18404
  // ../compiler/src/parser.ts
17997
18405
  function isIdentChar2(code) {
17998
18406
  return code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57 || code === 95 || code === 36;
@@ -18213,8 +18621,19 @@ function createBaseParser() {
18213
18621
  function parse4(source, options = {}) {
18214
18622
  const ParserClass = createBaseParser();
18215
18623
  const { code, annotations } = preprocessForClauses(blankComments(source));
18624
+ const vskSource = !options.filename || String(options.filename).endsWith(".vsk");
18625
+ const specifierExports = vskSource ? findSpecifierExports(code).filter((e) => !hasTopLevelValueDeclaration(code, e.local)) : [];
18626
+ let parseable = code;
18627
+ if (specifierExports.length > 0) {
18628
+ const edits = specifierExports.map((e) => code.slice(e.start, e.end)).map((text) => text.split("").map((ch) => ch === "\n" ? "\n" : " ").join(""));
18629
+ let cut = 0;
18630
+ for (const spec of specifierExports) {
18631
+ const blanked = edits[cut++];
18632
+ parseable = parseable.slice(0, spec.start) + blanked + parseable.slice(spec.end);
18633
+ }
18634
+ }
18216
18635
  try {
18217
- const ast = ParserClass.parse(code, {
18636
+ const ast = ParserClass.parse(parseable, {
18218
18637
  ecmaVersion: "latest",
18219
18638
  sourceType: "module",
18220
18639
  locations: true,
@@ -18224,6 +18643,11 @@ function parse4(source, options = {}) {
18224
18643
  if (annotations.length > 0) {
18225
18644
  ast.__vskAnnotations = annotations;
18226
18645
  }
18646
+ if (specifierExports.length > 0) {
18647
+ ast.__vskSpecifierExports = specifierExports.map(
18648
+ (e) => ({ local: e.local, exported: e.exported })
18649
+ );
18650
+ }
18227
18651
  return ast;
18228
18652
  } catch (e) {
18229
18653
  const err = e;
@@ -18264,6 +18688,7 @@ var init_parser = __esm({
18264
18688
  init_vesk_plugin();
18265
18689
  init_scan();
18266
18690
  init_errors();
18691
+ init_tokens();
18267
18692
  }
18268
18693
  });
18269
18694
 
@@ -18458,228 +18883,6 @@ var init_strip_ts = __esm({
18458
18883
  }
18459
18884
  });
18460
18885
 
18461
- // ../compiler/src/tokens.ts
18462
- function tokenizeCode(code) {
18463
- try {
18464
- const ParserClass = createBaseParser();
18465
- const tok = ParserClass.tokenizer(code, {
18466
- ecmaVersion: "latest",
18467
- sourceType: "module"
18468
- });
18469
- const out = [];
18470
- let t;
18471
- while ((t = tok.getToken()) && t.type && t.type.label !== "eof") {
18472
- out.push({
18473
- label: t.type.label,
18474
- value: typeof t.value === "string" ? t.value : "",
18475
- start: t.start,
18476
- end: t.end
18477
- });
18478
- }
18479
- return out;
18480
- } catch {
18481
- return null;
18482
- }
18483
- }
18484
- function containsIdentifier(code, name) {
18485
- const tokens = tokenizeCode(code);
18486
- if (tokens !== null) {
18487
- for (const t of tokens) {
18488
- if ((t.label === "name" || t.label === "jsxName") && t.value === name) return true;
18489
- }
18490
- return false;
18491
- }
18492
- return manualContainsIdentifier(code, name);
18493
- }
18494
- function isIdentifierImported(code, name) {
18495
- const tokens = tokenizeCode(code);
18496
- if (tokens !== null) {
18497
- for (let i = 0; i < tokens.length; i++) {
18498
- if (tokens[i].label !== "import") continue;
18499
- let j = i + 1;
18500
- while (j < tokens.length && tokens[j].label !== ";" && !(tokens[j].label === "name" && tokens[j].value === "from")) {
18501
- j++;
18502
- }
18503
- for (let k = i + 1; k < j; k++) {
18504
- if ((tokens[k].label === "name" || tokens[k].label === "jsxName") && tokens[k].value === name) return true;
18505
- }
18506
- i = j;
18507
- }
18508
- return false;
18509
- }
18510
- return manualIsIdentifierImported(code, name);
18511
- }
18512
- function extractImportNames(importText) {
18513
- const tokens = tokenizeCode(importText);
18514
- if (tokens !== null) {
18515
- const names = [];
18516
- let i = 0;
18517
- while (i < tokens.length && tokens[i].label !== "import") i++;
18518
- if (i >= tokens.length) return names;
18519
- i++;
18520
- if (i < tokens.length && tokens[i].label === "name" && tokens[i].value === "type") i++;
18521
- if (i < tokens.length && tokens[i].label === "{") {
18522
- i++;
18523
- while (i < tokens.length && tokens[i].label !== "}") {
18524
- const t = tokens[i];
18525
- if (t.label === "name") {
18526
- if (t.value === "type" || t.value === "typeof") {
18527
- i++;
18528
- continue;
18529
- }
18530
- let name = t.value;
18531
- if (i + 2 < tokens.length && tokens[i + 1].label === "name" && tokens[i + 1].value === "as" && tokens[i + 2].label === "name") {
18532
- name = tokens[i + 2].value;
18533
- i += 2;
18534
- }
18535
- names.push(name);
18536
- }
18537
- i++;
18538
- }
18539
- return names;
18540
- }
18541
- if (i < tokens.length && tokens[i].label === "*") {
18542
- while (i < tokens.length && tokens[i].label !== "name") i++;
18543
- if (i < tokens.length) names.push(tokens[i].value);
18544
- } else if (i < tokens.length && tokens[i].label === "name") {
18545
- names.push(tokens[i].value);
18546
- }
18547
- return names;
18548
- }
18549
- return manualExtractImportNames(importText);
18550
- }
18551
- function importModuleTarget(importText) {
18552
- const tokens = tokenizeCode(importText);
18553
- if (tokens === null) return null;
18554
- for (let i = tokens.length - 1; i >= 0; i--) {
18555
- if (tokens[i].label === "string") return tokens[i].value;
18556
- }
18557
- return null;
18558
- }
18559
- function manualContainsIdentifier(code, name) {
18560
- let i = 0;
18561
- while (i < code.length) {
18562
- const c = code[i];
18563
- if (c === '"' || c === "'" || c === "`") {
18564
- i = skipString(code, i);
18565
- continue;
18566
- }
18567
- if (c === "/" && (code[i + 1] === "/" || code[i + 1] === "*")) {
18568
- i = skipComment(code, i);
18569
- continue;
18570
- }
18571
- if (isIdentStart(c) && code.slice(i, i + name.length) === name) {
18572
- const after = i + name.length;
18573
- if ((after >= code.length || !isIdentChar(code[after])) && (i === 0 || !isIdentChar(code[i - 1]))) return true;
18574
- }
18575
- i++;
18576
- }
18577
- return false;
18578
- }
18579
- function manualIsIdentifierImported(code, name) {
18580
- let i = 0;
18581
- while (i < code.length) {
18582
- const c = code[i];
18583
- if (c === '"' || c === "'" || c === "`") {
18584
- i = skipString(code, i);
18585
- continue;
18586
- }
18587
- if (c === "/" && (code[i + 1] === "/" || code[i + 1] === "*")) {
18588
- i = skipComment(code, i);
18589
- continue;
18590
- }
18591
- if (isIdentStart(c)) {
18592
- let j = i + 1;
18593
- while (j < code.length && isIdentChar(code[j])) j++;
18594
- const word = code.slice(i, j);
18595
- if (word === "import") {
18596
- let k = j;
18597
- while (k < code.length) {
18598
- if (code[k] === ";" || code[k] === "\n") break;
18599
- if (code[k] === '"' || code[k] === "'" || code[k] === "`") {
18600
- k = skipString(code, k);
18601
- continue;
18602
- }
18603
- if (isIdentStart(code[k]) && code.slice(k, k + name.length) === name) {
18604
- const a = k + name.length;
18605
- if ((a >= code.length || !isIdentChar(code[a])) && (k === 0 || !isIdentChar(code[k - 1]))) return true;
18606
- }
18607
- k++;
18608
- }
18609
- }
18610
- i = j;
18611
- continue;
18612
- }
18613
- i++;
18614
- }
18615
- return false;
18616
- }
18617
- function manualExtractImportNames(importText) {
18618
- const names = [];
18619
- const open = importText.indexOf("{");
18620
- if (open !== -1) {
18621
- const close = importText.indexOf("}", open + 1);
18622
- if (close !== -1) {
18623
- let i2 = open + 1;
18624
- while (i2 < close) {
18625
- const c = importText[i2];
18626
- if (c === '"' || c === "'" || c === "`") {
18627
- i2 = skipString(importText, i2);
18628
- continue;
18629
- }
18630
- if (isIdentStart(c)) {
18631
- let j = i2 + 1;
18632
- while (j < close && isIdentChar(importText[j])) j++;
18633
- let word = importText.slice(i2, j);
18634
- if (word === "type" || word === "typeof") {
18635
- i2 = j;
18636
- continue;
18637
- }
18638
- let k = skipWhitespace(importText, j);
18639
- if (importText.slice(k, k + 2) === "as" && !isIdentChar(importText[k + 2])) {
18640
- let m = skipWhitespace(importText, k + 2);
18641
- if (isIdentStart(importText[m])) {
18642
- let n = m + 1;
18643
- while (n < close && isIdentChar(importText[n])) n++;
18644
- word = importText.slice(m, n);
18645
- }
18646
- }
18647
- names.push(word);
18648
- i2 = j;
18649
- continue;
18650
- }
18651
- i2++;
18652
- }
18653
- return names;
18654
- }
18655
- }
18656
- let i = 0;
18657
- while (i < importText.length && !isIdentStart(importText[i])) i++;
18658
- while (i < importText.length && isIdentChar(importText[i])) i++;
18659
- i = skipWhitespace(importText, i);
18660
- if (importText[i] === "*") {
18661
- i = skipWhitespace(importText, i + 1);
18662
- if (importText.slice(i, i + 2) === "as") i = skipWhitespace(importText, i + 2);
18663
- if (isIdentStart(importText[i])) {
18664
- let j = i + 1;
18665
- while (j < importText.length && isIdentChar(importText[j])) j++;
18666
- names.push(importText.slice(i, j));
18667
- }
18668
- } else if (isIdentStart(importText[i])) {
18669
- let j = i + 1;
18670
- while (j < importText.length && isIdentChar(importText[j])) j++;
18671
- names.push(importText.slice(i, j));
18672
- }
18673
- return names;
18674
- }
18675
- var init_tokens = __esm({
18676
- "../compiler/src/tokens.ts"() {
18677
- "use strict";
18678
- init_parser();
18679
- init_scan();
18680
- }
18681
- });
18682
-
18683
18886
  // ../compiler/src/module-imports.ts
18684
18887
  import { readFileSync as readFileSync2, existsSync as existsSync2, realpathSync, statSync } from "node:fs";
18685
18888
  import { createRequire as createRequire2 } from "node:module";
@@ -19629,19 +19832,65 @@ function collectVskImportPaths(imports, sourcePath2) {
19629
19832
  if (stripTypeImport(imp) === null) continue;
19630
19833
  const target = vskImportTarget(imp);
19631
19834
  if (!target) continue;
19632
- if (target.startsWith(".")) {
19633
- const full = resolve2(dirname3(sourcePath2), target);
19634
- if (existsSync3(full)) out.push(full);
19635
- continue;
19636
- }
19637
- const aliased = resolveImportPath(target, dirname3(sourcePath2));
19638
- if (aliased !== target && existsSync3(aliased)) out.push(aliased);
19835
+ const full = resolveVskTarget(target, sourcePath2);
19836
+ if (full) out.push(full);
19639
19837
  }
19640
19838
  return out;
19641
19839
  }
19840
+ function collectVskReexportPaths(reexportSources, sourcePath2) {
19841
+ const out = [];
19842
+ for (const spec of reexportSources) {
19843
+ if (!spec.endsWith(".vsk")) continue;
19844
+ const full = resolveVskTarget(spec, sourcePath2);
19845
+ if (full) out.push(full);
19846
+ }
19847
+ return out;
19848
+ }
19849
+ function resolveVskTarget(target, sourcePath2) {
19850
+ if (target.startsWith(".")) {
19851
+ const full = resolve2(dirname3(sourcePath2), target);
19852
+ return existsSync3(full) ? full : null;
19853
+ }
19854
+ const aliased = resolveImportPath(target, dirname3(sourcePath2));
19855
+ return aliased !== target && existsSync3(aliased) ? aliased : null;
19856
+ }
19857
+ function vskImportValueNames(imports) {
19858
+ const names = [];
19859
+ for (const imp of imports) {
19860
+ if (stripTypeImport(imp) === null) continue;
19861
+ if (vskImportTarget(imp) === null) continue;
19862
+ for (const pair of importBindingPairs(imp)) {
19863
+ if (pair.imported === "default" || pair.imported === "*") continue;
19864
+ names.push(pair.local);
19865
+ }
19866
+ }
19867
+ return names;
19868
+ }
19642
19869
  function vskImportLines(source) {
19643
19870
  return extractImportStatements(source).filter((imp) => vskImportTarget(imp) !== null && stripTypeImport(imp) !== null);
19644
19871
  }
19872
+ function vskRegistryAliases(importLines, exportAliases) {
19873
+ const aliases = [];
19874
+ for (const alias of exportAliases) {
19875
+ if (alias.local !== alias.exported) aliases.push({ local: alias.local, exported: alias.exported });
19876
+ }
19877
+ for (const imp of importLines) {
19878
+ if (stripTypeImport(imp) === null) continue;
19879
+ if (vskImportTarget(imp) === null) continue;
19880
+ for (const pair of importBindingPairs(imp)) {
19881
+ if (pair.imported === "default" || pair.imported === "*") continue;
19882
+ if (pair.local !== pair.imported) aliases.push({ local: pair.imported, exported: pair.local });
19883
+ }
19884
+ }
19885
+ return aliases;
19886
+ }
19887
+ function applyVskRegistryAliases(componentMap, aliases) {
19888
+ for (const { local, exported } of aliases) {
19889
+ if (componentMap.has(exported)) continue;
19890
+ const fn = componentMap.get(local);
19891
+ if (fn) componentMap.set(exported, fn);
19892
+ }
19893
+ }
19645
19894
  function isTypeOnlyImport(stmt) {
19646
19895
  if (!stmt || stmt.type !== "ImportDeclaration") return false;
19647
19896
  if (stmt.importKind === "type") return true;
@@ -19952,6 +20201,130 @@ function getJSXTagName(nameNode) {
19952
20201
  }
19953
20202
  return "unknown";
19954
20203
  }
20204
+ function jsxTagRootName(nameNode) {
20205
+ let node = nameNode;
20206
+ while (node && node.type === "JSXMemberExpression") node = node.object;
20207
+ return node && node.type === "JSXIdentifier" ? node.name : "";
20208
+ }
20209
+ function jsxTagMemberName(nameNode) {
20210
+ let node = nameNode;
20211
+ while (node && node.type === "JSXMemberExpression") {
20212
+ node = node.property;
20213
+ if (node && node.type === "JSXIdentifier") return node.name;
20214
+ }
20215
+ return "";
20216
+ }
20217
+ function jsxTagDepth(nameNode) {
20218
+ let depth = 0;
20219
+ let node = nameNode;
20220
+ while (node && node.type === "JSXMemberExpression") {
20221
+ depth++;
20222
+ node = node.object;
20223
+ }
20224
+ return depth;
20225
+ }
20226
+ function collectVskNamespaceLocals(ast) {
20227
+ const namespaceLocals = /* @__PURE__ */ new Map();
20228
+ for (const node of ast.body || []) {
20229
+ if (node.type !== "ImportDeclaration") continue;
20230
+ if (typeof node.source?.value !== "string" || !node.source.value.endsWith(".vsk")) continue;
20231
+ for (const spec of node.specifiers || []) {
20232
+ if (spec.type === "ImportNamespaceSpecifier" && spec.local?.name) {
20233
+ namespaceLocals.set(spec.local.name, { path: node.source.value, shadowed: false });
20234
+ }
20235
+ }
20236
+ }
20237
+ if (namespaceLocals.size === 0) return /* @__PURE__ */ new Set();
20238
+ markShadowedBindings(ast, namespaceLocals);
20239
+ return new Set([...namespaceLocals].filter(([, v]) => !v.shadowed).map(([k]) => k));
20240
+ }
20241
+ function markShadowedBindings(node, namespaceLocals) {
20242
+ if (!node || typeof node !== "object") return;
20243
+ if (Array.isArray(node)) {
20244
+ for (const child of node) markShadowedBindings(child, namespaceLocals);
20245
+ return;
20246
+ }
20247
+ if (typeof node.type === "string") {
20248
+ if (node.type === "ImportNamespaceSpecifier") return;
20249
+ for (const name of declaredBindingNames(node)) {
20250
+ const entry = namespaceLocals.get(name);
20251
+ if (entry) entry.shadowed = true;
20252
+ }
20253
+ }
20254
+ for (const key of Object.keys(node)) {
20255
+ if (key === "loc" || key === "range" || key === "start" || key === "end") continue;
20256
+ markShadowedBindings(node[key], namespaceLocals);
20257
+ }
20258
+ }
20259
+ function declaredBindingNames(node) {
20260
+ const out = [];
20261
+ const pushPattern = (id) => {
20262
+ if (!id) return;
20263
+ if (id.type === "Identifier") {
20264
+ out.push(id.name);
20265
+ return;
20266
+ }
20267
+ if (id.type === "ObjectPattern") {
20268
+ for (const prop of id.properties || []) {
20269
+ if (prop.type === "RestElement") pushPattern(prop.argument);
20270
+ else pushPattern(prop.value);
20271
+ }
20272
+ return;
20273
+ }
20274
+ if (id.type === "ArrayPattern") {
20275
+ for (const el of id.elements || []) if (el) pushPattern(el.type === "RestElement" ? el.argument : el);
20276
+ return;
20277
+ }
20278
+ if (id.type === "AssignmentPattern") pushPattern(id.left);
20279
+ if (id.type === "RestElement") pushPattern(id.argument);
20280
+ };
20281
+ switch (node.type) {
20282
+ case "VariableDeclarator":
20283
+ pushPattern(node.id);
20284
+ break;
20285
+ case "FunctionDeclaration":
20286
+ case "FunctionExpression":
20287
+ case "ArrowFunctionExpression":
20288
+ if (node.id) pushPattern(node.id);
20289
+ for (const param of node.params || []) pushPattern(param);
20290
+ break;
20291
+ case "ClassDeclaration":
20292
+ case "ClassExpression":
20293
+ if (node.id) pushPattern(node.id);
20294
+ break;
20295
+ case "CatchClause":
20296
+ pushPattern(node.param);
20297
+ break;
20298
+ default:
20299
+ break;
20300
+ }
20301
+ return out;
20302
+ }
20303
+ function assertNoVskNamespaceValue(source, expr) {
20304
+ if (!currentVskNamespaceLocals || currentVskNamespaceLocals.size === 0) return;
20305
+ const hit = findNamespaceValueUse(expr, currentVskNamespaceLocals);
20306
+ if (!hit) return;
20307
+ const { line, column } = offsetToLineCol2(source, hit.start ?? 0);
20308
+ throw VeskError.vskNamespaceMember({ file: currentSourceFile, line, column, code: codeFrame(source, line, column), form: "value" });
20309
+ }
20310
+ function findNamespaceValueUse(node, locals2) {
20311
+ if (!node || typeof node !== "object") return null;
20312
+ if (Array.isArray(node)) {
20313
+ for (const child of node) {
20314
+ const hit = findNamespaceValueUse(child, locals2);
20315
+ if (hit) return hit;
20316
+ }
20317
+ return null;
20318
+ }
20319
+ if (typeof node.type !== "string") return null;
20320
+ if (node.type === "MemberExpression" && node.object?.type === "Identifier" && locals2.has(node.object.name)) return node;
20321
+ for (const key of Object.keys(node)) {
20322
+ if (key === "loc" || key === "range" || key === "start" || key === "end") continue;
20323
+ const hit = findNamespaceValueUse(node[key], locals2);
20324
+ if (hit) return hit;
20325
+ }
20326
+ return null;
20327
+ }
19955
20328
  function isHTMLTag(name) {
19956
20329
  return name.length > 0 && name[0] === name[0].toLowerCase();
19957
20330
  }
@@ -19959,6 +20332,7 @@ function isMapCall(expr) {
19959
20332
  return expr.type === "CallExpression" && expr.callee.type === "MemberExpression" && expr.callee.property.name === "map" && expr.arguments.length === 1 && expr.arguments[0].type === "ArrowFunctionExpression";
19960
20333
  }
19961
20334
  function toExpression(source, expr) {
20335
+ assertNoVskNamespaceValue(source, expr);
19962
20336
  return new Expression(getSource(source, expr), [], expr, source);
19963
20337
  }
19964
20338
  function processAttribute(source, attr) {
@@ -20320,8 +20694,17 @@ function processJSXElement(source, element) {
20320
20694
  return [new HeadBlock(children2)];
20321
20695
  }
20322
20696
  if (nameNode && nameNode.type === "JSXMemberExpression") {
20697
+ const root3 = jsxTagRootName(nameNode);
20698
+ const isVskNamespace = !!currentVskNamespaceLocals && currentVskNamespaceLocals.has(root3);
20699
+ if (isVskNamespace && jsxTagDepth(nameNode) > 1) {
20700
+ const { line, column } = offsetToLineCol2(source, nameNode.start ?? 0);
20701
+ throw VeskError.vskNamespaceMember({ file: currentSourceFile, line, column, code: codeFrame(source, line, column), form: "nested" });
20702
+ }
20323
20703
  const { props, spreadProps, slots } = extractProps(source, element);
20324
20704
  const children2 = selfClosing ? [] : processJSXChildren(source, element.children || []);
20705
+ if (isVskNamespace) {
20706
+ return [new ComponentCall(jsxTagMemberName(nameNode), props, [...children2, ...slots.map((s) => new PropSlot(s.name, s.nodes))], spreadProps, element.start)];
20707
+ }
20325
20708
  return [new ComponentCall(tagName, props, [...children2, ...slots.map((s) => new PropSlot(s.name, s.nodes))], spreadProps, element.start, getSource(source, nameNode))];
20326
20709
  }
20327
20710
  if (!isHTMLTag(tagName) && selfClosing) {
@@ -20735,217 +21118,263 @@ function generateIR(ast, source, filename) {
20735
21118
  let staticProps = null;
20736
21119
  let loadFn = null;
20737
21120
  const topLevelCode = [];
20738
- for (const node of ast.body) {
20739
- if (node.type === "ImportDeclaration") {
20740
- const raw2 = getSource(source, node);
20741
- let cleaned = stripTypeImport(raw2);
20742
- if (cleaned === null) continue;
20743
- cleaned = normalizeRuntimeSpecifier(cleaned);
20744
- imports.push(cleaned);
20745
- for (const spec of node.specifiers) {
20746
- if (spec.importKind === "type") continue;
20747
- if (spec.type === "ImportSpecifier") {
20748
- importedNames.add(spec.local.name);
21121
+ const exportAliases = [];
21122
+ const reexportSources = [];
21123
+ for (const pair of ast.__vskSpecifierExports || []) {
21124
+ exportAliases.push({ local: pair.local, exported: pair.exported });
21125
+ }
21126
+ const vskNamespaceLocals = collectVskNamespaceLocals(ast);
21127
+ const prevNamespaceLocals = currentVskNamespaceLocals;
21128
+ const prevSourceFile = currentSourceFile;
21129
+ currentVskNamespaceLocals = vskNamespaceLocals;
21130
+ currentSourceFile = file;
21131
+ try {
21132
+ for (const node of ast.body) {
21133
+ if (node.type === "ImportDeclaration") {
21134
+ const raw2 = getSource(source, node);
21135
+ let cleaned = stripTypeImport(raw2);
21136
+ if (cleaned === null) continue;
21137
+ cleaned = normalizeRuntimeSpecifier(cleaned);
21138
+ imports.push(cleaned);
21139
+ for (const spec of node.specifiers) {
21140
+ if (spec.importKind === "type") continue;
21141
+ if (spec.type === "ImportSpecifier") {
21142
+ importedNames.add(spec.local.name);
21143
+ }
20749
21144
  }
21145
+ continue;
20750
21146
  }
20751
- continue;
20752
- }
20753
- if (node.type === "ExportNamedDeclaration" && node.declaration && !staticProps) {
20754
- const decl = node.declaration;
20755
- const fnName = decl.type === "FunctionDeclaration" ? decl.id?.name : decl.type === "VariableDeclaration" ? decl.declarations[0]?.id?.name : null;
20756
- if (fnName === "getStaticProps") {
20757
- staticProps = stripCodeTypes(getSource(source, decl));
21147
+ if (node.type === "ExportNamedDeclaration" && node.declaration && !staticProps) {
21148
+ const decl = node.declaration;
21149
+ const fnName = decl.type === "FunctionDeclaration" ? decl.id?.name : decl.type === "VariableDeclaration" ? decl.declarations[0]?.id?.name : null;
21150
+ if (fnName === "getStaticProps") {
21151
+ staticProps = stripCodeTypes(getSource(source, decl));
21152
+ continue;
21153
+ }
21154
+ }
21155
+ if (node.type === "ExportNamedDeclaration" && node.declaration && !loadFn) {
21156
+ const decl = node.declaration;
21157
+ const fnName = decl.type === "FunctionDeclaration" ? decl.id?.name : decl.type === "VariableDeclaration" ? decl.declarations[0]?.id?.name : null;
21158
+ if (fnName === "load") {
21159
+ loadFn = stripCodeTypes(getSource(source, decl));
21160
+ continue;
21161
+ }
21162
+ }
21163
+ if (node.type === "ExportNamedDeclaration" && node.declaration) {
21164
+ const decl = node.declaration;
21165
+ if (decl.type === "VariableDeclaration") {
21166
+ const declName = decl.declarations[0]?.id?.name;
21167
+ if (declName === "standalone") {
21168
+ continue;
21169
+ }
21170
+ }
21171
+ }
21172
+ if (node.type === "ExportNamedDeclaration" && !node.declaration) {
21173
+ if (node.source) {
21174
+ if (typeof node.source.value === "string") reexportSources.push(node.source.value);
21175
+ for (const spec of node.specifiers || []) {
21176
+ if (spec.type === "ExportSpecifier") {
21177
+ const localName = spec.local && spec.local.name;
21178
+ const exportedName = spec.exported && spec.exported.name;
21179
+ if (typeof localName === "string" && typeof exportedName === "string") {
21180
+ exportAliases.push({ local: localName, exported: exportedName });
21181
+ }
21182
+ }
21183
+ }
21184
+ continue;
21185
+ }
21186
+ for (const spec of node.specifiers || []) {
21187
+ if (spec.type === "ExportSpecifier") {
21188
+ const localName = spec.local && spec.local.name;
21189
+ const exportedName = spec.exported && spec.exported.name;
21190
+ if (typeof localName === "string" && typeof exportedName === "string") {
21191
+ exportAliases.push({ local: localName, exported: exportedName });
21192
+ }
21193
+ }
21194
+ }
20758
21195
  continue;
20759
21196
  }
20760
- }
20761
- if (node.type === "ExportNamedDeclaration" && node.declaration && !loadFn) {
20762
- const decl = node.declaration;
20763
- const fnName = decl.type === "FunctionDeclaration" ? decl.id?.name : decl.type === "VariableDeclaration" ? decl.declarations[0]?.id?.name : null;
20764
- if (fnName === "load") {
20765
- loadFn = stripCodeTypes(getSource(source, decl));
21197
+ if (node.type === "ExportAllDeclaration") {
21198
+ if (node.source && typeof node.source.value === "string") reexportSources.push(node.source.value);
20766
21199
  continue;
20767
21200
  }
20768
- }
20769
- if (node.type === "ExportNamedDeclaration" && node.declaration) {
20770
- const decl = node.declaration;
20771
- if (decl.type === "VariableDeclaration") {
20772
- const declName = decl.declarations[0]?.id?.name;
20773
- if (declName === "standalone") {
20774
- continue;
21201
+ let inner = node;
21202
+ let exported = false;
21203
+ let defaultExport = false;
21204
+ if (node.type === "ExportNamedDeclaration" && node.declaration) {
21205
+ inner = node.declaration;
21206
+ exported = true;
21207
+ } else if (node.type === "ExportDefaultDeclaration" && node.declaration) {
21208
+ inner = node.declaration;
21209
+ exported = true;
21210
+ defaultExport = true;
21211
+ }
21212
+ if (inner.type === "ComponentDeclaration") {
21213
+ } else if (inner.type === "ClassDeclaration") {
21214
+ const { line, column } = offsetToLineCol2(source, inner.start ?? 0);
21215
+ throw VeskError.classDecl({ file, line, column, code: codeFrame(source, line, column) });
21216
+ } else if (inner.type === "TSEnumDeclaration") {
21217
+ const code = processEnum(inner, source, exported);
21218
+ topLevelCode.push(code);
21219
+ continue;
21220
+ } else {
21221
+ topLevelCode.push(getSource(source, node));
21222
+ continue;
21223
+ }
21224
+ const name = inner.id.name;
21225
+ const paramNames = getParamNames(inner.params, source);
21226
+ const firstParam = inner.params?.[0];
21227
+ const propsAlias = firstParam && firstParam.type === "Identifier" ? firstParam.name : null;
21228
+ const propsType = getPropsType(inner.params, source);
21229
+ const bodyStmts = inner.body.body;
21230
+ const isClientComp = !!inner.client;
21231
+ const prevSlotProps = __slotProps;
21232
+ __slotProps = slotPropNamesFromType(propsType);
21233
+ __propsParam = propsAlias || null;
21234
+ if (isStatementMode(bodyStmts)) {
21235
+ const raw2 = processStatementModeBody(source, bodyStmts, file);
21236
+ const { body, css } = extractStyle(raw2);
21237
+ validateBlocks(name, isClientComp, body, file, source);
21238
+ const comp = new ComponentIR(name, paramNames, body, { mode: "statement", exported, defaultExport, isClient: inner.client, isAsync: inner.async, ssrAwait: componentUsesFetch(body), propsType, propsAlias });
21239
+ comp.style = css;
21240
+ components.push(comp);
21241
+ __slotProps = prevSlotProps;
21242
+ } else {
21243
+ const guardClauses = [];
21244
+ let mainReturn = null;
21245
+ const preamble = [];
21246
+ for (const stmt of bodyStmts) {
21247
+ if (stmt.type === "VeskBlock") {
21248
+ const innerBody = processStatementModeBody(source, stmt.body, file);
21249
+ if (stmt.tag === "server") {
21250
+ preamble.push(new ServerBlock(innerBody));
21251
+ } else if (stmt.tag === "client") {
21252
+ preamble.push(new ClientBlock(innerBody));
21253
+ }
21254
+ } else if (stmt.type === "ReturnStatement") {
21255
+ mainReturn = stmt;
21256
+ } else if (isTrackDeclaration(stmt)) {
21257
+ const elements = stmt.declarations[0].id.elements;
21258
+ const trackName = elements[0]?.name;
21259
+ const rawName = elements.length > 1 ? elements[1]?.name : null;
21260
+ const init = getSource(source, stmt.declarations[0].init);
21261
+ if (trackName) preamble.push(new TrackDecl(trackName, init, rawName));
21262
+ const refName = getComponentRefName(stmt);
21263
+ if (refName) preamble.push(new ComponentRef(refName));
21264
+ } else if (stmt.type === "IfStatement" && !mainReturn && stmt.consequent.type !== "ThrowStatement") {
21265
+ guardClauses.push(stmt);
21266
+ } else if (stmt.type === "ClassDeclaration") {
21267
+ const { line, column } = offsetToLineCol2(source, stmt.start ?? 0);
21268
+ throw VeskError.classDecl({ file, line, column, code: codeFrame(source, line, column) });
21269
+ } else {
21270
+ const raw2 = getSource(source, stmt);
21271
+ if (raw2) preamble.push(new RuntimeStatement(raw2, stmt, source));
21272
+ }
20775
21273
  }
21274
+ const guardBody = buildGuardChain(source, guardClauses, mainReturn);
21275
+ const { body, css } = extractStyle([...preamble, ...guardBody]);
21276
+ validateBlocks(name, isClientComp, body, file, source);
21277
+ const comp = new ComponentIR(name, paramNames, body, { exported, defaultExport, isClient: inner.client, isAsync: inner.async, ssrAwait: componentUsesFetch(body), propsType, propsAlias });
21278
+ comp.style = css;
21279
+ components.push(comp);
21280
+ __slotProps = prevSlotProps;
20776
21281
  }
20777
21282
  }
20778
- let inner = node;
20779
- let exported = false;
20780
- let defaultExport = false;
20781
- if (node.type === "ExportNamedDeclaration" && node.declaration) {
20782
- inner = node.declaration;
20783
- exported = true;
20784
- } else if (node.type === "ExportDefaultDeclaration" && node.declaration) {
20785
- inner = node.declaration;
20786
- exported = true;
20787
- defaultExport = true;
20788
- }
20789
- if (inner.type === "ComponentDeclaration") {
20790
- } else if (inner.type === "ClassDeclaration") {
20791
- const { line, column } = offsetToLineCol2(source, inner.start ?? 0);
20792
- throw VeskError.classDecl({ file, line, column, code: codeFrame(source, line, column) });
20793
- } else if (inner.type === "TSEnumDeclaration") {
20794
- const code = processEnum(inner, source, exported);
20795
- topLevelCode.push(code);
20796
- continue;
20797
- } else {
20798
- topLevelCode.push(getSource(source, node));
20799
- continue;
20800
- }
20801
- const name = inner.id.name;
20802
- const paramNames = getParamNames(inner.params, source);
20803
- const firstParam = inner.params?.[0];
20804
- const propsAlias = firstParam && firstParam.type === "Identifier" ? firstParam.name : null;
20805
- const propsType = getPropsType(inner.params, source);
20806
- const bodyStmts = inner.body.body;
20807
- const isClientComp = !!inner.client;
20808
- const prevSlotProps = __slotProps;
20809
- __slotProps = slotPropNamesFromType(propsType);
20810
- __propsParam = propsAlias || null;
20811
- if (isStatementMode(bodyStmts)) {
20812
- const raw2 = processStatementModeBody(source, bodyStmts, file);
20813
- const { body, css } = extractStyle(raw2);
20814
- validateBlocks(name, isClientComp, body, file, source);
20815
- const comp = new ComponentIR(name, paramNames, body, { mode: "statement", exported, defaultExport, isClient: inner.client, isAsync: inner.async, ssrAwait: componentUsesFetch(body), propsType, propsAlias });
20816
- comp.style = css;
20817
- components.push(comp);
20818
- __slotProps = prevSlotProps;
20819
- } else {
20820
- const guardClauses = [];
20821
- let mainReturn = null;
20822
- const preamble = [];
20823
- for (const stmt of bodyStmts) {
20824
- if (stmt.type === "VeskBlock") {
20825
- const innerBody = processStatementModeBody(source, stmt.body, file);
20826
- if (stmt.tag === "server") {
20827
- preamble.push(new ServerBlock(innerBody));
20828
- } else if (stmt.tag === "client") {
20829
- preamble.push(new ClientBlock(innerBody));
20830
- }
20831
- } else if (stmt.type === "ReturnStatement") {
20832
- mainReturn = stmt;
20833
- } else if (isTrackDeclaration(stmt)) {
20834
- const elements = stmt.declarations[0].id.elements;
20835
- const trackName = elements[0]?.name;
20836
- const rawName = elements.length > 1 ? elements[1]?.name : null;
20837
- const init = getSource(source, stmt.declarations[0].init);
20838
- if (trackName) preamble.push(new TrackDecl(trackName, init, rawName));
20839
- const refName = getComponentRefName(stmt);
20840
- if (refName) preamble.push(new ComponentRef(refName));
20841
- } else if (stmt.type === "IfStatement" && !mainReturn && stmt.consequent.type !== "ThrowStatement") {
20842
- guardClauses.push(stmt);
20843
- } else if (stmt.type === "ClassDeclaration") {
20844
- const { line, column } = offsetToLineCol2(source, stmt.start ?? 0);
20845
- throw VeskError.classDecl({ file, line, column, code: codeFrame(source, line, column) });
20846
- } else {
20847
- const raw2 = getSource(source, stmt);
20848
- if (raw2) preamble.push(new RuntimeStatement(raw2, stmt, source));
20849
- }
20850
- }
20851
- const guardBody = buildGuardChain(source, guardClauses, mainReturn);
20852
- const { body, css } = extractStyle([...preamble, ...guardBody]);
20853
- validateBlocks(name, isClientComp, body, file, source);
20854
- const comp = new ComponentIR(name, paramNames, body, { exported, defaultExport, isClient: inner.client, isAsync: inner.async, ssrAwait: componentUsesFetch(body), propsType, propsAlias });
20855
- comp.style = css;
20856
- components.push(comp);
20857
- __slotProps = prevSlotProps;
20858
- }
20859
- }
20860
- const asyncNames = new Set(components.filter((c) => c.isAsync || c.ssrAwait).map((c) => c.name));
20861
- for (const comp of components) {
20862
- if (asyncNames.has(comp.name)) continue;
20863
- const called2 = /* @__PURE__ */ new Map();
20864
- collectComponentCalls(comp.body, called2);
20865
- for (const [childName, start] of called2) {
20866
- if (!asyncNames.has(childName)) continue;
20867
- const { line, column } = offsetToLineCol2(source, start >= 0 ? start : 0);
20868
- throw VeskError.asyncChildInSyncParent(comp.name, childName, { file, line, column, code: codeFrame(source, line, column) });
20869
- }
20870
- }
20871
- const autoImportable = [
20872
- "useFetch",
20873
- "useRouter",
20874
- "useParams",
20875
- "usePathname",
20876
- "useSearchParams",
20877
- "useNavigate",
20878
- "defineAction",
20879
- "Form",
20880
- "Field",
20881
- "required",
20882
- "email",
20883
- "minLength",
20884
- "maxLength",
20885
- "pattern",
20886
- "custom",
20887
- "Link",
20888
- "NavLink",
20889
- "Outlet",
20890
- "Redirect",
20891
- "Image",
20892
- "Portal",
20893
- "Experiment",
20894
- "LoadingIndicator",
20895
- "useLoadingIndicator",
20896
- "JsonLd",
20897
- "ArticleSchema",
20898
- "ProductSchema",
20899
- "FAQPageSchema",
20900
- "BreadcrumbListSchema",
20901
- "OrganizationSchema",
20902
- "LocalBusinessSchema",
20903
- "VideoSchema",
20904
- "effect",
20905
- "derived",
20906
- "untrack",
20907
- "peek",
20908
- "tick",
20909
- "flushSync",
20910
- "on_destroy",
20911
- "createContext",
20912
- "redirect",
20913
- "permanentRedirect",
20914
- "notFound",
20915
- "NotFoundError",
20916
- "createResource",
20917
- "getAction",
20918
- "validateActionInput",
20919
- "issuesToFieldMap",
20920
- "isFormAction",
20921
- "Show",
20922
- "For",
20923
- "Switch",
20924
- "Match"
20925
- ];
20926
- const called = collectCallAndJsxTargets(ast);
20927
- const usedFunctions = /* @__PURE__ */ new Set();
20928
- for (const fn of autoImportable) {
20929
- if (called.has(fn)) usedFunctions.add(fn);
20930
- }
20931
- if (usedFunctions.size > 0) {
20932
- const existing = /* @__PURE__ */ new Set();
20933
- for (const imp of imports) {
20934
- if (importModuleTarget(imp) !== "@vesk/runtime") continue;
20935
- for (const n of extractImportNames(imp)) existing.add(n);
21283
+ const asyncNames = new Set(components.filter((c) => c.isAsync || c.ssrAwait).map((c) => c.name));
21284
+ for (const comp of components) {
21285
+ if (asyncNames.has(comp.name)) continue;
21286
+ const called2 = /* @__PURE__ */ new Map();
21287
+ collectComponentCalls(comp.body, called2);
21288
+ for (const [childName, start] of called2) {
21289
+ if (!asyncNames.has(childName)) continue;
21290
+ const { line, column } = offsetToLineCol2(source, start >= 0 ? start : 0);
21291
+ throw VeskError.asyncChildInSyncParent(comp.name, childName, { file, line, column, code: codeFrame(source, line, column) });
21292
+ }
20936
21293
  }
20937
- const boundLocally = /* @__PURE__ */ new Set();
20938
- for (const imp of imports) {
20939
- for (const pair of importBindingPairs(imp)) boundLocally.add(pair.local);
21294
+ const autoImportable = [
21295
+ "useFetch",
21296
+ "useRouter",
21297
+ "useParams",
21298
+ "usePathname",
21299
+ "useSearchParams",
21300
+ "useNavigate",
21301
+ "defineAction",
21302
+ "Form",
21303
+ "Field",
21304
+ "required",
21305
+ "email",
21306
+ "minLength",
21307
+ "maxLength",
21308
+ "pattern",
21309
+ "custom",
21310
+ "Link",
21311
+ "NavLink",
21312
+ "Outlet",
21313
+ "Redirect",
21314
+ "Image",
21315
+ "Portal",
21316
+ "Experiment",
21317
+ "LoadingIndicator",
21318
+ "useLoadingIndicator",
21319
+ "JsonLd",
21320
+ "ArticleSchema",
21321
+ "ProductSchema",
21322
+ "FAQPageSchema",
21323
+ "BreadcrumbListSchema",
21324
+ "OrganizationSchema",
21325
+ "LocalBusinessSchema",
21326
+ "VideoSchema",
21327
+ "effect",
21328
+ "derived",
21329
+ "untrack",
21330
+ "peek",
21331
+ "tick",
21332
+ "flushSync",
21333
+ "on_destroy",
21334
+ "createContext",
21335
+ "redirect",
21336
+ "permanentRedirect",
21337
+ "notFound",
21338
+ "NotFoundError",
21339
+ "createResource",
21340
+ "getAction",
21341
+ "validateActionInput",
21342
+ "issuesToFieldMap",
21343
+ "isFormAction",
21344
+ "Show",
21345
+ "For",
21346
+ "Switch",
21347
+ "Match",
21348
+ "primitive",
21349
+ "leaf"
21350
+ ];
21351
+ const called = collectCallAndJsxTargets(ast);
21352
+ const usedFunctions = /* @__PURE__ */ new Set();
21353
+ for (const fn of autoImportable) {
21354
+ if (called.has(fn)) usedFunctions.add(fn);
20940
21355
  }
20941
- const missing = [...usedFunctions].filter((f) => !existing.has(f) && !boundLocally.has(f));
20942
- if (missing.length > 0) {
20943
- imports.push(`import { ${missing.join(", ")} } from '@vesk/runtime';`);
21356
+ if (usedFunctions.size > 0) {
21357
+ const existing = /* @__PURE__ */ new Set();
21358
+ for (const imp of imports) {
21359
+ if (importModuleTarget(imp) !== "@vesk/runtime") continue;
21360
+ for (const n of extractImportNames(imp)) existing.add(n);
21361
+ }
21362
+ const boundLocally = /* @__PURE__ */ new Set();
21363
+ for (const imp of imports) {
21364
+ for (const pair of importBindingPairs(imp)) boundLocally.add(pair.local);
21365
+ }
21366
+ const missing = [...usedFunctions].filter((f) => !existing.has(f) && !boundLocally.has(f));
21367
+ if (missing.length > 0) {
21368
+ imports.push(`import { ${missing.join(", ")} } from '@vesk/runtime';`);
21369
+ }
20944
21370
  }
21371
+ return new IRRoot(components, imports, importedNames, staticProps, loadFn, topLevelCode, exportAliases, reexportSources);
21372
+ } finally {
21373
+ currentVskNamespaceLocals = prevNamespaceLocals;
21374
+ currentSourceFile = prevSourceFile;
20945
21375
  }
20946
- return new IRRoot(components, imports, importedNames, staticProps, loadFn, topLevelCode);
20947
21376
  }
20948
- var __vskAnnotations, __slotProps, __propsParam;
21377
+ var __vskAnnotations, __slotProps, __propsParam, currentVskNamespaceLocals, currentSourceFile;
20949
21378
  var init_ir_generator = __esm({
20950
21379
  "../compiler/src/ir-generator.ts"() {
20951
21380
  "use strict";
@@ -20960,6 +21389,7 @@ var init_ir_generator = __esm({
20960
21389
  __vskAnnotations = [];
20961
21390
  __slotProps = null;
20962
21391
  __propsParam = null;
21392
+ currentVskNamespaceLocals = null;
20963
21393
  }
20964
21394
  });
20965
21395
 
@@ -21853,6 +22283,13 @@ function loadRuntimeImports(importStrs) {
21853
22283
  }
21854
22284
  return {};
21855
22285
  }
22286
+ function patternElementName(element) {
22287
+ if (!element) return null;
22288
+ if (element.type === "Identifier") return element.name;
22289
+ if (element.type === "AssignmentPattern" && element.left) return patternElementName(element.left);
22290
+ if (element.type === "RestElement" && element.argument) return patternElementName(element.argument);
22291
+ return null;
22292
+ }
21856
22293
  function evalTopLevelCode(topLevelCode, __vesk) {
21857
22294
  for (const code of topLevelCode) {
21858
22295
  const ast = tryParseTopLevel(code);
@@ -21863,8 +22300,11 @@ function evalTopLevelCode(topLevelCode, __vesk) {
21863
22300
  if (!target) continue;
21864
22301
  if (target.type === "VariableDeclaration") {
21865
22302
  for (const d of target.declarations) {
21866
- if (!d.id || d.id.type !== "Identifier") continue;
21867
- const initSrc = d.init ? code.slice(d.init.start, d.init.end) : "undefined";
22303
+ if (!d.id) continue;
22304
+ const isTrack = d.id.type === "ArrayPattern" && d.id.lazy === true;
22305
+ const names = isTrack ? (d.id.elements || []).map(patternElementName) : d.id.type === "Identifier" ? [d.id.name] : [];
22306
+ if (names.every((n) => n === null)) continue;
22307
+ const initSrc = d.init ? stripTrackDeclMarkers(code.slice(d.init.start, d.init.end), d.init.start, d.init) : "undefined";
21868
22308
  try {
21869
22309
  const keys = Object.keys(__vesk);
21870
22310
  const params = [...keys, "__vesk", "result"];
@@ -21872,7 +22312,10 @@ function evalTopLevelCode(topLevelCode, __vesk) {
21872
22312
  const fn = new Function(...params, body);
21873
22313
  const result = { value: void 0 };
21874
22314
  fn(...keys.map((k) => __vesk[k]), __vesk, result);
21875
- __vesk[d.id.name] = result.value;
22315
+ names.forEach((name, i) => {
22316
+ if (name === null) return;
22317
+ __vesk[name] = isTrack ? Array.isArray(result.value) ? result.value[i] : void 0 : result.value;
22318
+ });
21876
22319
  } catch {
21877
22320
  }
21878
22321
  }
@@ -21882,7 +22325,7 @@ function evalTopLevelCode(topLevelCode, __vesk) {
21882
22325
  const keys = Object.keys(__vesk);
21883
22326
  const params = [...keys, "__vesk"];
21884
22327
  const paramSrc = target.params.length ? code.slice(target.params[0].start, target.params[target.params.length - 1].end) : "";
21885
- const bodySrc = code.slice(target.body.start, target.body.end);
22328
+ const bodySrc = stripTrackDeclMarkers(code.slice(target.body.start, target.body.end), target.body.start, target.body);
21886
22329
  const asyncKw = target.async ? "async " : "";
21887
22330
  const fn = new Function(...params, `__vesk['${target.id.name}'] = ${asyncKw}function ${target.id.name}(${paramSrc}) ${bodySrc};`);
21888
22331
  fn(...keys.map((k) => __vesk[k]), __vesk);
@@ -25830,6 +26273,96 @@ var init_headless = __esm({
25830
26273
  }
25831
26274
  });
25832
26275
 
26276
+ // ../runtime/src/primitive.ts
26277
+ function primitive(fn) {
26278
+ const wrapped = ((props, registry, scope2) => {
26279
+ return fn(props == null ? EMPTY_PROPS : props, registry, scope2);
26280
+ });
26281
+ wrapped.__veskPrimitive = true;
26282
+ return wrapped;
26283
+ }
26284
+ function leaf(fn) {
26285
+ fn.__veskLeaf = true;
26286
+ return fn;
26287
+ }
26288
+ function isPrimitive(value) {
26289
+ return typeof value === "function" && value.__veskPrimitive === true;
26290
+ }
26291
+ function isLeaf(value) {
26292
+ return typeof value === "function" && value.__veskLeaf === true;
26293
+ }
26294
+ function isVeskComponent(value) {
26295
+ return typeof value === "function";
26296
+ }
26297
+ function toDomNode(value) {
26298
+ if (typeof document === "undefined") return value;
26299
+ if (value == null || typeof value === "boolean") return value;
26300
+ if (typeof value.nodeType === "number") {
26301
+ return value;
26302
+ }
26303
+ if (typeof value !== "string") return value;
26304
+ if (value === "") return document.createDocumentFragment();
26305
+ const template = document.createElement("template");
26306
+ template.innerHTML = value;
26307
+ const { content } = template;
26308
+ if (content.childNodes.length === 1) {
26309
+ const only = content.firstChild;
26310
+ content.removeChild(only);
26311
+ return only;
26312
+ }
26313
+ return content;
26314
+ }
26315
+ function isCell2(value) {
26316
+ return typeof value === "object" && value !== null && typeof value.f === "number";
26317
+ }
26318
+ function readDep(dep) {
26319
+ return isCell2(dep) ? get(dep) : dep;
26320
+ }
26321
+ function rerenderNode(node, deps, call) {
26322
+ if (typeof document === "undefined") return node;
26323
+ if (deps.length === 0) return node;
26324
+ let owned = null;
26325
+ let current2 = null;
26326
+ if (Array.isArray(node)) {
26327
+ const roots = node.filter((n) => n && typeof n.nodeType === "number");
26328
+ owned = roots.length ? roots : null;
26329
+ current2 = owned ? owned[0] : null;
26330
+ } else if (node && typeof node.nodeType === "number") {
26331
+ current2 = node;
26332
+ }
26333
+ if (!current2) return node;
26334
+ const liveRange = () => {
26335
+ if (owned) return owned;
26336
+ return current2 && current2.parentNode ? [current2] : null;
26337
+ };
26338
+ let seen = deps.map(readDep);
26339
+ effect(() => {
26340
+ const now2 = deps.map(readDep);
26341
+ if (now2.length === seen.length && now2.every((v, i) => Object.is(v, seen[i]))) return;
26342
+ seen = now2;
26343
+ const old = liveRange();
26344
+ if (!old || !old[0].parentNode) return;
26345
+ const next = toDomNode(call());
26346
+ if (!next || typeof next.nodeType !== "number") return;
26347
+ const fresh = next.nodeType === 11 ? Array.from(next.childNodes) : [next];
26348
+ const parent = old[0].parentNode;
26349
+ for (const freshNode of fresh) parent.insertBefore(freshNode, old[0]);
26350
+ for (const oldNode of old) if (oldNode.parentNode) oldNode.parentNode.removeChild(oldNode);
26351
+ owned = next.nodeType === 11 ? fresh : null;
26352
+ current2 = fresh[0] ?? current2;
26353
+ });
26354
+ return node;
26355
+ }
26356
+ var EMPTY_PROPS;
26357
+ var init_primitive = __esm({
26358
+ "../runtime/src/primitive.ts"() {
26359
+ "use strict";
26360
+ init_ripple_runtime();
26361
+ init_ripple_blocks();
26362
+ EMPTY_PROPS = Object.freeze({});
26363
+ }
26364
+ });
26365
+
25833
26366
  // ../runtime/src/action.ts
25834
26367
  function getActionRegistry() {
25835
26368
  const g2 = globalThis;
@@ -25983,11 +26516,15 @@ __export(index_server_exports, {
25983
26516
  get_server_context: () => get_server_context,
25984
26517
  headers: () => headers,
25985
26518
  isFormAction: () => isFormAction,
26519
+ isLeaf: () => isLeaf,
25986
26520
  isLoadingActive: () => isLoadingActive,
26521
+ isPrimitive: () => isPrimitive,
26522
+ isVeskComponent: () => isVeskComponent,
25987
26523
  is_destroyed: () => is_destroyed,
25988
26524
  isr: () => isr,
25989
26525
  isrConfigToRevalidate: () => isrConfigToRevalidate,
25990
26526
  issuesToFieldMap: () => issuesToFieldMap,
26527
+ leaf: () => leaf,
25991
26528
  locals: () => locals,
25992
26529
  maxLength: () => maxLength,
25993
26530
  minLength: () => minLength,
@@ -26001,12 +26538,14 @@ __export(index_server_exports, {
26001
26538
  permanentRedirect: () => permanentRedirect,
26002
26539
  pop_component: () => pop_component,
26003
26540
  pre_effect: () => pre_effect,
26541
+ primitive: () => primitive,
26004
26542
  push_component: () => push_component,
26005
26543
  readSignedCookie: () => readSignedCookie2,
26006
26544
  redirect: () => redirect,
26007
26545
  removeHook: () => removeHook,
26008
26546
  render: () => render,
26009
26547
  required: () => required,
26548
+ rerenderNode: () => rerenderNode,
26010
26549
  resolveSsrResources: () => resolveSsrResources,
26011
26550
  resume_block: () => resume_block,
26012
26551
  revalidateComponent: () => revalidateComponent,
@@ -26030,6 +26569,7 @@ __export(index_server_exports, {
26030
26569
  set_server_context: () => set_server_context,
26031
26570
  signCookie: () => signCookie2,
26032
26571
  tick: () => tick,
26572
+ toDomNode: () => toDomNode,
26033
26573
  track: () => track,
26034
26574
  unlink_block: () => unlink_block,
26035
26575
  unsignCookie: () => unsignCookie2,
@@ -26068,6 +26608,7 @@ var init_index_server = __esm({
26068
26608
  init_form();
26069
26609
  init_md();
26070
26610
  init_headless();
26611
+ init_primitive();
26071
26612
  init_loading_indicator();
26072
26613
  init_action();
26073
26614
  }
@@ -28497,11 +29038,20 @@ function printWithTypesStripped(ast, code, hadTs = hasTsSyntax(ast)) {
28497
29038
  function transformTopLevelForActions(topLevelCode, mode) {
28498
29039
  const out = [];
28499
29040
  for (const c of topLevelCode) {
28500
- const rewritten = rewriteTopLevelActions(c, mode);
29041
+ const rewritten = rewriteTopLevelActions(stripTopLevelTrackDecls(c), mode);
28501
29042
  if (rewritten !== "") out.push(rewritten);
28502
29043
  }
28503
29044
  return out;
28504
29045
  }
29046
+ function stripTopLevelTrackDecls(code) {
29047
+ let ast;
29048
+ try {
29049
+ ast = parse4(code);
29050
+ } catch {
29051
+ return code;
29052
+ }
29053
+ return stripTrackDeclMarkers(code, 0, ast);
29054
+ }
28505
29055
  function collectActionIds(source) {
28506
29056
  const ids = [];
28507
29057
  const stmts = collectTopLevelStatements(source);
@@ -28557,6 +29107,7 @@ var init_actions = __esm({
28557
29107
  "use strict";
28558
29108
  init_parser();
28559
29109
  init_strip_ts();
29110
+ init_tokens();
28560
29111
  ACTION_PREFIX = "/_vesk/action/";
28561
29112
  }
28562
29113
  });
@@ -28684,6 +29235,39 @@ function simpleGetName(expr) {
28684
29235
  }
28685
29236
  return inner;
28686
29237
  }
29238
+ function untrackBindingArg(expr) {
29239
+ let head = -1;
29240
+ for (const name of BINDING_REF_CALLS) {
29241
+ if (expr.startsWith(`${name}(`)) {
29242
+ head = name.length;
29243
+ break;
29244
+ }
29245
+ }
29246
+ if (head < 0) return expr;
29247
+ const rest = expr.slice(head + 1);
29248
+ if (rest[0] !== "g" || rest[1] !== "e" || rest[2] !== "t" || rest[3] !== "(") return expr;
29249
+ let i = 4;
29250
+ let word = "";
29251
+ for (; i < rest.length; i++) {
29252
+ const c = rest.charCodeAt(i);
29253
+ const ok = c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95 || c === 36;
29254
+ if (!ok) break;
29255
+ word += rest[i];
29256
+ }
29257
+ if (word.length === 0 || rest[i] !== ")") return expr;
29258
+ const after = i + 1;
29259
+ if (rest[after] !== "," && rest[after] !== ")") return expr;
29260
+ return expr.slice(0, head + 1) + word + rest.slice(after);
29261
+ }
29262
+ function trackedRefTarget(expr, tracked2) {
29263
+ const cell = simpleGetName(expr);
29264
+ if (cell !== null) return cell;
29265
+ if (/^[A-Za-z_$][\w$]*$/.test(expr)) {
29266
+ const info = tracked2.get(expr);
29267
+ if (info && info.kind === "cell" && info.cellName === expr) return expr;
29268
+ }
29269
+ return null;
29270
+ }
28687
29271
  function semicolonizeStatement(code) {
28688
29272
  const trimmed = code.trimEnd();
28689
29273
  if (!trimmed || trimmed.endsWith(";") || trimmed.endsWith("}")) return code;
@@ -28782,6 +29366,21 @@ function transformTracked(irNode, tracked2) {
28782
29366
  }
28783
29367
  return context.next();
28784
29368
  },
29369
+ Property(node, context) {
29370
+ if (node.shorthand && node.value && node.value.type === "Identifier" && !node.computed) {
29371
+ const info = context.state.get(node.value.name);
29372
+ if (info && info.kind === "virtual") {
29373
+ return {
29374
+ ...node,
29375
+ shorthand: false,
29376
+ value: callExpr({ type: "Identifier", name: "get" }, [
29377
+ { type: "Identifier", name: info.cellName }
29378
+ ])
29379
+ };
29380
+ }
29381
+ }
29382
+ return context.next();
29383
+ },
28785
29384
  Identifier(node, context) {
28786
29385
  const parent = context.path.at(-1);
28787
29386
  if (parent) {
@@ -28793,6 +29392,8 @@ function transformTracked(irNode, tracked2) {
28793
29392
  return context.next();
28794
29393
  if (parent.type === "Property" && parent.value === node && parent.key && parent.key.type === "Identifier" && parent.key.name === "into")
28795
29394
  return context.next();
29395
+ if (parent.type === "Property" && parent.key === node && !parent.computed && !parent.shorthand)
29396
+ return context.next();
28796
29397
  if (parent.type === "MemberExpression" && !parent.computed && parent.object === node && parent.property && parent.property.type === "Identifier" && parent.property.name === "set")
28797
29398
  return context.next();
28798
29399
  }
@@ -28819,6 +29420,28 @@ function collectTrackedNames(body) {
28819
29420
  }
28820
29421
  return names;
28821
29422
  }
29423
+ function collectTrackedDeps(value, tracked2) {
29424
+ const ast = value?.ast;
29425
+ if (!ast || typeof ast !== "object" || tracked2.size === 0) return [];
29426
+ const found = [];
29427
+ const seen = /* @__PURE__ */ new Set();
29428
+ walk4(ast, tracked2, {
29429
+ Identifier(node, context) {
29430
+ const parent = context.path.at(-1);
29431
+ if (parent) {
29432
+ if (parent.type === "MemberExpression" && !parent.computed && parent.property === node) return context.next();
29433
+ if (parent.type === "Property" && parent.key === node) return context.next();
29434
+ }
29435
+ const info = context.state.get(node.name);
29436
+ if (info && !seen.has(node.name)) {
29437
+ seen.add(node.name);
29438
+ found.push(node.name);
29439
+ }
29440
+ return context.next();
29441
+ }
29442
+ });
29443
+ return found;
29444
+ }
28822
29445
  function transformTrackedInit(init, tracked2) {
28823
29446
  if (!init) return init;
28824
29447
  let expr = null;
@@ -29012,8 +29635,9 @@ function emitStatic(ctx2, node, tracked2, effectsVar, skipK = 0, regionBudget) {
29012
29635
  const target = attr.target || "";
29013
29636
  const isEvent2 = target.startsWith("on") && target.length > 2;
29014
29637
  if (target === "ref") {
29015
- const expr = transformTracked(attr.expression, tracked2);
29016
- ctx2.push(`(${expr})(${ssrEl});`);
29638
+ const expr = untrackBindingArg(transformTracked(attr.expression, tracked2));
29639
+ const cell = trackedRefTarget(expr, tracked2);
29640
+ ctx2.push(cell !== null ? `set(${cell}, ${ssrEl});` : `(${expr})(${ssrEl});`);
29017
29641
  } else if (isEvent2) {
29018
29642
  const eventName = target.slice(2).toLowerCase();
29019
29643
  const handler = transformTracked(attr.expression, tracked2);
@@ -29070,8 +29694,9 @@ function emitStatic(ctx2, node, tracked2, effectsVar, skipK = 0, regionBudget) {
29070
29694
  const target = attr.target || "";
29071
29695
  const isEvent2 = target.startsWith("on") && target.length > 2;
29072
29696
  if (target === "ref") {
29073
- const expr = transformTracked(attr.expression, tracked2);
29074
- ctx2.push(`(${expr})(${el});`);
29697
+ const expr = untrackBindingArg(transformTracked(attr.expression, tracked2));
29698
+ const cell = trackedRefTarget(expr, tracked2);
29699
+ ctx2.push(cell !== null ? `set(${cell}, ${el});` : `(${expr})(${el});`);
29075
29700
  } else if (isEvent2) {
29076
29701
  const eventName = target.slice(2).toLowerCase();
29077
29702
  const handler = transformTracked(attr.expression, tracked2);
@@ -29265,19 +29890,29 @@ function emitComponentCall(ctx2, node, tracked2, effectsVar, parentVar, compPref
29265
29890
  const calleeExpr = node.calleeExpr ? `(${node.calleeExpr})` : null;
29266
29891
  const slotChildren = node.children.filter((c) => c instanceof PropSlot);
29267
29892
  const regChildren = node.children.filter((c) => !(c instanceof PropSlot));
29268
- const callArgs = () => `{ ${propsEntries.join(", ")} }`;
29893
+ const plainTarget = !!(calleeExpr || ctx2.importedNames.has(node.componentName)) && !ctx2.selfClaimNames.has(node.componentName);
29894
+ const trackedDeps = [];
29895
+ if (plainTarget) {
29896
+ for (const p of node.props) {
29897
+ if (typeof p.value === "string") continue;
29898
+ for (const d of collectTrackedDeps(p.value, tracked2)) if (!trackedDeps.includes(d)) trackedDeps.push(d);
29899
+ }
29900
+ for (const sp of node.spreadProps) {
29901
+ for (const d of collectTrackedDeps(sp, tracked2)) if (!trackedDeps.includes(d)) trackedDeps.push(d);
29902
+ }
29903
+ }
29904
+ const callArgs = () => plainTarget ? `reactiveProps({ ${propsEntries.join(", ")} })` : `{ ${propsEntries.join(", ")} }`;
29269
29905
  if (ctx2.hydrate) {
29270
29906
  const access = calleeExpr ?? (ctx2.importedNames.has(node.componentName) ? node.componentName : `__components[${JSON.stringify(node.componentName)}]`);
29271
29907
  if (!calleeExpr && !ctx2.importedNames.has(node.componentName)) {
29272
29908
  ctx2.push(`if (${access} == null) throw new Error(${JSON.stringify(`Component "${node.componentName}" was not found while rendering. Declare it with the \`component\` keyword, import it, or register it in the component registry.`)});`);
29273
29909
  }
29274
- const plainTarget = !!(calleeExpr || ctx2.importedNames.has(node.componentName)) && !ctx2.selfClaimNames.has(node.componentName);
29275
29910
  const walkerArg = ctx2.walker;
29276
29911
  const promptExpr = ctx2.markerless && (regionBudget || skipK > 0) ? markerlessSkipExpr(regionBudget, skipK) : null;
29277
29912
  const maybeReplace = (v2) => {
29278
29913
  if (!plainTarget) return;
29279
29914
  const claim = promptExpr ? `${walkerArg}.claimOnly(undefined, ${promptExpr})` : `${walkerArg}.claimOnly()`;
29280
- ctx2.push(`if (${v2} && ${v2}.parentNode == null && ${v2}.nodeType !== 11) { const __sr = ${claim}; if (__sr && __sr.parentNode) __sr.parentNode.replaceChild(${v2}, __sr); }`);
29915
+ ctx2.push(`if (${v2} && ${v2}.parentNode == null) { if (${v2}.nodeType === 11) { const __cnt = ${v2}.childNodes.length; let __sr = null; for (let __i = 0; __i < __cnt; __i++) { const __c = ${claim}; if (__c && __c.parentNode) { if (__sr) { __c.remove(); } else { __sr = __c; } } } if (__sr) { const __p = __sr.parentNode; while (${v2}.firstChild) __p.insertBefore(${v2}.firstChild, __sr); __p.removeChild(__sr); } } else { const __sr = ${claim}; if (__sr && __sr.parentNode) __sr.parentNode.replaceChild(${v2}, __sr); } }`);
29281
29916
  if (regionBudget && ctx2.markerless) ctx2.push(`${regionBudget} = 0;`);
29282
29917
  };
29283
29918
  const maybeRetire = () => {
@@ -29312,10 +29947,15 @@ function emitComponentCall(ctx2, node, tracked2, effectsVar, parentVar, compPref
29312
29947
  }
29313
29948
  ctx2.push(`let ${v} = undefined;`);
29314
29949
  ctx2.push(`if (__hydrate) __hydrate.childFrame = (__hydrate.childFrame || 0) + 1;`);
29315
- ctx2.push(`try { ${v} = ${awaitKw}${access}(${callArgs()}, __registry, ${walkerArg}); } finally { if (__hydrate) __hydrate.childFrame--; }`);
29950
+ ctx2.push(`try { ${v} = toDomNode(${awaitKw}${access}(${callArgs()}, __registry, ${walkerArg})); } finally { if (__hydrate) __hydrate.childFrame--; }`);
29951
+ const rootsVar = trackedDeps.length > 0 ? ctx2.n() : null;
29952
+ if (rootsVar) ctx2.push(`const ${rootsVar} = ${v} && ${v}.nodeType === 11 ? Array.from(${v}.childNodes) : [${v}];`);
29316
29953
  if (ctx2.markerless && promptExpr && !plainTarget && regionBudget) ctx2.push(`${regionBudget} = 0;`);
29317
29954
  maybeReplace(v);
29318
29955
  maybeRetire();
29956
+ if (trackedDeps.length > 0) {
29957
+ ctx2.push(`rerenderNode(${rootsVar}, [${trackedDeps.join(", ")}], () => ${awaitKw}${access}(${callArgs()}, __registry, ${walkerArg}));`);
29958
+ }
29319
29959
  return v;
29320
29960
  } else {
29321
29961
  for (const slot of slotChildren) {
@@ -29337,12 +29977,18 @@ function emitComponentCall(ctx2, node, tracked2, effectsVar, parentVar, compPref
29337
29977
  propsEntries.push(`children: ${frag}`);
29338
29978
  }
29339
29979
  if (calleeExpr) {
29340
- ctx2.push(`const ${v} = ${calleeExpr}(${callArgs()});`);
29980
+ ctx2.push(`const ${v} = toDomNode(${calleeExpr}(${callArgs()}));`);
29341
29981
  } else if (ctx2.importedNames.has(node.componentName)) {
29342
- ctx2.push(`const ${v} = ${awaitKw}${node.componentName}(${callArgs()});`);
29982
+ ctx2.push(`const ${v} = toDomNode(${awaitKw}${node.componentName}(${callArgs()}));`);
29343
29983
  } else {
29344
29984
  ctx2.push(`if (${compPrefix}[${JSON.stringify(node.componentName)}] == null) throw new Error(${JSON.stringify(`Component "${node.componentName}" was not found while rendering. Declare it with the \`component\` keyword, import it, or register it in the component registry.`)});`);
29345
- ctx2.push(`const ${v} = ${awaitKw}${compPrefix}[${JSON.stringify(node.componentName)}](${callArgs()});`);
29985
+ ctx2.push(`const ${v} = toDomNode(${awaitKw}${compPrefix}[${JSON.stringify(node.componentName)}](${callArgs()}));`);
29986
+ }
29987
+ if (trackedDeps.length > 0) {
29988
+ const calleeRef = calleeExpr ?? (ctx2.importedNames.has(node.componentName) ? node.componentName : `${compPrefix}[${JSON.stringify(node.componentName)}]`);
29989
+ const rootsVar2 = ctx2.n();
29990
+ ctx2.push(`const ${rootsVar2} = ${v} && ${v}.nodeType === 11 ? Array.from(${v}.childNodes) : [${v}];`);
29991
+ ctx2.push(`rerenderNode(${rootsVar2}, [${trackedDeps.join(", ")}], () => ${awaitKw}${calleeRef}(${callArgs()}));`);
29346
29992
  }
29347
29993
  }
29348
29994
  return v;
@@ -30428,7 +31074,7 @@ function emitClientFromIR(ir, options) {
30428
31074
  }
30429
31075
  }
30430
31076
  const exportCode = exportLines.join("\n");
30431
- const runtimeNames = ["track", "get", "set", "destroy_block", "getActiveComponent", "setActiveComponent", "reactiveProps", "applyStyle"];
31077
+ const runtimeNames = ["track", "get", "set", "destroy_block", "getActiveComponent", "setActiveComponent", "reactiveProps", "applyStyle", "toDomNode", "rerenderNode"];
30432
31078
  if (ir.components.some((c) => !isStaticIR(c.body))) runtimeNames.push("effect");
30433
31079
  for (const name of usedRuntimeBindings(ir)) runtimeNames.push(name);
30434
31080
  for (const name of ["derived"]) {
@@ -30489,14 +31135,26 @@ function compileClientBoth(source, _componentName, sourcePath2, opts) {
30489
31135
  }
30490
31136
  const alloc = nameAllocFor(sourcePath2);
30491
31137
  const comp = emitClientFromIR(ir, { forceClient: true, nameAllocator: alloc });
30492
- if (opts?.skipHyd) return { comp, hyd: "", name };
31138
+ const aliases = vskRegistryAliases(ir.imports, ir.exportAliases);
31139
+ const reexportPaths = sourcePath2 ? collectVskReexportPaths(ir.reexportSources, sourcePath2) : [];
31140
+ if (opts?.skipHyd) return { comp, hyd: "", name, aliases, reexportPaths, componentNames: ir.components.map((c) => c.name) };
30493
31141
  return {
30494
31142
  comp,
30495
31143
  hyd: emitClientFromIR(irHyd, { forceClient: true, hydrate: true, includeTopLevel: false, nameAllocator: alloc, markerless: opts?.markerless !== false }),
30496
- name
31144
+ name,
31145
+ aliases,
31146
+ reexportPaths,
31147
+ // Every component NAME this file registers, not just the resolved one —
31148
+ // the bundle needs the full list to spot same-name declarations across
31149
+ // files (see findVskComponentCollisions).
31150
+ componentNames: ir.components.map((c) => c.name)
30497
31151
  };
30498
31152
  }
30499
- var NON_BUBBLING_EVENTS, Ctx, PROPERTY_ATTRS;
31153
+ function vskComponentNames(source, sourcePath2) {
31154
+ const ast = parse4(source, sourcePath2 ? { filename: sourcePath2 } : {});
31155
+ return generateIR(ast, source, sourcePath2).components.map((c) => c.name);
31156
+ }
31157
+ var BINDING_REF_CALLS, NON_BUBBLING_EVENTS, Ctx, PROPERTY_ATTRS;
30500
31158
  var init_client_codegen = __esm({
30501
31159
  "../compiler/src/client-codegen.ts"() {
30502
31160
  "use strict";
@@ -30508,8 +31166,10 @@ var init_client_codegen = __esm({
30508
31166
  init_module_imports();
30509
31167
  init_scan();
30510
31168
  init_tokens();
31169
+ init_vsk_imports();
30511
31170
  init_md_inline();
30512
31171
  init_strip_ts();
31172
+ BINDING_REF_CALLS = ["bindValue", "bindChecked", "bindGroup"];
30513
31173
  NON_BUBBLING_EVENTS = /* @__PURE__ */ new Set([
30514
31174
  "focus",
30515
31175
  "blur",
@@ -31045,7 +31705,8 @@ function buildComponentEntries(irRoot) {
31045
31705
  const importedNames = /* @__PURE__ */ new Set([...runtimeNames, ...localValueNames, ...topValueNames]);
31046
31706
  const hasTracked = irRoot.components.some((c) => c.body.some((n) => n instanceof TrackDecl));
31047
31707
  const extraNames = hasTracked ? ["get", "set", "track"] : [];
31048
- const allNames = [.../* @__PURE__ */ new Set([...runtimeNames, ...topNames, ...extraNames, ...localValueNames])];
31708
+ const vskValueNames = vskImportValueNames(irRoot.imports);
31709
+ const allNames = [.../* @__PURE__ */ new Set([...runtimeNames, ...topNames, ...extraNames, ...localValueNames, ...vskValueNames])];
31049
31710
  const scopeDecl = allNames.length > 0 ? `const { ${allNames.join(", ")} } = __vesk;
31050
31711
  ` : "";
31051
31712
  setVskImportedNames(importedNames);
@@ -31086,41 +31747,155 @@ var init_server_jsgen = __esm({
31086
31747
  init_scan();
31087
31748
  init_server_utils();
31088
31749
  init_module_imports();
31750
+ init_vsk_imports();
31089
31751
  __currentCompName = "";
31090
31752
  }
31091
31753
  });
31092
31754
 
31093
31755
  // ../compiler/src/ssr-store.ts
31094
31756
  import { AsyncLocalStorage } from "node:async_hooks";
31757
+ function newSsrToken() {
31758
+ return Math.random().toString(36).slice(2);
31759
+ }
31760
+ function createSsrStore() {
31761
+ return { token: newSsrToken(), data: {} };
31762
+ }
31763
+ function adoptSsrStore() {
31764
+ return storage.getStore() ?? createSsrStore();
31765
+ }
31766
+ function isThenable(value) {
31767
+ return typeof value?.then === "function";
31768
+ }
31095
31769
  function withSsrStore(fn) {
31096
31770
  const existing = storage.getStore();
31097
31771
  if (existing) return fn();
31098
- return storage.run({}, fn);
31772
+ const store = createSsrStore();
31773
+ keepSsrSlot(store.token);
31774
+ let result;
31775
+ try {
31776
+ result = storage.run(store, fn);
31777
+ } catch (err) {
31778
+ dropSsrSlot(store.token);
31779
+ throw err;
31780
+ }
31781
+ if (isThenable(result)) {
31782
+ return result.then(
31783
+ (value) => {
31784
+ dropSsrSlot(store.token);
31785
+ return value;
31786
+ },
31787
+ (err) => {
31788
+ dropSsrSlot(store.token);
31789
+ throw err;
31790
+ }
31791
+ );
31792
+ }
31793
+ dropSsrSlot(store.token);
31794
+ return result;
31795
+ }
31796
+ function withSsrStoreOf(store, fn) {
31797
+ return storage.run(store, fn);
31099
31798
  }
31100
- var storage, ssrSink2;
31799
+ function keepSsrSlot(token) {
31800
+ if (!token) return;
31801
+ liveSlots.set(token, (liveSlots.get(token) ?? 0) + 1);
31802
+ }
31803
+ function dropSsrSlot(token) {
31804
+ if (!token) return;
31805
+ const count = liveSlots.get(token);
31806
+ if (count === void 0) return;
31807
+ if (count <= 1) liveSlots.delete(token);
31808
+ else liveSlots.set(token, count - 1);
31809
+ }
31810
+ function isSsrSlotLive(token) {
31811
+ return liveSlots.has(token);
31812
+ }
31813
+ var TOKEN_KEY, storage, liveSlots, ssrSink2;
31101
31814
  var init_ssr_store = __esm({
31102
31815
  "../compiler/src/ssr-store.ts"() {
31103
31816
  "use strict";
31104
31817
  init_index_server();
31818
+ TOKEN_KEY = "__vsk_ssr_token";
31105
31819
  storage = new AsyncLocalStorage();
31820
+ liveSlots = /* @__PURE__ */ new Map();
31106
31821
  ssrSink2 = {
31107
31822
  set: (key, value) => {
31108
31823
  const store = storage.getStore();
31109
- if (store) store[key] = value;
31824
+ if (store) store.data[key] = value;
31110
31825
  },
31111
31826
  get: (key) => {
31112
31827
  const store = storage.getStore();
31113
- return store ? store[key] : void 0;
31828
+ return store ? store.data[key] : void 0;
31114
31829
  },
31115
- snapshot: () => ({ ...storage.getStore() ?? {} }),
31830
+ snapshot: () => ({ ...storage.getStore()?.data ?? {} }),
31116
31831
  clear: () => {
31117
31832
  const store = storage.getStore();
31118
31833
  if (store) {
31119
- for (const key of Object.keys(store)) delete store[key];
31834
+ for (const key of Object.keys(store.data)) delete store.data[key];
31120
31835
  }
31121
31836
  }
31122
31837
  };
31123
31838
  setSsrSink(ssrSink2);
31839
+ Object.defineProperty(globalThis, TOKEN_KEY, {
31840
+ configurable: true,
31841
+ get() {
31842
+ return storage.getStore()?.token;
31843
+ },
31844
+ set(value) {
31845
+ const store = storage.getStore();
31846
+ if (store) store.token = value;
31847
+ }
31848
+ });
31849
+ }
31850
+ });
31851
+
31852
+ // ../compiler/src/vsk-collision.ts
31853
+ var VskComponentOwners, reportedCollisions;
31854
+ var init_vsk_collision = __esm({
31855
+ "../compiler/src/vsk-collision.ts"() {
31856
+ "use strict";
31857
+ VskComponentOwners = class {
31858
+ owners = /* @__PURE__ */ new Map();
31859
+ /** Records that `file` declares a component called `name`. */
31860
+ claim(name, file) {
31861
+ let set2 = this.owners.get(name);
31862
+ if (!set2) {
31863
+ set2 = /* @__PURE__ */ new Set();
31864
+ this.owners.set(name, set2);
31865
+ }
31866
+ set2.add(file);
31867
+ }
31868
+ /** Names declared by more than one file, each with its declaring files. */
31869
+ collisions() {
31870
+ const out = [];
31871
+ for (const [name, files] of this.owners) {
31872
+ if (files.size > 1) out.push({ name, files: [...files] });
31873
+ }
31874
+ return out.sort((a, b) => a.name.localeCompare(b.name));
31875
+ }
31876
+ /**
31877
+ * Warns once per colliding name. Returns the message per collision so a
31878
+ * caller (or a test) can assert on the text without capturing stderr.
31879
+ *
31880
+ * Deduped by name for the life of the process: the SSR path compiles one
31881
+ * file graph per `compileFile` call, so without this a single build would
31882
+ * repeat the same warning once per entry page.
31883
+ */
31884
+ report(context) {
31885
+ const collisions = this.collisions();
31886
+ const fresh = [];
31887
+ for (const { name, files } of collisions) {
31888
+ if (reportedCollisions.has(name)) continue;
31889
+ reportedCollisions.add(name);
31890
+ fresh.push(`${name}: ${files.join(", ")}`);
31891
+ console.warn(
31892
+ `[vesk] ${context}: component "${name}" is declared in ${files.length} files and resolves to only one of them \u2014 ${files.join(", ")}. Which one wins depends on compile order, and the client and server registries pick differently, so this can render a different component in the browser than in the SSR HTML. Rename one of them.`
31893
+ );
31894
+ }
31895
+ return fresh;
31896
+ }
31897
+ };
31898
+ reportedCollisions = /* @__PURE__ */ new Set();
31124
31899
  }
31125
31900
  });
31126
31901
 
@@ -31144,9 +31919,12 @@ function scopedVesk(fn, fallback) {
31144
31919
  return fn.__veskScope || fallback;
31145
31920
  }
31146
31921
  function compileFile(source, options) {
31147
- return compileFileInternal(source, options?.sourcePath, /* @__PURE__ */ new Set());
31922
+ const owners = new VskComponentOwners();
31923
+ const result = compileFileInternal(source, options?.sourcePath, /* @__PURE__ */ new Set(), owners);
31924
+ owners.report("SSR");
31925
+ return result;
31148
31926
  }
31149
- function compileFileInternal(source, sourcePath2, seenImportFiles) {
31927
+ function compileFileInternal(source, sourcePath2, seenImportFiles, owners) {
31150
31928
  if (sourcePath2) {
31151
31929
  const dir = dirname7(sourcePath2);
31152
31930
  source = inlineMdImportsFrom(source, sourcePath2, guessProjectRoots(dir));
@@ -31155,10 +31933,15 @@ function compileFileInternal(source, sourcePath2, seenImportFiles) {
31155
31933
  const ir = generateIR(ast, source, sourcePath2);
31156
31934
  const componentMap = buildComponentMap2(ir, true);
31157
31935
  const ownComponentNames = ir.components.map((c) => c.name);
31936
+ if (sourcePath2 && owners) for (const n of ownComponentNames) owners.claim(n, sourcePath2);
31158
31937
  const __vesk = loadRuntimeImports(ir.imports);
31159
31938
  applyLocalModuleImports(__vesk, ir.imports, sourcePath2);
31160
31939
  if (sourcePath2) {
31161
- for (const importPath of collectVskImportPaths(ir.imports, sourcePath2)) {
31940
+ const vskPaths = [
31941
+ ...collectVskImportPaths(ir.imports, sourcePath2),
31942
+ ...collectVskReexportPaths(ir.reexportSources, sourcePath2)
31943
+ ];
31944
+ for (const importPath of vskPaths) {
31162
31945
  if (seenImportFiles.has(importPath)) continue;
31163
31946
  seenImportFiles.add(importPath);
31164
31947
  let importedSrc;
@@ -31167,7 +31950,7 @@ function compileFileInternal(source, sourcePath2, seenImportFiles) {
31167
31950
  } catch {
31168
31951
  continue;
31169
31952
  }
31170
- const sub = compileFileInternal(importedSrc, importPath, seenImportFiles);
31953
+ const sub = compileFileInternal(importedSrc, importPath, seenImportFiles, owners);
31171
31954
  for (const [name, fn] of sub.componentMap) {
31172
31955
  if (!componentMap.has(name)) componentMap.set(name, fn);
31173
31956
  }
@@ -31178,6 +31961,7 @@ function compileFileInternal(source, sourcePath2, seenImportFiles) {
31178
31961
  }
31179
31962
  }
31180
31963
  evalTopLevelCode(transformTopLevelForActions(ir.topLevelCode, "server"), __vesk);
31964
+ applyVskRegistryAliases(componentMap, vskRegistryAliases(ir.imports, ir.exportAliases));
31181
31965
  for (const name of ownComponentNames) {
31182
31966
  const fn = componentMap.get(name);
31183
31967
  if (fn && !fn.__veskScope) fn.__veskScope = __vesk;
@@ -31195,29 +31979,32 @@ function render2(source, componentName, props = {}, registry = /* @__PURE__ */ n
31195
31979
  const targetComp = compiled.ir.components.find((c) => c.name === componentName);
31196
31980
  const isAsyncComp = !!(targetComp && (targetComp.isAsync || targetComp.ssrAwait));
31197
31981
  globalThis.__vsk_ssr = true;
31198
- if (!globalThis.__vsk_ssr_token) globalThis.__vsk_ssr_token = Math.random().toString(36).slice(2);
31199
- const renderToken = globalThis.__vsk_ssr_token;
31200
- if (isAsyncComp) {
31201
- return withSsrStore(() => (async () => {
31202
- let bodyHtml2;
31203
- try {
31204
- bodyHtml2 = await renderFn(props, fullRegistry, scopedVesk(renderFn, __vesk));
31205
- } finally {
31206
- delete globalThis.__vsk_ssr;
31207
- await settleSsrPromises(renderToken);
31208
- clearSsrCells(renderToken);
31209
- }
31210
- return bodyHtml2;
31211
- })());
31212
- }
31213
- let bodyHtml;
31214
- try {
31215
- bodyHtml = withSsrStore(() => renderFn(props, fullRegistry, scopedVesk(renderFn, __vesk)));
31216
- } finally {
31217
- delete globalThis.__vsk_ssr;
31218
- clearSsrCells(renderToken);
31219
- }
31220
- return bodyHtml;
31982
+ return withSsrStore(() => {
31983
+ if (!globalThis.__vsk_ssr_token) globalThis.__vsk_ssr_token = Math.random().toString(36).slice(2);
31984
+ const renderToken = globalThis.__vsk_ssr_token;
31985
+ keepSsrSlot(renderToken);
31986
+ if (isAsyncComp) {
31987
+ return (async () => {
31988
+ let bodyHtml2;
31989
+ try {
31990
+ bodyHtml2 = await renderFn(props, fullRegistry, scopedVesk(renderFn, __vesk));
31991
+ } finally {
31992
+ delete globalThis.__vsk_ssr;
31993
+ await settleSsrPromises(renderToken);
31994
+ clearSsrCells(renderToken);
31995
+ }
31996
+ return bodyHtml2;
31997
+ })();
31998
+ }
31999
+ let bodyHtml;
32000
+ try {
32001
+ bodyHtml = renderFn(props, fullRegistry, scopedVesk(renderFn, __vesk));
32002
+ } finally {
32003
+ delete globalThis.__vsk_ssr;
32004
+ clearSsrCells(renderToken);
32005
+ }
32006
+ return bodyHtml;
32007
+ });
31221
32008
  }
31222
32009
  function renderPage(source, componentName, props = {}, registry = /* @__PURE__ */ new Map(), options = {}) {
31223
32010
  resetVskState(!!options.hydrate, options.markerless !== false);
@@ -31241,9 +32028,10 @@ function renderPage(source, componentName, props = {}, registry = /* @__PURE__ *
31241
32028
  globalThis.__vsk_ssr = true;
31242
32029
  if (!globalThis.__vsk_ssr_token) globalThis.__vsk_ssr_token = Math.random().toString(36).slice(2);
31243
32030
  const renderToken = globalThis.__vsk_ssr_token;
32031
+ keepSsrSlot(renderToken);
31244
32032
  pruneSsrDataSlots();
31245
32033
  if (targetComp && (targetComp.isAsync || targetComp.ssrAwait)) {
31246
- return withSsrStore(() => (async () => {
32034
+ return (async () => {
31247
32035
  let bodyHtml2;
31248
32036
  try {
31249
32037
  bodyHtml2 = await renderFn(ssrProps, fullRegistry, scopedVesk(renderFn, __vesk));
@@ -31257,22 +32045,22 @@ function renderPage(source, componentName, props = {}, registry = /* @__PURE__ *
31257
32045
  head: renderHeadHtml(targetComp, ssrProps),
31258
32046
  props: ssrProps
31259
32047
  };
31260
- })());
32048
+ })();
31261
32049
  }
31262
32050
  let bodyHtml;
31263
32051
  try {
31264
- bodyHtml = withSsrStore(() => renderFn(ssrProps, fullRegistry, scopedVesk(renderFn, __vesk)));
32052
+ bodyHtml = renderFn(ssrProps, fullRegistry, scopedVesk(renderFn, __vesk));
31265
32053
  } finally {
31266
32054
  delete globalThis.__vsk_ssr;
31267
32055
  }
31268
32056
  const headHtml = targetComp ? renderHeadHtml(targetComp, ssrProps) : "";
31269
32057
  const pending = globalThis[`__vsk_ssr_promises_${renderToken}`];
31270
32058
  if (pending && pending.length > 0) {
31271
- return withSsrStore(() => (async () => {
32059
+ return (async () => {
31272
32060
  await settleSsrPromises(renderToken);
31273
32061
  clearSsrCells(renderToken);
31274
32062
  return { body: bodyHtml, head: headHtml, props: ssrProps };
31275
- })());
32063
+ })();
31276
32064
  }
31277
32065
  clearSsrCells(renderToken);
31278
32066
  return { body: bodyHtml, head: headHtml, props: ssrProps };
@@ -31296,6 +32084,7 @@ function clearSsrCells(token) {
31296
32084
  if (!token) return;
31297
32085
  delete globalThis[`__vsk_ssr_promises_${token}`];
31298
32086
  delete globalThis[`__vsk_ssr_failures_${token}`];
32087
+ dropSsrSlot(token);
31299
32088
  const cells = globalThis.__vsk_ssr_cells;
31300
32089
  if (!cells || !(cells instanceof Map)) return;
31301
32090
  for (const k of cells.keys()) {
@@ -31304,15 +32093,27 @@ function clearSsrCells(token) {
31304
32093
  }
31305
32094
  async function settleSsrPromises(token) {
31306
32095
  if (!token) return;
31307
- const pending = globalThis[`__vsk_ssr_promises_${token}`];
31308
- if (!pending || pending.length === 0) return;
31309
- await Promise.allSettled(pending);
32096
+ const key = `__vsk_ssr_promises_${token}`;
32097
+ for (let round = 0; round < 10; round++) {
32098
+ const pending = globalThis[key];
32099
+ if (!pending || pending.length === 0) return;
32100
+ const before = pending.length;
32101
+ await Promise.allSettled(pending.slice());
32102
+ const after = globalThis[key];
32103
+ if (!after || after.length <= before) return;
32104
+ }
31310
32105
  }
31311
32106
  function pruneSsrDataSlots() {
31312
32107
  const g2 = globalThis;
31313
- const keys = Object.keys(g2).filter((k) => typeof k === "string" && k.startsWith("__vsk_ssr_data_"));
31314
- if (keys.length <= 40) return;
31315
- keys.sort().slice(0, keys.length - 40).forEach((k) => {
32108
+ const prefix = "__vsk_ssr_data_";
32109
+ const stale = [];
32110
+ for (const k of Object.keys(g2)) {
32111
+ if (typeof k !== "string" || !k.startsWith(prefix)) continue;
32112
+ if (isSsrSlotLive(k.slice(prefix.length))) continue;
32113
+ stale.push(k);
32114
+ }
32115
+ if (stale.length <= 40) return;
32116
+ stale.sort().slice(0, stale.length - 40).forEach((k) => {
31316
32117
  delete g2[k];
31317
32118
  });
31318
32119
  }
@@ -31443,6 +32244,7 @@ async function renderFullPage(source, componentName, props = {}, registry = /* @
31443
32244
  globalThis.__vsk_ssr = true;
31444
32245
  if (!globalThis.__vsk_ssr_token) globalThis.__vsk_ssr_token = Math.random().toString(36).slice(2);
31445
32246
  const renderToken = globalThis.__vsk_ssr_token;
32247
+ keepSsrSlot(renderToken);
31446
32248
  pruneSsrDataSlots();
31447
32249
  globalThis.__vsk_ssr_data = {};
31448
32250
  try {
@@ -31519,12 +32321,15 @@ ${dataScriptBlock}${clientScript}</body>
31519
32321
  } finally {
31520
32322
  delete globalThis.__vsk_ssr;
31521
32323
  delete globalThis[`__vsk_ssr_data_${renderToken}`];
31522
- delete globalThis.__vsk_ssr_token;
32324
+ dropSsrSlot(renderToken);
31523
32325
  pruneSsrDataSlots();
31524
32326
  }
31525
32327
  });
31526
32328
  }
31527
32329
  function renderPageStream(source, componentName, props = {}, registry = /* @__PURE__ */ new Map(), options = {}) {
32330
+ const streamStore = adoptSsrStore();
32331
+ keepSsrSlot(streamStore.token);
32332
+ const streamToken = streamStore.token;
31528
32333
  async function* raw2() {
31529
32334
  const cached = options.cached || void 0;
31530
32335
  const ir = cached ? cached.ir : generateIR(parse4(source, options.sourcePath ? { filename: options.sourcePath } : {}), source, options.sourcePath);
@@ -31593,8 +32398,7 @@ function renderPageStream(source, componentName, props = {}, registry = /* @__PU
31593
32398
  yield '</head>\n<body>\n<div id="root">\n';
31594
32399
  globalThis.__vsk_ssr = true;
31595
32400
  globalThis.__vsk_ssr_data = {};
31596
- if (!globalThis.__vsk_ssr_token) globalThis.__vsk_ssr_token = Math.random().toString(36).slice(2);
31597
- const renderToken = globalThis.__vsk_ssr_token;
32401
+ const renderToken = streamToken;
31598
32402
  pruneSsrDataSlots();
31599
32403
  let bodyHtml;
31600
32404
  try {
@@ -31614,7 +32418,7 @@ function renderPageStream(source, componentName, props = {}, registry = /* @__PU
31614
32418
  console.error(`[render-trace] renderPageStream comp=${componentName} keys=${Object.keys(ssrData).join(",") || "\u2205"} slot=${Object.keys(slot).join(",") || "\u2205"} sink=${Object.keys(ssrSink2.snapshot()).join(",") || "\u2205"}`);
31615
32419
  }
31616
32420
  delete globalThis[`__vsk_ssr_data_${renderToken}`];
31617
- delete globalThis.__vsk_ssr_token;
32421
+ dropSsrSlot(renderToken);
31618
32422
  pruneSsrDataSlots();
31619
32423
  const dataScripts = buildDataScripts(ssrProps, ssrData, options.externalDataScript);
31620
32424
  const dataScriptBlock = dataScripts.length > 0 ? "\n" + dataScripts.join("\n") : "";
@@ -31627,11 +32431,20 @@ function renderPageStream(source, componentName, props = {}, registry = /* @__PU
31627
32431
  }
31628
32432
  const gen = raw2();
31629
32433
  async function* scoped() {
31630
- let result;
31631
- do {
31632
- result = await withSsrStore(() => gen.next());
31633
- if (!result.done) yield result.value;
31634
- } while (!result.done);
32434
+ try {
32435
+ let result;
32436
+ do {
32437
+ result = await withSsrStoreOf(streamStore, () => gen.next());
32438
+ if (!result.done) yield result.value;
32439
+ } while (!result.done);
32440
+ } finally {
32441
+ dropSsrSlot(streamToken);
32442
+ delete globalThis[`__vsk_ssr_data_${streamToken}`];
32443
+ delete globalThis[`__vsk_ssr_promises_${streamToken}`];
32444
+ delete globalThis[`__vsk_ssr_failures_${streamToken}`];
32445
+ delete globalThis.__vsk_ssr_data;
32446
+ pruneSsrDataSlots();
32447
+ }
31635
32448
  }
31636
32449
  return scoped();
31637
32450
  }
@@ -31650,6 +32463,7 @@ var init_server_render = __esm({
31650
32463
  init_md_inline();
31651
32464
  init_ssr_store();
31652
32465
  init_module_imports();
32466
+ init_vsk_collision();
31653
32467
  }
31654
32468
  });
31655
32469
 
@@ -34147,7 +34961,7 @@ function unwrapMaybeCell2(v) {
34147
34961
  }
34148
34962
  return v;
34149
34963
  }
34150
- function isCell2(v) {
34964
+ function isCell3(v) {
34151
34965
  return v !== null && typeof v === "object" && typeof v.get === "function";
34152
34966
  }
34153
34967
  function escapeHtml7(s) {
@@ -36152,7 +36966,7 @@ function Md2(props, _registry, hydrate) {
36152
36966
  if (propFg && propFg !== "none")
36153
36967
  wrapperParts.push(`--md-code-fg:${propFg}`);
36154
36968
  const wrapperStyle = wrapperParts.length > 0 ? escapeHtml7(wrapperParts.join(";")) : "";
36155
- const reactive = isCell2(contentCell);
36969
+ const reactive = isCell3(contentCell);
36156
36970
  const pathMode = isPublicMarkdownPath2(content);
36157
36971
  if (mdIsSSR2()) {
36158
36972
  const attrs = className ? ` class="${escapeHtml7(className)}"` : "";
@@ -36813,6 +37627,36 @@ var init_errors2 = __esm({
36813
37627
  tip: isBuiltin ? `"${name}" is a Vesk built-in. Use it directly \u2014 no manual import needed.` : ""
36814
37628
  });
36815
37629
  }
37630
+ /**
37631
+ * A `.vsk` namespace is resolved at the JSX-tag level: `<ns.Icon />` looks
37632
+ * the component up in the registry by its exported name, exactly like
37633
+ * `import { Icon }`, and no module object is ever built. The two forms that
37634
+ * genuinely need a real module object are reported here.
37635
+ *
37636
+ * - `nested` — `<ns.Sub.Icon />`. A `.vsk` module's exports are flat
37637
+ * component names, so there is no object to walk into.
37638
+ * - `value` — `ns.max` read as a value. Component tags resolve; plain value
37639
+ * reads do not, because nothing binds `ns` at runtime.
37640
+ */
37641
+ static vskNamespaceMember(context = {}) {
37642
+ const nested = context.form === "nested";
37643
+ return new _VeskError(nested ? "A `.vsk` namespace is flat, so `<ns.Sub.Icon />` cannot be resolved." : "A `.vsk` namespace resolves component tags only, so `ns.value` is not available.", {
37644
+ ...context,
37645
+ code: context.code || "V0410",
37646
+ suggestions: nested ? [
37647
+ "Import the component by name: import { Icon } from './icons.vsk'",
37648
+ "Import from the module that owns Sub: import * as Sub from './sub.vsk'"
37649
+ ] : [
37650
+ "Import the value by name: import { MAX } from './constants.vsk'",
37651
+ "Move the value into a .ts module and import it from there \u2014 those are real ES modules with live bindings."
37652
+ ],
37653
+ nextSteps: [
37654
+ "A `.vsk` tag resolves by component name in the global registry, not by module exports, so `import * as ns` + `<ns.Icon />` needs no module object.",
37655
+ nested ? "Re-export with a flat name (`export { Icon }`) or import the component directly." : "Re-export the value under a flat name and import it directly, or keep the value in a .ts module."
37656
+ ],
37657
+ tip: "`<ns.Icon />` works; only nested paths and value reads need a real module namespace."
37658
+ });
37659
+ }
36816
37660
  static classDecl(context = {}) {
36817
37661
  return new _VeskError("class declarations are not supported inside Vesk components.", {
36818
37662
  ...context,
@@ -39778,6 +40622,7 @@ init_server_jsgen();
39778
40622
  // ../compiler/src/precompile-runtime.ts
39779
40623
  init_ir();
39780
40624
  init_server_utils();
40625
+ init_vsk_imports();
39781
40626
  var IR_CLASSES = [
39782
40627
  ["Expression", Expression.prototype],
39783
40628
  ["IRRoot", IRRoot.prototype],
@@ -39864,7 +40709,11 @@ function precompileFileInternal(source, sourcePath2, seenImportFiles) {
39864
40709
  const bindings = sourcePath2 !== void 0 ? collectModuleBundle(ir.imports, dirname6(sourcePath2), collector) : [];
39865
40710
  const subFiles = [];
39866
40711
  if (sourcePath2 !== void 0) {
39867
- for (const importPath of collectVskImportPaths(ir.imports, sourcePath2)) {
40712
+ const vskPaths = [
40713
+ ...collectVskImportPaths(ir.imports, sourcePath2),
40714
+ ...collectVskReexportPaths(ir.reexportSources, sourcePath2)
40715
+ ];
40716
+ for (const importPath of vskPaths) {
39868
40717
  if (seenImportFiles.has(importPath)) continue;
39869
40718
  seenImportFiles.add(importPath);
39870
40719
  try {
@@ -40147,54 +40996,67 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
40147
40996
  let dataCode;
40148
40997
  const exposeErr = "process.env.NODE_ENV !== 'production'";
40149
40998
  const dataNavCleanup = [
40150
- " } finally {",
40151
- " const __dnToken = globalThis.__vsk_ssr_token;",
40152
- " delete globalThis.__vsk_ssr;",
40153
- " if (__dnToken) delete globalThis[`__vsk_ssr_data_${__dnToken}`];",
40154
- " delete globalThis.__vsk_ssr_token;",
40155
- " delete globalThis.__vsk_ssr_data;",
40156
- " }"
40999
+ " } finally {",
41000
+ " const __dnToken = globalThis.__vsk_ssr_token;",
41001
+ " delete globalThis.__vsk_ssr;",
41002
+ " if (__dnToken) delete globalThis[`__vsk_ssr_data_${__dnToken}`];",
41003
+ // NOT `delete globalThis.__vsk_ssr_token`: that global is a
41004
+ // configurable AsyncLocalStorage accessor (ssr-store.ts), so `delete`
41005
+ // removes the property definition and the process silently reverts to a
41006
+ // process-global token — the cross-request data-slot race, for good. The
41007
+ // token dies with the withSsrStore scope wrapped around this block instead.
41008
+ " delete globalThis.__vsk_ssr_data;",
41009
+ " }"
41010
+ ];
41011
+ const dataNavWrap = (body) => [
41012
+ " return withSsrStore(async () => {",
41013
+ ...body.map((l) => l ? " " + l : l),
41014
+ " });"
40157
41015
  ];
40158
41016
  if (layoutDecls.length > 0) {
40159
41017
  dataCode = [
40160
41018
  " if (request.headers.get('x-vesk-data') === '1') {",
40161
- " try {",
40162
- " let dataPage;",
40163
- " try {",
40164
- " dataPage = await renderPage('', _pageComp, { params }, __componentRegistry, { hydrate: true, cached: _pageCompiled });",
40165
- " } catch (err) {",
40166
- " if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
40167
- " const message = err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err);",
40168
- ` return new Response(JSON.stringify({ error: ${exposeErr} ? message : 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' } });`,
40169
- " }",
40170
- " let _dataHead = dataPage.head || '';",
40171
- " for (let _i = _layoutCompList.length - 1; _i >= 0; _i--) {",
40172
- " const _dl = await renderPage('', _layoutCompList[_i], { params, children: '' }, __componentRegistry, { hydrate: true, cached: _layoutCompiledList[_i] });",
40173
- " _dataHead = (_dl.head || '') + _dataHead;",
40174
- " }",
40175
- " return new Response(JSON.stringify({ path: url.pathname, params, props: dataPage.props || { params }, head: _dataHead }), {",
40176
- " headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' },",
40177
- " });",
40178
- ...dataNavCleanup,
41019
+ ...dataNavWrap([
41020
+ " try {",
41021
+ " let dataPage;",
41022
+ " try {",
41023
+ " dataPage = await renderPage('', _pageComp, { params }, __componentRegistry, { hydrate: true, cached: _pageCompiled });",
41024
+ " } catch (err) {",
41025
+ " if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
41026
+ " const message = err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err);",
41027
+ ` return new Response(JSON.stringify({ error: ${exposeErr} ? message : 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' } });`,
41028
+ " }",
41029
+ " let _dataHead = dataPage.head || '';",
41030
+ " for (let _i = _layoutCompList.length - 1; _i >= 0; _i--) {",
41031
+ " const _dl = await renderPage('', _layoutCompList[_i], { params, children: '' }, __componentRegistry, { hydrate: true, cached: _layoutCompiledList[_i] });",
41032
+ " _dataHead = (_dl.head || '') + _dataHead;",
41033
+ " }",
41034
+ " return new Response(JSON.stringify({ path: url.pathname, params, props: dataPage.props || { params }, head: _dataHead }), {",
41035
+ " headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' },",
41036
+ " });",
41037
+ ...dataNavCleanup
41038
+ ]),
40179
41039
  " }",
40180
41040
  " return __renderHtml(params, url.href);"
40181
41041
  ].join("\n");
40182
41042
  } else {
40183
41043
  dataCode = [
40184
41044
  " if (request.headers.get('x-vesk-data') === '1') {",
40185
- " try {",
40186
- " let dataPage;",
40187
- " try {",
40188
- " dataPage = await renderPage('', _comp, { params }, __componentRegistry, { hydrate: true, cached: _compiled });",
40189
- " } catch (err) {",
40190
- " if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
40191
- " const message = err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err);",
40192
- ` return new Response(JSON.stringify({ error: ${exposeErr} ? message : 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' } });`,
40193
- " }",
40194
- " return new Response(JSON.stringify({ path: url.pathname, params, props: dataPage.props || { params }, head: dataPage.head || '' }), {",
40195
- " headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' },",
40196
- " });",
40197
- ...dataNavCleanup,
41045
+ ...dataNavWrap([
41046
+ " try {",
41047
+ " let dataPage;",
41048
+ " try {",
41049
+ " dataPage = await renderPage('', _comp, { params }, __componentRegistry, { hydrate: true, cached: _compiled });",
41050
+ " } catch (err) {",
41051
+ " if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
41052
+ " const message = err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err);",
41053
+ ` return new Response(JSON.stringify({ error: ${exposeErr} ? message : 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' } });`,
41054
+ " }",
41055
+ " return new Response(JSON.stringify({ path: url.pathname, params, props: dataPage.props || { params }, head: dataPage.head || '' }), {",
41056
+ " headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' },",
41057
+ " });",
41058
+ ...dataNavCleanup
41059
+ ]),
40198
41060
  " }",
40199
41061
  " return __renderHtml(params, url.href);"
40200
41062
  ].join("\n");
@@ -40884,6 +41746,7 @@ init_esbuild_fallback();
40884
41746
  init_strip_ts();
40885
41747
  init_parser();
40886
41748
  init_client_codegen();
41749
+ init_vsk_collision();
40887
41750
  import { readFileSync as readFileSync11, existsSync as existsSync11, writeFileSync as writeFileSync4, unlinkSync as unlinkSync3, statSync as statSync3, rmSync, mkdtempSync, mkdirSync as mkdirSync3 } from "node:fs";
40888
41751
  import { resolve as resolve10, join as join7, dirname as dirname8, relative as relative2, sep } from "node:path";
40889
41752
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -41001,6 +41864,31 @@ function extractCompiledNodes(code, isTarget) {
41001
41864
  function isModuleLevel(node) {
41002
41865
  return node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration";
41003
41866
  }
41867
+ function nativeLibraryImportStubs(code) {
41868
+ let ast;
41869
+ try {
41870
+ ast = parse4(code);
41871
+ } catch {
41872
+ return "";
41873
+ }
41874
+ const body = ast.body ?? [];
41875
+ const bindings = [];
41876
+ for (const node of body) {
41877
+ if (node?.type !== "ImportDeclaration") continue;
41878
+ const src2 = node.source?.value;
41879
+ if (typeof src2 !== "string" || !src2.startsWith("@vesk/") || src2.startsWith("@vesk/runtime")) continue;
41880
+ for (const spec of node.specifiers ?? []) {
41881
+ if (typeof spec?.local?.name === "string") bindings.push([spec.local.name, src2]);
41882
+ }
41883
+ }
41884
+ if (bindings.length === 0) return "";
41885
+ const lines = bindings.map(([local, spec]) => {
41886
+ const message = `web preview: native library "${spec}" has no browser equivalent on the web (dev-only) \u2014 binding "${local}" cannot be provided in vesk dev --web. Build for Android to use it.`;
41887
+ const thrower = `throw Object.assign(new Error(${JSON.stringify(message)}), { __veskPreviewMissing: ${JSON.stringify(spec)} })`;
41888
+ return `const ${local} = new Proxy(function () {}, { get: function () { ${thrower}; }, apply: function () { ${thrower}; }, construct: function () { ${thrower}; } });`;
41889
+ });
41890
+ return lines.join("\n") + "\n\n";
41891
+ }
41004
41892
  function demoteExports(code) {
41005
41893
  let ast;
41006
41894
  try {
@@ -41334,7 +42222,8 @@ async function generateClientBundle(routeTree, appDir, componentMap, options) {
41334
42222
  }
41335
42223
  const namesBefore = cache2 ? new Set(runtimeImportNames) : null;
41336
42224
  const importedPaths = resolveVskImports(filePath, (p, n) => compileFile2(p, n, output, imports));
41337
- const { comp: rawComp, hyd: rawHyd, name: actualName } = compileClientBoth(src2, null, filePath);
42225
+ const { comp: rawComp, hyd: rawHyd, name: actualName, aliases, reexportPaths, componentNames } = compileClientBoth(src2, null, filePath);
42226
+ for (const cn of componentNames || []) componentOwners.claim(cn, filePath);
41338
42227
  const compWithImports = rawComp ? stripExports(stripVskImports(stripRuntimeImport(rawComp))) : "";
41339
42228
  const hydWithImports = rawHyd ? stripExports(stripVskImports(stripRuntimeImport(rawHyd))) : "";
41340
42229
  const compSpecs = [];
@@ -41354,6 +42243,11 @@ async function generateClientBundle(routeTree, appDir, componentMap, options) {
41354
42243
  output.push(`Object.defineProperty(__components, ${JSON.stringify(resolvedName)}, { get: () => __components[${JSON.stringify(actualName)}], configurable: true });`);
41355
42244
  output.push(`Object.defineProperty(__hydrators, ${JSON.stringify(resolvedName)}, { get: () => __hydrators[${JSON.stringify(actualName)}], configurable: true });`);
41356
42245
  }
42246
+ for (const alias of aliases || []) {
42247
+ output.push(`Object.defineProperty(__components, ${JSON.stringify(alias.exported)}, { get: () => __components[${JSON.stringify(alias.local)}], configurable: true });`);
42248
+ output.push(`Object.defineProperty(__hydrators, ${JSON.stringify(alias.exported)}, { get: () => __hydrators[${JSON.stringify(alias.local)}], configurable: true });`);
42249
+ }
42250
+ for (const reexportPath of reexportPaths || []) compileFile2(reexportPath, null, output, imports);
41357
42251
  if (cache2 && namesBefore) {
41358
42252
  const st = statSync3(filePath);
41359
42253
  cache2.files.set(filePath, {
@@ -41379,6 +42273,7 @@ async function generateClientBundle(routeTree, appDir, componentMap, options) {
41379
42273
  }
41380
42274
  const codeSplit = !!options?.codeSplit;
41381
42275
  const transformPlugins = options?.plugins || [];
42276
+ const componentOwners = new VskComponentOwners();
41382
42277
  async function applyTransformPlugins(code, filePath) {
41383
42278
  if (transformPlugins.length === 0) return code;
41384
42279
  let out = code;
@@ -41491,7 +42386,7 @@ ${entry.code}
41491
42386
  const err = e;
41492
42387
  console.error("[vesk] chunk bundle failed", entry.name, err?.errors?.map((x) => x.text).join(" | ") || err?.message || String(e));
41493
42388
  const stripped = demoteExports(removeCompiledNodes(entry.code, isAnyImport));
41494
- finalCode = chunkIIFE(stripped);
42389
+ finalCode = chunkIIFE(nativeLibraryImportStubs(entry.code) + stripped);
41495
42390
  } finally {
41496
42391
  try {
41497
42392
  rmSync(tmpBase, { recursive: true, force: true });
@@ -41499,7 +42394,7 @@ ${entry.code}
41499
42394
  }
41500
42395
  }
41501
42396
  } else {
41502
- finalCode = chunkIIFE(entry.code);
42397
+ finalCode = chunkIIFE(demoteExports(entry.code));
41503
42398
  }
41504
42399
  chunks.push({ name: entry.name, code: finalCode });
41505
42400
  }
@@ -41517,6 +42412,7 @@ ${entry.code}
41517
42412
  for (const chunk of chunks) {
41518
42413
  transformedChunks.push({ ...chunk, code: await applyTransformPlugins(chunk.code, chunk.name) });
41519
42414
  }
42415
+ componentOwners.report("client bundle");
41520
42416
  return { main: await applyTransformPlugins(main, "client.js"), chunks: transformedChunks, cachedFileHits, compiledFiles, mainFromCache, editedSources, editedNames };
41521
42417
  } else {
41522
42418
  let compileFileMono2 = function(filePath, resolvedName) {
@@ -41524,6 +42420,7 @@ ${entry.code}
41524
42420
  seen.add(filePath);
41525
42421
  const src2 = readFileSync11(filePath, "utf-8");
41526
42422
  resolveVskImports(filePath, (p, n) => compileFileMono2(p, n || ""));
42423
+ for (const cn of vskComponentNames(src2, filePath)) componentOwners.claim(cn, filePath);
41527
42424
  const monoAlloc = nameAllocFor(filePath);
41528
42425
  const compCode = compileClient(src2, null, { forceClient: true, sourcePath: filePath, nameAllocator: monoAlloc });
41529
42426
  const hydCode = compileClient(src2, null, { hydrate: true, forceClient: true, includeTopLevel: false, sourcePath: filePath, nameAllocator: monoAlloc });
@@ -41573,6 +42470,7 @@ ${entry.code}
41573
42470
  aliasLines,
41574
42471
  hydratorAliasLines
41575
42472
  }, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache);
42473
+ componentOwners.report("client bundle");
41576
42474
  return { main: await applyTransformPlugins(main, "client.js"), chunks: [] };
41577
42475
  }
41578
42476
  }
@@ -41708,7 +42606,7 @@ function appendHmrGlobals(code) {
41708
42606
  return code + "globalThis.__vesk_hmr_eval = (code, n) => {\n if (!n || n !== globalThis.__vesk_hmr_nonce) throw new Error('vesk hmr: invalid nonce');\n return eval(code);\n};\n";
41709
42607
  }
41710
42608
  async function buildMainBundle(routeTree, runtimeDir, codeSplit, mono, hmr, importRuntime, runtimeImportNames, routeDataCache) {
41711
- const baseRuntimeImports = ["createFileRouter", "get", "set", "effect", "track", "destroy_block", "getActiveComponent", "setActiveComponent", "NavLink", "Link", "reactiveProps", "matchRoute", "ensureChunk"];
42609
+ const baseRuntimeImports = ["createFileRouter", "get", "set", "effect", "track", "destroy_block", "getActiveComponent", "setActiveComponent", "NavLink", "Link", "reactiveProps", "matchRoute", "ensureChunk", "toDomNode", "rerenderNode"];
41712
42610
  const allRuntimeImports = runtimeImportNames && runtimeImportNames.size > 0 ? [.../* @__PURE__ */ new Set([...baseRuntimeImports, ...runtimeImportNames])] : baseRuntimeImports;
41713
42611
  const runtimeGlobals = [
41714
42612
  "reconcile",
@@ -42991,33 +43889,104 @@ init_server_render();
42991
43889
  // ../compiler/dist/ssr-store.js
42992
43890
  init_index_server();
42993
43891
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
43892
+ var TOKEN_KEY2 = "__vsk_ssr_token";
42994
43893
  var storage2 = new AsyncLocalStorage2();
43894
+ var liveSlots2 = /* @__PURE__ */ new Map();
43895
+ function newSsrToken2() {
43896
+ return Math.random().toString(36).slice(2);
43897
+ }
43898
+ function createSsrStore3() {
43899
+ return { token: newSsrToken2(), data: {} };
43900
+ }
43901
+ function isThenable2(value) {
43902
+ return typeof value?.then === "function";
43903
+ }
42995
43904
  function withSsrStore2(fn) {
42996
43905
  const existing = storage2.getStore();
42997
43906
  if (existing)
42998
43907
  return fn();
42999
- return storage2.run({}, fn);
43908
+ const store = createSsrStore3();
43909
+ keepSsrSlot2(store.token);
43910
+ let result;
43911
+ try {
43912
+ result = storage2.run(store, fn);
43913
+ } catch (err) {
43914
+ dropSsrSlot2(store.token);
43915
+ throw err;
43916
+ }
43917
+ if (isThenable2(result)) {
43918
+ return result.then((value) => {
43919
+ dropSsrSlot2(store.token);
43920
+ return value;
43921
+ }, (err) => {
43922
+ dropSsrSlot2(store.token);
43923
+ throw err;
43924
+ });
43925
+ }
43926
+ dropSsrSlot2(store.token);
43927
+ return result;
43928
+ }
43929
+ function withSsrStoreOf2(store, fn) {
43930
+ return storage2.run(store, fn);
43931
+ }
43932
+ function resetSsrToken() {
43933
+ const store = storage2.getStore();
43934
+ const token = newSsrToken2();
43935
+ if (store) {
43936
+ if (store.token)
43937
+ liveSlots2.delete(store.token);
43938
+ store.token = token;
43939
+ }
43940
+ liveSlots2.set(token, 1);
43941
+ return token;
43942
+ }
43943
+ function keepSsrSlot2(token) {
43944
+ if (!token)
43945
+ return;
43946
+ liveSlots2.set(token, (liveSlots2.get(token) ?? 0) + 1);
43947
+ }
43948
+ function dropSsrSlot2(token) {
43949
+ if (!token)
43950
+ return;
43951
+ const count = liveSlots2.get(token);
43952
+ if (count === void 0)
43953
+ return;
43954
+ if (count <= 1)
43955
+ liveSlots2.delete(token);
43956
+ else
43957
+ liveSlots2.set(token, count - 1);
43000
43958
  }
43001
43959
  var ssrSink3 = {
43002
43960
  set: (key, value) => {
43003
43961
  const store = storage2.getStore();
43004
43962
  if (store)
43005
- store[key] = value;
43963
+ store.data[key] = value;
43006
43964
  },
43007
43965
  get: (key) => {
43008
43966
  const store = storage2.getStore();
43009
- return store ? store[key] : void 0;
43967
+ return store ? store.data[key] : void 0;
43010
43968
  },
43011
- snapshot: () => ({ ...storage2.getStore() ?? {} }),
43969
+ snapshot: () => ({ ...storage2.getStore()?.data ?? {} }),
43012
43970
  clear: () => {
43013
43971
  const store = storage2.getStore();
43014
43972
  if (store) {
43015
- for (const key of Object.keys(store))
43016
- delete store[key];
43973
+ for (const key of Object.keys(store.data))
43974
+ delete store.data[key];
43017
43975
  }
43018
43976
  }
43019
43977
  };
43020
43978
  setSsrSink(ssrSink3);
43979
+ Object.defineProperty(globalThis, TOKEN_KEY2, {
43980
+ configurable: true,
43981
+ get() {
43982
+ return storage2.getStore()?.token;
43983
+ },
43984
+ set(value) {
43985
+ const store = storage2.getStore();
43986
+ if (store)
43987
+ store.token = value;
43988
+ }
43989
+ });
43021
43990
 
43022
43991
  // ../compiler/dist/client-codegen.js
43023
43992
  init_ir();
@@ -43028,6 +43997,7 @@ init_server_utils();
43028
43997
  init_module_imports();
43029
43998
  init_scan();
43030
43999
  init_tokens();
44000
+ init_vsk_imports();
43031
44001
  init_md_inline();
43032
44002
  init_strip_ts();
43033
44003
  import { walk as walk6 } from "zimmerframe";
@@ -43051,6 +44021,47 @@ function simpleGetName2(expr) {
43051
44021
  }
43052
44022
  return inner;
43053
44023
  }
44024
+ var BINDING_REF_CALLS2 = ["bindValue", "bindChecked", "bindGroup"];
44025
+ function untrackBindingArg2(expr) {
44026
+ let head = -1;
44027
+ for (const name of BINDING_REF_CALLS2) {
44028
+ if (expr.startsWith(`${name}(`)) {
44029
+ head = name.length;
44030
+ break;
44031
+ }
44032
+ }
44033
+ if (head < 0)
44034
+ return expr;
44035
+ const rest = expr.slice(head + 1);
44036
+ if (rest[0] !== "g" || rest[1] !== "e" || rest[2] !== "t" || rest[3] !== "(")
44037
+ return expr;
44038
+ let i = 4;
44039
+ let word = "";
44040
+ for (; i < rest.length; i++) {
44041
+ const c = rest.charCodeAt(i);
44042
+ const ok = c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95 || c === 36;
44043
+ if (!ok)
44044
+ break;
44045
+ word += rest[i];
44046
+ }
44047
+ if (word.length === 0 || rest[i] !== ")")
44048
+ return expr;
44049
+ const after = i + 1;
44050
+ if (rest[after] !== "," && rest[after] !== ")")
44051
+ return expr;
44052
+ return expr.slice(0, head + 1) + word + rest.slice(after);
44053
+ }
44054
+ function trackedRefTarget2(expr, tracked2) {
44055
+ const cell = simpleGetName2(expr);
44056
+ if (cell !== null)
44057
+ return cell;
44058
+ if (/^[A-Za-z_$][\w$]*$/.test(expr)) {
44059
+ const info = tracked2.get(expr);
44060
+ if (info && info.kind === "cell" && info.cellName === expr)
44061
+ return expr;
44062
+ }
44063
+ return null;
44064
+ }
43054
44065
  function semicolonizeStatement2(code) {
43055
44066
  const trimmed = code.trimEnd();
43056
44067
  if (!trimmed || trimmed.endsWith(";") || trimmed.endsWith("}"))
@@ -43157,6 +44168,21 @@ function transformTracked2(irNode, tracked2) {
43157
44168
  }
43158
44169
  return context.next();
43159
44170
  },
44171
+ Property(node, context) {
44172
+ if (node.shorthand && node.value && node.value.type === "Identifier" && !node.computed) {
44173
+ const info = context.state.get(node.value.name);
44174
+ if (info && info.kind === "virtual") {
44175
+ return {
44176
+ ...node,
44177
+ shorthand: false,
44178
+ value: callExpr2({ type: "Identifier", name: "get" }, [
44179
+ { type: "Identifier", name: info.cellName }
44180
+ ])
44181
+ };
44182
+ }
44183
+ }
44184
+ return context.next();
44185
+ },
43160
44186
  Identifier(node, context) {
43161
44187
  const parent = context.path.at(-1);
43162
44188
  if (parent) {
@@ -43168,6 +44194,8 @@ function transformTracked2(irNode, tracked2) {
43168
44194
  return context.next();
43169
44195
  if (parent.type === "Property" && parent.value === node && parent.key && parent.key.type === "Identifier" && parent.key.name === "into")
43170
44196
  return context.next();
44197
+ if (parent.type === "Property" && parent.key === node && !parent.computed && !parent.shorthand)
44198
+ return context.next();
43171
44199
  if (parent.type === "MemberExpression" && !parent.computed && parent.object === node && parent.property && parent.property.type === "Identifier" && parent.property.name === "set")
43172
44200
  return context.next();
43173
44201
  }
@@ -43195,6 +44223,31 @@ function collectTrackedNames2(body) {
43195
44223
  }
43196
44224
  return names;
43197
44225
  }
44226
+ function collectTrackedDeps2(value, tracked2) {
44227
+ const ast = value?.ast;
44228
+ if (!ast || typeof ast !== "object" || tracked2.size === 0)
44229
+ return [];
44230
+ const found = [];
44231
+ const seen = /* @__PURE__ */ new Set();
44232
+ walk6(ast, tracked2, {
44233
+ Identifier(node, context) {
44234
+ const parent = context.path.at(-1);
44235
+ if (parent) {
44236
+ if (parent.type === "MemberExpression" && !parent.computed && parent.property === node)
44237
+ return context.next();
44238
+ if (parent.type === "Property" && parent.key === node)
44239
+ return context.next();
44240
+ }
44241
+ const info = context.state.get(node.name);
44242
+ if (info && !seen.has(node.name)) {
44243
+ seen.add(node.name);
44244
+ found.push(node.name);
44245
+ }
44246
+ return context.next();
44247
+ }
44248
+ });
44249
+ return found;
44250
+ }
43198
44251
  function transformTrackedInit2(init, tracked2) {
43199
44252
  if (!init)
43200
44253
  return init;
@@ -43531,8 +44584,9 @@ function emitStatic2(ctx2, node, tracked2, effectsVar, skipK = 0, regionBudget)
43531
44584
  const target = attr.target || "";
43532
44585
  const isEvent2 = target.startsWith("on") && target.length > 2;
43533
44586
  if (target === "ref") {
43534
- const expr = transformTracked2(attr.expression, tracked2);
43535
- ctx2.push(`(${expr})(${ssrEl});`);
44587
+ const expr = untrackBindingArg2(transformTracked2(attr.expression, tracked2));
44588
+ const cell = trackedRefTarget2(expr, tracked2);
44589
+ ctx2.push(cell !== null ? `set(${cell}, ${ssrEl});` : `(${expr})(${ssrEl});`);
43536
44590
  } else if (isEvent2) {
43537
44591
  const eventName = target.slice(2).toLowerCase();
43538
44592
  const handler = transformTracked2(attr.expression, tracked2);
@@ -43590,8 +44644,9 @@ function emitStatic2(ctx2, node, tracked2, effectsVar, skipK = 0, regionBudget)
43590
44644
  const target = attr.target || "";
43591
44645
  const isEvent2 = target.startsWith("on") && target.length > 2;
43592
44646
  if (target === "ref") {
43593
- const expr = transformTracked2(attr.expression, tracked2);
43594
- ctx2.push(`(${expr})(${el});`);
44647
+ const expr = untrackBindingArg2(transformTracked2(attr.expression, tracked2));
44648
+ const cell = trackedRefTarget2(expr, tracked2);
44649
+ ctx2.push(cell !== null ? `set(${cell}, ${el});` : `(${expr})(${el});`);
43595
44650
  } else if (isEvent2) {
43596
44651
  const eventName = target.slice(2).toLowerCase();
43597
44652
  const handler = transformTracked2(attr.expression, tracked2);
@@ -43810,20 +44865,35 @@ function emitComponentCall2(ctx2, node, tracked2, effectsVar, parentVar, compPre
43810
44865
  const calleeExpr = node.calleeExpr ? `(${node.calleeExpr})` : null;
43811
44866
  const slotChildren = node.children.filter((c) => c instanceof PropSlot);
43812
44867
  const regChildren = node.children.filter((c) => !(c instanceof PropSlot));
43813
- const callArgs = () => `{ ${propsEntries.join(", ")} }`;
44868
+ const plainTarget = !!(calleeExpr || ctx2.importedNames.has(node.componentName)) && !ctx2.selfClaimNames.has(node.componentName);
44869
+ const trackedDeps = [];
44870
+ if (plainTarget) {
44871
+ for (const p of node.props) {
44872
+ if (typeof p.value === "string")
44873
+ continue;
44874
+ for (const d of collectTrackedDeps2(p.value, tracked2))
44875
+ if (!trackedDeps.includes(d))
44876
+ trackedDeps.push(d);
44877
+ }
44878
+ for (const sp of node.spreadProps) {
44879
+ for (const d of collectTrackedDeps2(sp, tracked2))
44880
+ if (!trackedDeps.includes(d))
44881
+ trackedDeps.push(d);
44882
+ }
44883
+ }
44884
+ const callArgs = () => plainTarget ? `reactiveProps({ ${propsEntries.join(", ")} })` : `{ ${propsEntries.join(", ")} }`;
43814
44885
  if (ctx2.hydrate) {
43815
44886
  const access = calleeExpr ?? (ctx2.importedNames.has(node.componentName) ? node.componentName : `__components[${JSON.stringify(node.componentName)}]`);
43816
44887
  if (!calleeExpr && !ctx2.importedNames.has(node.componentName)) {
43817
44888
  ctx2.push(`if (${access} == null) throw new Error(${JSON.stringify(`Component "${node.componentName}" was not found while rendering. Declare it with the \`component\` keyword, import it, or register it in the component registry.`)});`);
43818
44889
  }
43819
- const plainTarget = !!(calleeExpr || ctx2.importedNames.has(node.componentName)) && !ctx2.selfClaimNames.has(node.componentName);
43820
44890
  const walkerArg = ctx2.walker;
43821
44891
  const promptExpr = ctx2.markerless && (regionBudget || skipK > 0) ? markerlessSkipExpr2(regionBudget, skipK) : null;
43822
44892
  const maybeReplace = (v2) => {
43823
44893
  if (!plainTarget)
43824
44894
  return;
43825
44895
  const claim = promptExpr ? `${walkerArg}.claimOnly(undefined, ${promptExpr})` : `${walkerArg}.claimOnly()`;
43826
- ctx2.push(`if (${v2} && ${v2}.parentNode == null && ${v2}.nodeType !== 11) { const __sr = ${claim}; if (__sr && __sr.parentNode) __sr.parentNode.replaceChild(${v2}, __sr); }`);
44896
+ ctx2.push(`if (${v2} && ${v2}.parentNode == null) { if (${v2}.nodeType === 11) { const __cnt = ${v2}.childNodes.length; let __sr = null; for (let __i = 0; __i < __cnt; __i++) { const __c = ${claim}; if (__c && __c.parentNode) { if (__sr) { __c.remove(); } else { __sr = __c; } } } if (__sr) { const __p = __sr.parentNode; while (${v2}.firstChild) __p.insertBefore(${v2}.firstChild, __sr); __p.removeChild(__sr); } } else { const __sr = ${claim}; if (__sr && __sr.parentNode) __sr.parentNode.replaceChild(${v2}, __sr); } }`);
43827
44897
  if (regionBudget && ctx2.markerless)
43828
44898
  ctx2.push(`${regionBudget} = 0;`);
43829
44899
  };
@@ -43862,11 +44932,17 @@ function emitComponentCall2(ctx2, node, tracked2, effectsVar, parentVar, compPre
43862
44932
  }
43863
44933
  ctx2.push(`let ${v} = undefined;`);
43864
44934
  ctx2.push(`if (__hydrate) __hydrate.childFrame = (__hydrate.childFrame || 0) + 1;`);
43865
- ctx2.push(`try { ${v} = ${awaitKw}${access}(${callArgs()}, __registry, ${walkerArg}); } finally { if (__hydrate) __hydrate.childFrame--; }`);
44935
+ ctx2.push(`try { ${v} = toDomNode(${awaitKw}${access}(${callArgs()}, __registry, ${walkerArg})); } finally { if (__hydrate) __hydrate.childFrame--; }`);
44936
+ const rootsVar = trackedDeps.length > 0 ? ctx2.n() : null;
44937
+ if (rootsVar)
44938
+ ctx2.push(`const ${rootsVar} = ${v} && ${v}.nodeType === 11 ? Array.from(${v}.childNodes) : [${v}];`);
43866
44939
  if (ctx2.markerless && promptExpr && !plainTarget && regionBudget)
43867
44940
  ctx2.push(`${regionBudget} = 0;`);
43868
44941
  maybeReplace(v);
43869
44942
  maybeRetire();
44943
+ if (trackedDeps.length > 0) {
44944
+ ctx2.push(`rerenderNode(${rootsVar}, [${trackedDeps.join(", ")}], () => ${awaitKw}${access}(${callArgs()}, __registry, ${walkerArg}));`);
44945
+ }
43870
44946
  return v;
43871
44947
  } else {
43872
44948
  for (const slot of slotChildren) {
@@ -43890,12 +44966,18 @@ function emitComponentCall2(ctx2, node, tracked2, effectsVar, parentVar, compPre
43890
44966
  propsEntries.push(`children: ${frag}`);
43891
44967
  }
43892
44968
  if (calleeExpr) {
43893
- ctx2.push(`const ${v} = ${calleeExpr}(${callArgs()});`);
44969
+ ctx2.push(`const ${v} = toDomNode(${calleeExpr}(${callArgs()}));`);
43894
44970
  } else if (ctx2.importedNames.has(node.componentName)) {
43895
- ctx2.push(`const ${v} = ${awaitKw}${node.componentName}(${callArgs()});`);
44971
+ ctx2.push(`const ${v} = toDomNode(${awaitKw}${node.componentName}(${callArgs()}));`);
43896
44972
  } else {
43897
44973
  ctx2.push(`if (${compPrefix}[${JSON.stringify(node.componentName)}] == null) throw new Error(${JSON.stringify(`Component "${node.componentName}" was not found while rendering. Declare it with the \`component\` keyword, import it, or register it in the component registry.`)});`);
43898
- ctx2.push(`const ${v} = ${awaitKw}${compPrefix}[${JSON.stringify(node.componentName)}](${callArgs()});`);
44974
+ ctx2.push(`const ${v} = toDomNode(${awaitKw}${compPrefix}[${JSON.stringify(node.componentName)}](${callArgs()}));`);
44975
+ }
44976
+ if (trackedDeps.length > 0) {
44977
+ const calleeRef = calleeExpr ?? (ctx2.importedNames.has(node.componentName) ? node.componentName : `${compPrefix}[${JSON.stringify(node.componentName)}]`);
44978
+ const rootsVar2 = ctx2.n();
44979
+ ctx2.push(`const ${rootsVar2} = ${v} && ${v}.nodeType === 11 ? Array.from(${v}.childNodes) : [${v}];`);
44980
+ ctx2.push(`rerenderNode(${rootsVar2}, [${trackedDeps.join(", ")}], () => ${awaitKw}${calleeRef}(${callArgs()}));`);
43899
44981
  }
43900
44982
  }
43901
44983
  return v;
@@ -45135,7 +46217,7 @@ function emitClientFromIR2(ir, options) {
45135
46217
  }
45136
46218
  }
45137
46219
  const exportCode = exportLines.join("\n");
45138
- const runtimeNames = ["track", "get", "set", "destroy_block", "getActiveComponent", "setActiveComponent", "reactiveProps", "applyStyle"];
46220
+ const runtimeNames = ["track", "get", "set", "destroy_block", "getActiveComponent", "setActiveComponent", "reactiveProps", "applyStyle", "toDomNode", "rerenderNode"];
45139
46221
  if (ir.components.some((c) => !isStaticIR2(c.body)))
45140
46222
  runtimeNames.push("effect");
45141
46223
  for (const name of usedRuntimeBindings2(ir))
@@ -45203,12 +46285,20 @@ function compileClientBoth2(source, _componentName, sourcePath2, opts) {
45203
46285
  }
45204
46286
  const alloc = nameAllocFor2(sourcePath2);
45205
46287
  const comp = emitClientFromIR2(ir, { forceClient: true, nameAllocator: alloc });
46288
+ const aliases = vskRegistryAliases(ir.imports, ir.exportAliases);
46289
+ const reexportPaths = sourcePath2 ? collectVskReexportPaths(ir.reexportSources, sourcePath2) : [];
45206
46290
  if (opts?.skipHyd)
45207
- return { comp, hyd: "", name };
46291
+ return { comp, hyd: "", name, aliases, reexportPaths, componentNames: ir.components.map((c) => c.name) };
45208
46292
  return {
45209
46293
  comp,
45210
46294
  hyd: emitClientFromIR2(irHyd, { forceClient: true, hydrate: true, includeTopLevel: false, nameAllocator: alloc, markerless: opts?.markerless !== false }),
45211
- name
46295
+ name,
46296
+ aliases,
46297
+ reexportPaths,
46298
+ // Every component NAME this file registers, not just the resolved one —
46299
+ // the bundle needs the full list to spot same-name declarations across
46300
+ // files (see findVskComponentCollisions).
46301
+ componentNames: ir.components.map((c) => c.name)
45212
46302
  };
45213
46303
  }
45214
46304
 
@@ -46407,6 +47497,7 @@ async function build3(options) {
46407
47497
  init_strip_ts();
46408
47498
  init_parser();
46409
47499
  init_client_codegen();
47500
+ init_vsk_collision();
46410
47501
  init_vsk_imports();
46411
47502
  init_md_inline();
46412
47503
  init_module_imports();
@@ -46529,6 +47620,35 @@ function extractCompiledNodes2(code, isTarget) {
46529
47620
  function isModuleLevel2(node) {
46530
47621
  return node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration";
46531
47622
  }
47623
+ function nativeLibraryImportStubs2(code) {
47624
+ let ast;
47625
+ try {
47626
+ ast = parse4(code);
47627
+ } catch {
47628
+ return "";
47629
+ }
47630
+ const body = ast.body ?? [];
47631
+ const bindings = [];
47632
+ for (const node of body) {
47633
+ if (node?.type !== "ImportDeclaration")
47634
+ continue;
47635
+ const src2 = node.source?.value;
47636
+ if (typeof src2 !== "string" || !src2.startsWith("@vesk/") || src2.startsWith("@vesk/runtime"))
47637
+ continue;
47638
+ for (const spec of node.specifiers ?? []) {
47639
+ if (typeof spec?.local?.name === "string")
47640
+ bindings.push([spec.local.name, src2]);
47641
+ }
47642
+ }
47643
+ if (bindings.length === 0)
47644
+ return "";
47645
+ const lines = bindings.map(([local, spec]) => {
47646
+ const message = `web preview: native library "${spec}" has no browser equivalent on the web (dev-only) \u2014 binding "${local}" cannot be provided in vesk dev --web. Build for Android to use it.`;
47647
+ const thrower = `throw Object.assign(new Error(${JSON.stringify(message)}), { __veskPreviewMissing: ${JSON.stringify(spec)} })`;
47648
+ return `const ${local} = new Proxy(function () {}, { get: function () { ${thrower}; }, apply: function () { ${thrower}; }, construct: function () { ${thrower}; } });`;
47649
+ });
47650
+ return lines.join("\n") + "\n\n";
47651
+ }
46532
47652
  function demoteExports2(code) {
46533
47653
  let ast;
46534
47654
  try {
@@ -46895,7 +48015,9 @@ async function generateClientBundle2(routeTree, appDir, componentMap, options) {
46895
48015
  }
46896
48016
  const namesBefore = cache2 ? new Set(runtimeImportNames) : null;
46897
48017
  const importedPaths = resolveVskImports(filePath, (p, n) => compileFile2(p, n, output, imports));
46898
- const { comp: rawComp, hyd: rawHyd, name: actualName } = compileClientBoth(src2, null, filePath);
48018
+ const { comp: rawComp, hyd: rawHyd, name: actualName, aliases, reexportPaths, componentNames } = compileClientBoth(src2, null, filePath);
48019
+ for (const cn of componentNames || [])
48020
+ componentOwners.claim(cn, filePath);
46899
48021
  const compWithImports = rawComp ? stripExports(stripVskImports(stripRuntimeImport(rawComp))) : "";
46900
48022
  const hydWithImports = rawHyd ? stripExports(stripVskImports(stripRuntimeImport(rawHyd))) : "";
46901
48023
  const compSpecs = [];
@@ -46918,6 +48040,12 @@ async function generateClientBundle2(routeTree, appDir, componentMap, options) {
46918
48040
  output.push(`Object.defineProperty(__components, ${JSON.stringify(resolvedName)}, { get: () => __components[${JSON.stringify(actualName)}], configurable: true });`);
46919
48041
  output.push(`Object.defineProperty(__hydrators, ${JSON.stringify(resolvedName)}, { get: () => __hydrators[${JSON.stringify(actualName)}], configurable: true });`);
46920
48042
  }
48043
+ for (const alias of aliases || []) {
48044
+ output.push(`Object.defineProperty(__components, ${JSON.stringify(alias.exported)}, { get: () => __components[${JSON.stringify(alias.local)}], configurable: true });`);
48045
+ output.push(`Object.defineProperty(__hydrators, ${JSON.stringify(alias.exported)}, { get: () => __hydrators[${JSON.stringify(alias.local)}], configurable: true });`);
48046
+ }
48047
+ for (const reexportPath of reexportPaths || [])
48048
+ compileFile2(reexportPath, null, output, imports);
46921
48049
  if (cache2 && namesBefore) {
46922
48050
  const st = statSync14(filePath);
46923
48051
  cache2.files.set(filePath, {
@@ -46943,6 +48071,7 @@ async function generateClientBundle2(routeTree, appDir, componentMap, options) {
46943
48071
  }
46944
48072
  const codeSplit = !!options?.codeSplit;
46945
48073
  const transformPlugins = options?.plugins || [];
48074
+ const componentOwners = new VskComponentOwners();
46946
48075
  async function applyTransformPlugins(code, filePath) {
46947
48076
  if (transformPlugins.length === 0)
46948
48077
  return code;
@@ -47061,7 +48190,7 @@ ${entry.code}
47061
48190
  const err = e;
47062
48191
  console.error("[vesk] chunk bundle failed", entry.name, err?.errors?.map((x) => x.text).join(" | ") || err?.message || String(e));
47063
48192
  const stripped = demoteExports2(removeCompiledNodes2(entry.code, isAnyImport2));
47064
- finalCode = chunkIIFE(stripped);
48193
+ finalCode = chunkIIFE(nativeLibraryImportStubs2(entry.code) + stripped);
47065
48194
  } finally {
47066
48195
  try {
47067
48196
  rmSync4(tmpBase, { recursive: true, force: true });
@@ -47069,7 +48198,7 @@ ${entry.code}
47069
48198
  }
47070
48199
  }
47071
48200
  } else {
47072
- finalCode = chunkIIFE(entry.code);
48201
+ finalCode = chunkIIFE(demoteExports2(entry.code));
47073
48202
  }
47074
48203
  chunks.push({ name: entry.name, code: finalCode });
47075
48204
  }
@@ -47088,6 +48217,7 @@ ${entry.code}
47088
48217
  for (const chunk of chunks) {
47089
48218
  transformedChunks.push({ ...chunk, code: await applyTransformPlugins(chunk.code, chunk.name) });
47090
48219
  }
48220
+ componentOwners.report("client bundle");
47091
48221
  return { main: await applyTransformPlugins(main, "client.js"), chunks: transformedChunks, cachedFileHits, compiledFiles, mainFromCache, editedSources, editedNames };
47092
48222
  } else {
47093
48223
  let compileFileMono2 = function(filePath, resolvedName) {
@@ -47096,6 +48226,8 @@ ${entry.code}
47096
48226
  seen.add(filePath);
47097
48227
  const src2 = readFileSync24(filePath, "utf-8");
47098
48228
  resolveVskImports(filePath, (p, n) => compileFileMono2(p, n || ""));
48229
+ for (const cn of vskComponentNames(src2, filePath))
48230
+ componentOwners.claim(cn, filePath);
47099
48231
  const monoAlloc = nameAllocFor(filePath);
47100
48232
  const compCode = compileClient(src2, null, { forceClient: true, sourcePath: filePath, nameAllocator: monoAlloc });
47101
48233
  const hydCode = compileClient(src2, null, { hydrate: true, forceClient: true, includeTopLevel: false, sourcePath: filePath, nameAllocator: monoAlloc });
@@ -47155,6 +48287,7 @@ ${entry.code}
47155
48287
  aliasLines,
47156
48288
  hydratorAliasLines
47157
48289
  }, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache);
48290
+ componentOwners.report("client bundle");
47158
48291
  return { main: await applyTransformPlugins(main, "client.js"), chunks: [] };
47159
48292
  }
47160
48293
  }
@@ -47292,7 +48425,7 @@ function appendHmrGlobals2(code) {
47292
48425
  return code + "globalThis.__vesk_hmr_eval = (code, n) => {\n if (!n || n !== globalThis.__vesk_hmr_nonce) throw new Error('vesk hmr: invalid nonce');\n return eval(code);\n};\n";
47293
48426
  }
47294
48427
  async function buildMainBundle2(routeTree, runtimeDir, codeSplit, mono, hmr, importRuntime, runtimeImportNames, routeDataCache) {
47295
- const baseRuntimeImports = ["createFileRouter", "get", "set", "effect", "track", "destroy_block", "getActiveComponent", "setActiveComponent", "NavLink", "Link", "reactiveProps", "matchRoute", "ensureChunk"];
48428
+ const baseRuntimeImports = ["createFileRouter", "get", "set", "effect", "track", "destroy_block", "getActiveComponent", "setActiveComponent", "NavLink", "Link", "reactiveProps", "matchRoute", "ensureChunk", "toDomNode", "rerenderNode"];
47296
48429
  const allRuntimeImports = runtimeImportNames && runtimeImportNames.size > 0 ? [.../* @__PURE__ */ new Set([...baseRuntimeImports, ...runtimeImportNames])] : baseRuntimeImports;
47297
48430
  const runtimeGlobals = [
47298
48431
  "reconcile",
@@ -53292,11 +54425,11 @@ ${prettifyHtml(body)}
53292
54425
  </html>`;
53293
54426
  return applyHtmlPlugins(fullHtml, ctx2.plugins, { sourcePath: ctx2.url.pathname });
53294
54427
  }
53295
- const leaf = chain.find((n) => n.page);
53296
- if (!leaf) return null;
53297
- const src2 = readFileSync37(resolve37(ctx2.appDirPath, leaf.sourceDir, "page.vsk"), "utf-8");
53298
- const compName = resolveComponentName(src2) || leaf.page;
53299
- const html = await renderFullPage(src2, compName, { params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: actionCssUrls(ctx2.appDirPath), security: ctx2.security, sourcePath: resolve37(ctx2.appDirPath, leaf.sourceDir, "page.vsk"), plugins: ctx2.plugins });
54428
+ const leaf2 = chain.find((n) => n.page);
54429
+ if (!leaf2) return null;
54430
+ const src2 = readFileSync37(resolve37(ctx2.appDirPath, leaf2.sourceDir, "page.vsk"), "utf-8");
54431
+ const compName = resolveComponentName(src2) || leaf2.page;
54432
+ const html = await renderFullPage(src2, compName, { params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: actionCssUrls(ctx2.appDirPath), security: ctx2.security, sourcePath: resolve37(ctx2.appDirPath, leaf2.sourceDir, "page.vsk"), plugins: ctx2.plugins });
53300
54433
  return applyHtmlPlugins(html.replace("</body>", ' <script type="module" src="/_vesk/hmr.js"></script>\n</body>'), ctx2.plugins, { sourcePath: ctx2.url.pathname });
53301
54434
  }
53302
54435
  async function handleActionRequest(req, res, ctx2) {
@@ -53689,8 +54822,41 @@ var ROUTE_STRUCTURAL_VSK = /* @__PURE__ */ new Set([
53689
54822
  "offline.vsk",
53690
54823
  "network.vsk"
53691
54824
  ]);
53692
- var HMR_SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".vesk", "tarballs", ".git"]);
53693
- var HMR_SKIP_MARKERS = ["node_modules/", ".vesk/", "tmp-vesk-chunk-"];
54825
+ var HMR_SKIP_DIRS = /* @__PURE__ */ new Set([
54826
+ "node_modules",
54827
+ ".vesk",
54828
+ "tarballs",
54829
+ ".git",
54830
+ "dist",
54831
+ "build",
54832
+ "coverage",
54833
+ "out",
54834
+ ".next",
54835
+ ".nuxt",
54836
+ ".output",
54837
+ ".svelte-kit",
54838
+ ".turbo",
54839
+ ".cache",
54840
+ ".vercel",
54841
+ ".netlify"
54842
+ ]);
54843
+ var HMR_SKIP_MARKERS = [
54844
+ "node_modules/",
54845
+ ".vesk/",
54846
+ "tmp-vesk-chunk-",
54847
+ "/dist/",
54848
+ "/build/",
54849
+ "/coverage/",
54850
+ "/out/",
54851
+ "/.next/",
54852
+ "/.nuxt/",
54853
+ "/.output/",
54854
+ "/.svelte-kit/",
54855
+ "/.turbo/",
54856
+ "/.cache/",
54857
+ "/.vercel/",
54858
+ "/.netlify/"
54859
+ ];
53694
54860
  var HMR_SCRIPT_EXTS = [".mts", ".ts", ".tsx", ".mjs", ".js", ".cjs"];
53695
54861
  var HMR_CONFIG_NAMES = /* @__PURE__ */ new Set([
53696
54862
  "vesk.config.ts",
@@ -54237,6 +55403,7 @@ async function startDevServer(port, projectDir, config, host) {
54237
55403
  const treeChanged = needsRescan && prevTree !== stripAnnots(routeTree);
54238
55404
  const isOutsideApp = !fullPath.startsWith(appDirPath + "/") && fullPath !== appDirPath;
54239
55405
  const fileDeleted = eventType === "rename" && !fileExists;
55406
+ if (isOutsideApp) ssrCompileCache.clear();
54240
55407
  const cssPromise = rebuildTailwindCss();
54241
55408
  let bundleError = null;
54242
55409
  let hotEditedSource = null;
@@ -54381,6 +55548,7 @@ Object.defineProperty(__components, ${JSON.stringify(cname)}, { get: () => __com
54381
55548
  const t0 = Date.now();
54382
55549
  try {
54383
55550
  bcast({ type: "compiling" });
55551
+ ssrCompileCache.clear();
54384
55552
  await fullRebuild();
54385
55553
  LOG.info(`${kind === "config" ? "config" : "script"} changed, full rebuild + reload (${filename}) \u2014 ${Date.now() - t0}ms`);
54386
55554
  } catch (e) {
@@ -54688,11 +55856,11 @@ Object.defineProperty(__components, ${JSON.stringify(cname)}, { get: () => __com
54688
55856
  const forData = req.headers["x-vesk-data"] === "1";
54689
55857
  async function renderSSR() {
54690
55858
  const ssg2 = globalThis;
54691
- const freshToken = Math.random().toString(36).slice(2);
54692
- ssg2.__vsk_ssr_token = freshToken;
54693
55859
  ssg2.__vsk_ssr_data = {};
55860
+ let freshToken;
54694
55861
  try {
54695
55862
  return await withSsrStore2(async () => {
55863
+ freshToken = resetSsrToken();
54696
55864
  const chain = cleanChain;
54697
55865
  let body = "";
54698
55866
  let head = "";
@@ -54753,11 +55921,11 @@ ${prettifyHtml(body)}
54753
55921
  html = injectDevScripts(html);
54754
55922
  html = await applyHtmlPlugins(html, getActiveDevPlugins(), { sourcePath: url.pathname });
54755
55923
  } else {
54756
- const leaf = chain.find((n) => n.page);
54757
- if (leaf) {
54758
- const src2 = readFileSync38(resolve38(appDirPath, leaf.sourceDir, "page.vsk"), "utf-8");
54759
- const compName = extractCompName2(src2) || leaf.page;
54760
- html = await renderFullPage(src2, compName, { params: matched.params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: activeCssUrls(), security, externalDataScript: storeDataScript, sourcePath: resolve38(appDirPath, leaf.sourceDir, "page.vsk"), cached: cachedSsrCompile(ssrCompileCache, src2, resolve38(appDirPath, leaf.sourceDir, "page.vsk")), plugins: getActiveDevPlugins() });
55924
+ const leaf2 = chain.find((n) => n.page);
55925
+ if (leaf2) {
55926
+ const src2 = readFileSync38(resolve38(appDirPath, leaf2.sourceDir, "page.vsk"), "utf-8");
55927
+ const compName = extractCompName2(src2) || leaf2.page;
55928
+ html = await renderFullPage(src2, compName, { params: matched.params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: activeCssUrls(), security, externalDataScript: storeDataScript, sourcePath: resolve38(appDirPath, leaf2.sourceDir, "page.vsk"), cached: cachedSsrCompile(ssrCompileCache, src2, resolve38(appDirPath, leaf2.sourceDir, "page.vsk")), plugins: getActiveDevPlugins() });
54761
55929
  html = html.replace("</body>", ' <script type="module" src="/_vesk/hmr.js"></script>\n</body>');
54762
55930
  html = await applyHtmlPlugins(html, getActiveDevPlugins(), { sourcePath: url.pathname });
54763
55931
  } else {
@@ -54767,27 +55935,26 @@ ${prettifyHtml(body)}
54767
55935
  return { html, props: props || { params: matched.params }, head };
54768
55936
  });
54769
55937
  } finally {
54770
- delete ssg2[`__vsk_ssr_data_${freshToken}`];
54771
- delete ssg2[`__vsk_ssr_promises_${freshToken}`];
54772
- delete ssg2[`__vsk_ssr_failures_${freshToken}`];
54773
- if (ssg2.__vsk_ssr_token === freshToken) delete ssg2.__vsk_ssr_token;
55938
+ const token = freshToken;
55939
+ dropSsrSlot2(token);
55940
+ delete ssg2[`__vsk_ssr_data_${token}`];
55941
+ delete ssg2[`__vsk_ssr_promises_${token}`];
55942
+ delete ssg2[`__vsk_ssr_failures_${token}`];
54774
55943
  delete ssg2.__vsk_ssr_data;
54775
55944
  }
54776
55945
  }
54777
55946
  function renderSSRStream() {
54778
55947
  const sst = globalThis;
54779
- const streamToken = Math.random().toString(36).slice(2);
54780
- sst.__vsk_ssr_token = streamToken;
54781
55948
  sst.__vsk_ssr_data = {};
54782
55949
  async function* raw2() {
54783
55950
  const chain = cleanChain;
54784
55951
  const hasLayout = chain.some((n) => n.layout && existsSync42(resolve38(appDirPath, n.sourceDir, "layout.vsk")));
54785
55952
  if (!hasLayout) {
54786
- const leaf = chain.find((n) => n.page);
54787
- if (leaf) {
54788
- const src2 = readFileSync38(resolve38(appDirPath, leaf.sourceDir, "page.vsk"), "utf-8");
54789
- const compName = extractCompName2(src2) || leaf.page;
54790
- yield* renderPageStream(src2, compName, { params: matched.params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: activeCssUrls(), security, externalDataScript: storeDataScript, sourcePath: resolve38(appDirPath, leaf.sourceDir, "page.vsk"), cached: cachedSsrCompile(ssrCompileCache, src2, resolve38(appDirPath, leaf.sourceDir, "page.vsk")), plugins: getActiveDevPlugins() });
55953
+ const leaf2 = chain.find((n) => n.page);
55954
+ if (leaf2) {
55955
+ const src2 = readFileSync38(resolve38(appDirPath, leaf2.sourceDir, "page.vsk"), "utf-8");
55956
+ const compName = extractCompName2(src2) || leaf2.page;
55957
+ yield* renderPageStream(src2, compName, { params: matched.params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: activeCssUrls(), security, externalDataScript: storeDataScript, sourcePath: resolve38(appDirPath, leaf2.sourceDir, "page.vsk"), cached: cachedSsrCompile(ssrCompileCache, src2, resolve38(appDirPath, leaf2.sourceDir, "page.vsk")), plugins: getActiveDevPlugins() });
54791
55958
  } else {
54792
55959
  throw new Error("No page or layout matched");
54793
55960
  }
@@ -54841,18 +56008,22 @@ ${prettifyHtml(body)}
54841
56008
  yield ' <script type="module" src="/_vesk/client.js"></script>\n</body>\n</html>';
54842
56009
  }
54843
56010
  const gen = raw2();
56011
+ const streamStore = createSsrStore3();
54844
56012
  async function* scoped() {
54845
56013
  try {
54846
56014
  let result;
54847
56015
  do {
54848
- result = await withSsrStore2(() => gen.next());
56016
+ result = await withSsrStoreOf2(streamStore, () => gen.next());
54849
56017
  if (!result.done) yield result.value;
54850
56018
  } while (!result.done);
54851
56019
  } finally {
54852
- delete sst[`__vsk_ssr_data_${streamToken}`];
54853
- delete sst[`__vsk_ssr_promises_${streamToken}`];
54854
- delete sst[`__vsk_ssr_failures_${streamToken}`];
54855
- if (sst.__vsk_ssr_token === streamToken) delete sst.__vsk_ssr_token;
56020
+ const token = streamStore.token;
56021
+ dropSsrSlot2(token);
56022
+ if (token) {
56023
+ delete sst[`__vsk_ssr_data_${token}`];
56024
+ delete sst[`__vsk_ssr_promises_${token}`];
56025
+ delete sst[`__vsk_ssr_failures_${token}`];
56026
+ }
54856
56027
  delete sst.__vsk_ssr_data;
54857
56028
  }
54858
56029
  }
@@ -55071,7 +56242,6 @@ ${prettifyHtml(body)}
55071
56242
  LOG.info(`${projectDir}`);
55072
56243
  LOG.info(`${pageCount} page${pageCount === 1 ? "" : "s"}: ${routes.join(", ") || "(none)"}`);
55073
56244
  if (apiCount > 0) LOG.info(`${apiCount} api route${apiCount === 1 ? "" : "s"} (app/api)`);
55074
- LOG.info("hmr enabled \u2014 edit app/ to hot reload");
55075
56245
  });
55076
56246
  updateSourceMapping();
55077
56247
  const hmrClients = /* @__PURE__ */ new Set();
@@ -55242,11 +56412,15 @@ __export(index_server_exports2, {
55242
56412
  get_server_context: () => get_server_context,
55243
56413
  headers: () => headers,
55244
56414
  isFormAction: () => isFormAction,
56415
+ isLeaf: () => isLeaf,
55245
56416
  isLoadingActive: () => isLoadingActive,
56417
+ isPrimitive: () => isPrimitive,
56418
+ isVeskComponent: () => isVeskComponent,
55246
56419
  is_destroyed: () => is_destroyed,
55247
56420
  isr: () => isr,
55248
56421
  isrConfigToRevalidate: () => isrConfigToRevalidate,
55249
56422
  issuesToFieldMap: () => issuesToFieldMap,
56423
+ leaf: () => leaf,
55250
56424
  locals: () => locals,
55251
56425
  maxLength: () => maxLength,
55252
56426
  minLength: () => minLength,
@@ -55260,12 +56434,14 @@ __export(index_server_exports2, {
55260
56434
  permanentRedirect: () => permanentRedirect,
55261
56435
  pop_component: () => pop_component,
55262
56436
  pre_effect: () => pre_effect,
56437
+ primitive: () => primitive,
55263
56438
  push_component: () => push_component,
55264
56439
  readSignedCookie: () => readSignedCookie2,
55265
56440
  redirect: () => redirect,
55266
56441
  removeHook: () => removeHook,
55267
56442
  render: () => render,
55268
56443
  required: () => required,
56444
+ rerenderNode: () => rerenderNode,
55269
56445
  resolveSsrResources: () => resolveSsrResources,
55270
56446
  resume_block: () => resume_block,
55271
56447
  revalidateComponent: () => revalidateComponent,
@@ -55289,6 +56465,7 @@ __export(index_server_exports2, {
55289
56465
  set_server_context: () => set_server_context,
55290
56466
  signCookie: () => signCookie2,
55291
56467
  tick: () => tick,
56468
+ toDomNode: () => toDomNode,
55292
56469
  track: () => track,
55293
56470
  unlink_block: () => unlink_block,
55294
56471
  unsignCookie: () => unsignCookie2,
@@ -55324,6 +56501,7 @@ init_experiment();
55324
56501
  init_form();
55325
56502
  init_md();
55326
56503
  init_headless();
56504
+ init_primitive();
55327
56505
  init_loading_indicator();
55328
56506
  init_action();
55329
56507