@vesk/vesk-cli 0.2.60 → 0.2.62

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 +579 -33
  2. package/package.json +5 -5
package/dist/cli.js CHANGED
@@ -495,7 +495,7 @@ ${this.code}`;
495
495
  });
496
496
 
497
497
  // ../compiler/src/ir.ts
498
- var Expression, IRRoot, ComponentIR, StaticNode, TextNode, DynamicBinding, OpaqueDynamicRegion, MapRegion, ComponentRef, ComponentCall, SlotNode, PropSlot, PropSlotRender, WhileLoop, SwitchCase, SwitchBlock, TryCatch, TrackDecl, RuntimeStatement, ForLoop, ServerBlock, ClientBlock, HeadBlock;
498
+ var Expression, IRRoot, ComponentIR, StaticNode, TextNode, DynamicBinding, OpaqueDynamicRegion, MapRegion, ComponentRef, ComponentCall, SlotNode, PropSlot, PropSlotRender, WhileLoop, SwitchCase, SwitchBlock, TryCatch, TrackDecl, RuntimeStatement, BreakSignal, ForLoop, ServerBlock, ClientBlock, HeadBlock;
499
499
  var init_ir = __esm({
500
500
  "../compiler/src/ir.ts"() {
501
501
  "use strict";
@@ -742,6 +742,10 @@ var init_ir = __esm({
742
742
  this.source = source;
743
743
  }
744
744
  };
745
+ BreakSignal = class {
746
+ constructor() {
747
+ }
748
+ };
745
749
  ForLoop = class {
746
750
  init;
747
751
  condition;
@@ -4839,7 +4843,7 @@ async function renderNotFound(router, match, container) {
4839
4843
  }
4840
4844
  if (container.replaceChildren) container.replaceChildren();
4841
4845
  else container.innerHTML = "";
4842
- container.innerHTML = "<h1>404 \u2014 Not Found</h1>";
4846
+ container.innerHTML = defaultErrorHtml(404, "Not Found");
4843
4847
  router._currentMatch = match;
4844
4848
  }
4845
4849
  function defaultOfflineHtml(url) {
@@ -4848,6 +4852,9 @@ function defaultOfflineHtml(url) {
4848
4852
  function escapeOfflineUrl(url) {
4849
4853
  return String(url).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
4850
4854
  }
4855
+ function defaultErrorHtml(status, message) {
4856
+ return '<div data-vesk-default-error="' + status + '" style="display:flex;align-items:center;justify-content:center;min-height:50vh;padding:32px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:inherit"><div style="display:flex;align-items:center"><span style="font-size:24px;font-weight:500;line-height:49px;padding-right:23px;margin-right:20px;border-right:1px solid currentColor;opacity:.85">' + status + '</span><span style="font-size:14px;line-height:49px;opacity:.7">' + message + "</span></div></div>";
4857
+ }
4851
4858
  async function renderOfflinePage(router, match, container) {
4852
4859
  const url = match.pathname || (typeof window !== "undefined" ? window.location.pathname : "");
4853
4860
  const chain = match.matchChain;
@@ -5136,7 +5143,7 @@ function renderMatch(router, match, container, navToken) {
5136
5143
  } else {
5137
5144
  container.innerHTML = "";
5138
5145
  }
5139
- container.innerHTML = "<h1>404 \u2014 Not Found</h1>";
5146
+ container.innerHTML = defaultErrorHtml(404, "Not Found");
5140
5147
  return;
5141
5148
  }
5142
5149
  if (pageNode._pageName && (!pageNode.page || typeof pageNode.page === "string")) {
@@ -5324,7 +5331,7 @@ async function renderErrorPage(router, match, container, error) {
5324
5331
  if (!errorFn) {
5325
5332
  if (container.replaceChildren) container.replaceChildren();
5326
5333
  else container.innerHTML = "";
5327
- container.innerHTML = "<h1>500 \u2014 Internal Server Error</h1>";
5334
+ container.innerHTML = defaultErrorHtml(500, "Internal Server Error");
5328
5335
  return;
5329
5336
  }
5330
5337
  const layoutNodes = chain.filter((n) => n.layout);
@@ -5388,7 +5395,7 @@ async function hydrateInitial(router, match, container, strategy) {
5388
5395
  });
5389
5396
  return;
5390
5397
  }
5391
- container.innerHTML = "<h1>404 \u2014 Not Found</h1>";
5398
+ container.innerHTML = defaultErrorHtml(404, "Not Found");
5392
5399
  return;
5393
5400
  }
5394
5401
  const ssrErrorMarker = (() => {
@@ -6045,7 +6052,7 @@ function createFileRouter(routeTree, options = {}) {
6045
6052
  }
6046
6053
  })();
6047
6054
  } else {
6048
- container.innerHTML = "<h1>404 \u2014 Not Found</h1>";
6055
+ container.innerHTML = defaultErrorHtml(404, "Not Found");
6049
6056
  }
6050
6057
  return;
6051
6058
  }
@@ -21555,6 +21562,7 @@ function processJSXCallbackBody(source, body) {
21555
21562
  for (const c of body.children) nodes.push(...processJSXChildren(source, [c]));
21556
21563
  return nodes;
21557
21564
  }
21565
+ if (body.type === "BlockStatement") return processStatementModeBody(source, body.body);
21558
21566
  if (body.type === "ParenthesizedExpression") return exprToIR(source, body.expression);
21559
21567
  return exprToIR(source, body);
21560
21568
  }
@@ -21713,6 +21721,29 @@ function getReturnStatement(node) {
21713
21721
  }
21714
21722
  return null;
21715
21723
  }
21724
+ function containsLoopControl(node) {
21725
+ if (!node) return false;
21726
+ if (node.type === "ContinueStatement" || node.type === "BreakStatement") return true;
21727
+ if (node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") return false;
21728
+ if (node.type === "ForStatement" || node.type === "ForInStatement" || node.type === "ForOfStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement") return false;
21729
+ if (node.type === "BlockStatement") return node.body.some(containsLoopControl);
21730
+ if (node.type === "IfStatement") return containsLoopControl(node.consequent) || containsLoopControl(node.alternate);
21731
+ if (node.type === "SwitchStatement") return node.cases.some((c) => (c.consequent || []).some(containsLoopControl));
21732
+ if (node.type === "TryStatement") {
21733
+ return containsLoopControl(node.block) || containsLoopControl(node.handler) || containsLoopControl(node.finalizer);
21734
+ }
21735
+ if (node.type === "CatchClause") return containsLoopControl(node.body);
21736
+ if (node.type === "LabeledStatement") return containsLoopControl(node.body);
21737
+ return false;
21738
+ }
21739
+ function getLoopControlGuard(consequent, kind) {
21740
+ const stmts = consequent.type === "BlockStatement" ? consequent.body : [consequent];
21741
+ if (stmts.length === 0) return null;
21742
+ const want = kind === "continue" ? "ContinueStatement" : "BreakStatement";
21743
+ const last = stmts[stmts.length - 1];
21744
+ if (!last || last.type !== want) return null;
21745
+ return { pre: stmts.slice(0, -1), node: last };
21746
+ }
21716
21747
  function isStatementMode(bodyStmts) {
21717
21748
  if (bodyStmts.some((s) => s.type === "JSXElement" || s.type === "JSXExpressionContainer" || s.type === "JSXFragment")) return true;
21718
21749
  for (const stmt of bodyStmts) {
@@ -21751,6 +21782,9 @@ function processIfStatement(source, stmt) {
21751
21782
  return [new OpaqueDynamicRegion(condExpr, consequent, alternate)];
21752
21783
  }
21753
21784
  function processForStatement(source, stmt, alternate = []) {
21785
+ if (stmt.body && !hasJSXInSubtree(stmt.body) && containsLoopControl(stmt.body)) {
21786
+ return [new RuntimeStatement(getSource(source, stmt), stmt, source)];
21787
+ }
21754
21788
  if (stmt.type === "ForOfStatement") {
21755
21789
  const left = stmt.left;
21756
21790
  let itemVar = "item";
@@ -21784,6 +21818,9 @@ function processForStatement(source, stmt, alternate = []) {
21784
21818
  return [];
21785
21819
  }
21786
21820
  function processWhileStatement(source, stmt) {
21821
+ if (stmt.body && !hasJSXInSubtree(stmt.body) && containsLoopControl(stmt.body)) {
21822
+ return [new RuntimeStatement(getSource(source, stmt), stmt, source)];
21823
+ }
21787
21824
  const condition = toExpression(source, stmt.test);
21788
21825
  const bodyTemplate = processBlockBody(source, stmt.body);
21789
21826
  const isDoWhile = stmt.type === "DoWhileStatement";
@@ -21849,6 +21886,18 @@ function processStatementModeBody(source, bodyStmts, filename) {
21849
21886
  nodes.push(new OpaqueDynamicRegion(toExpression(source, stmt.test), consequent, alternate));
21850
21887
  break;
21851
21888
  }
21889
+ if (!stmt.alternate) {
21890
+ const guardContinue = getLoopControlGuard(stmt.consequent, "continue");
21891
+ const guardBreak = guardContinue ? null : getLoopControlGuard(stmt.consequent, "break");
21892
+ const guard = guardContinue || guardBreak;
21893
+ if (guard) {
21894
+ const consequent = guard.pre.length ? processStatementModeBody(source, guard.pre, filename) : [];
21895
+ if (guardBreak) consequent.push(new BreakSignal());
21896
+ const alternate = processStatementModeBody(source, bodyStmts.slice(i + 1), filename);
21897
+ nodes.push(new OpaqueDynamicRegion(toExpression(source, stmt.test), consequent, alternate));
21898
+ break;
21899
+ }
21900
+ }
21852
21901
  nodes.push(...processIfStatement(source, stmt));
21853
21902
  } else if (stmt.type === "ForOfStatement") {
21854
21903
  let alternate = [];
@@ -21886,6 +21935,11 @@ function processStatementModeBody(source, bodyStmts, filename) {
21886
21935
  } else if (stmt.type === "ClassDeclaration") {
21887
21936
  const { line, column } = offsetToLineCol2(source, stmt.start ?? 0);
21888
21937
  throw VeskError.classDecl({ file: filename || "", line, column, code: codeFrame(source, line, column) });
21938
+ } else if (stmt.type === "ContinueStatement") {
21939
+ break;
21940
+ } else if (stmt.type === "BreakStatement") {
21941
+ nodes.push(new BreakSignal());
21942
+ break;
21889
21943
  } else {
21890
21944
  const raw2 = getSource(source, stmt);
21891
21945
  if (raw2) nodes.push(new RuntimeStatement(raw2, stmt, source));
@@ -22017,6 +22071,7 @@ function warnStaleConstBindings(comp, file) {
22017
22071
  if (d.id?.type !== "Identifier" || !d.init) continue;
22018
22072
  if (reactive.has(d.id.name)) continue;
22019
22073
  if (d.init.type === "ArrowFunctionExpression" || d.init.type === "FunctionExpression") continue;
22074
+ if (isReactiveFactoryCall(d.init)) continue;
22020
22075
  if (d.init.type === "Identifier" && reactive.has(d.init.name)) continue;
22021
22076
  const seen = /* @__PURE__ */ new Set();
22022
22077
  collectIdentifiers(d.init, seen);
@@ -22057,6 +22112,16 @@ function warnStaleConstBindings(comp, file) {
22057
22112
  }
22058
22113
  });
22059
22114
  }
22115
+ function isReactiveFactoryCall(node) {
22116
+ if (!node || node.type !== "CallExpression") return false;
22117
+ const callee = node.callee;
22118
+ if (!callee) return false;
22119
+ if (callee.type === "Identifier") return callee.name === "derived";
22120
+ if (callee.type === "MemberExpression" && !callee.computed) {
22121
+ return callee.property?.type === "Identifier" && callee.property.name === "derived";
22122
+ }
22123
+ return false;
22124
+ }
22060
22125
  function collectIdentifiers(node, into) {
22061
22126
  if (!node || typeof node !== "object") return;
22062
22127
  if (Array.isArray(node)) {
@@ -22064,6 +22129,15 @@ function collectIdentifiers(node, into) {
22064
22129
  return;
22065
22130
  }
22066
22131
  if (typeof node.type !== "string") return;
22132
+ if (node.type === "MemberExpression" && !node.computed) {
22133
+ collectIdentifiers(node.object, into);
22134
+ if (node.property?.type === "MemberExpression") collectIdentifiers(node.property, into);
22135
+ return;
22136
+ }
22137
+ if ((node.type === "Property" || node.type === "PropertyDefinition" || node.type === "MethodDefinition") && !node.computed) {
22138
+ collectIdentifiers(node.value, into);
22139
+ return;
22140
+ }
22067
22141
  if (node.type === "Identifier" && typeof node.name === "string") into.add(node.name);
22068
22142
  for (const key of Object.keys(node)) {
22069
22143
  if (key === "loc" || key === "range" || key === "start" || key === "end") continue;
@@ -30395,14 +30469,36 @@ function transformTracked(irNode, tracked2) {
30395
30469
  }
30396
30470
  function collectTrackedNames(body) {
30397
30471
  const names = /* @__PURE__ */ new Map();
30472
+ collectTrackedNamesInto(body, names);
30473
+ return names;
30474
+ }
30475
+ function collectTrackedNamesInto(body, names) {
30398
30476
  for (const node of body) {
30399
30477
  if (node instanceof TrackDecl) {
30400
30478
  const cellName = node.rawName || node.name;
30401
30479
  names.set(node.name, { cellName, kind: "virtual" });
30402
30480
  if (node.rawName) names.set(node.rawName, { cellName, kind: "cell" });
30481
+ } else if (node instanceof StaticNode || node instanceof ServerBlock || node instanceof ClientBlock || node instanceof HeadBlock) {
30482
+ collectTrackedNamesInto(node.children, names);
30483
+ } else if (node instanceof ComponentCall) {
30484
+ collectTrackedNamesInto(node.children, names);
30485
+ } else if (node instanceof PropSlot) {
30486
+ collectTrackedNamesInto(node.body, names);
30487
+ } else if (node instanceof MapRegion) {
30488
+ collectTrackedNamesInto(node.bodyTemplate, names);
30489
+ collectTrackedNamesInto(node.alternateNodes, names);
30490
+ } else if (node instanceof OpaqueDynamicRegion) {
30491
+ collectTrackedNamesInto(node.consequentNodes, names);
30492
+ collectTrackedNamesInto(node.alternateNodes, names);
30493
+ } else if (node instanceof WhileLoop || node instanceof ForLoop) {
30494
+ collectTrackedNamesInto(node.bodyTemplate, names);
30495
+ } else if (node instanceof TryCatch) {
30496
+ collectTrackedNamesInto(node.bodyTemplate, names);
30497
+ collectTrackedNamesInto(node.catchBody, names);
30498
+ } else if (node instanceof SwitchBlock) {
30499
+ for (const c of node.cases) collectTrackedNamesInto(c.body, names);
30403
30500
  }
30404
30501
  }
30405
- return names;
30406
30502
  }
30407
30503
  function collectTrackedDeps(value, tracked2) {
30408
30504
  const ast = value?.ast;
@@ -30437,6 +30533,53 @@ function transformTrackedInit(init, tracked2) {
30437
30533
  if (!expr) return init;
30438
30534
  return transformTracked({ raw: init, ast: expr }, tracked2);
30439
30535
  }
30536
+ function runtimeDeclaredNames(node) {
30537
+ if (!(node instanceof RuntimeStatement)) return [];
30538
+ const stmt = node.ast;
30539
+ if (!stmt || stmt.type !== "VariableDeclaration" || !stmt.declarations) return [];
30540
+ const out = [];
30541
+ for (const d of stmt.declarations) {
30542
+ if (d.id && d.id.type === "Identifier" && typeof d.id.name === "string") out.push(d.id.name);
30543
+ }
30544
+ return out;
30545
+ }
30546
+ function initReadsAnyOf(init, names) {
30547
+ if (!init || names.size === 0) return false;
30548
+ let expr = null;
30549
+ try {
30550
+ const prog = parse4(`(${init})`);
30551
+ expr = prog.body?.[0]?.type === "ExpressionStatement" ? prog.body[0].expression ?? null : null;
30552
+ } catch {
30553
+ return false;
30554
+ }
30555
+ if (!expr) return false;
30556
+ let found = false;
30557
+ const walk9 = (n) => {
30558
+ if (found || !n || typeof n !== "object") return;
30559
+ if (Array.isArray(n)) {
30560
+ for (const c of n) walk9(c);
30561
+ return;
30562
+ }
30563
+ const t = n.type;
30564
+ if (typeof t !== "string") return;
30565
+ if (t === "Identifier") {
30566
+ if (names.has(n.name)) found = true;
30567
+ return;
30568
+ }
30569
+ if (t === "MemberExpression") {
30570
+ const m = n;
30571
+ walk9(m.object);
30572
+ if (m.computed) walk9(m.property);
30573
+ return;
30574
+ }
30575
+ for (const key of Object.keys(n)) {
30576
+ if (key === "loc" || key === "range" || key === "start" || key === "end") continue;
30577
+ walk9(n[key]);
30578
+ }
30579
+ };
30580
+ walk9(expr);
30581
+ return found;
30582
+ }
30440
30583
  function indent2(code, level = 1) {
30441
30584
  const pad = " ".repeat(level);
30442
30585
  return code.split("\n").map((l) => l ? pad + l : "").join("\n");
@@ -30488,6 +30631,10 @@ function emitNode(ctx2, node, tracked2, effectsVar, parentVar, compPrefix = "__c
30488
30631
  ctx2.push(semicolonizeStatement(transformTracked(node, tracked2)));
30489
30632
  return null;
30490
30633
  }
30634
+ if (node instanceof BreakSignal) {
30635
+ if (ctx2.breakFlag) ctx2.push(`${ctx2.breakFlag} = true;`);
30636
+ return null;
30637
+ }
30491
30638
  if (node instanceof SlotNode) {
30492
30639
  if (!parentVar) {
30493
30640
  if (ctx2.hydrate) {
@@ -31294,12 +31441,18 @@ function emitWhileLoop(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget)
31294
31441
  ctx2.push(`const ${endAnchor} = document.createComment('while-end');`);
31295
31442
  emitHydrateFenceAnchoring(ctx2, anchor, endAnchor, parent === "$root", budget || void 0);
31296
31443
  const renderLoop = ctx2.n();
31444
+ const hasBreak = bodyHasBreak(node.bodyTemplate);
31445
+ const breakVar = hasBreak ? ctx2.n() : null;
31297
31446
  ctx2.push(`const ${renderLoop} = ${ctx2.isAsyncScope ? "async () => {" : "() => {"}`);
31298
31447
  if (!hyd) ctx2.push(indent2(`const __p = ${anchor}.parentNode;`));
31299
31448
  if (!hyd) ctx2.push(indent2(`const __b = document.createDocumentFragment();`));
31300
31449
  if (hyd) ctx2.push(indent2(`const __cl = [];`));
31450
+ if (breakVar) ctx2.push(indent2(`let ${breakVar} = false;`));
31451
+ const savedBreakFlag = ctx2.breakFlag;
31452
+ ctx2.breakFlag = breakVar;
31301
31453
  if (node.isDoWhile) {
31302
31454
  ctx2.push(indent2(`do {`));
31455
+ if (breakVar) ctx2.push(indent2(indent2(`if (${breakVar}) break;`)));
31303
31456
  for (const n of node.bodyTemplate) {
31304
31457
  const v = emitNode(ctx2, n, tracked2, effectsVar, hyd ? parentVar : "__b", "__components", 0, budget || void 0);
31305
31458
  if (v) {
@@ -31310,6 +31463,7 @@ function emitWhileLoop(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget)
31310
31463
  ctx2.push(indent2(`} while (${condExpr});`));
31311
31464
  } else {
31312
31465
  ctx2.push(indent2(`while (${condExpr}) {`));
31466
+ if (breakVar) ctx2.push(indent2(indent2(`if (${breakVar}) break;`)));
31313
31467
  for (const n of node.bodyTemplate) {
31314
31468
  const v = emitNode(ctx2, n, tracked2, effectsVar, hyd ? parentVar : "__b", "__components", 0, budget || void 0);
31315
31469
  if (v) {
@@ -31319,6 +31473,7 @@ function emitWhileLoop(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget)
31319
31473
  }
31320
31474
  ctx2.push(indent2(`}`));
31321
31475
  }
31476
+ ctx2.breakFlag = savedBreakFlag;
31322
31477
  if (!hyd) ctx2.push(indent2(`__p.insertBefore(__b, ${endAnchor});`));
31323
31478
  if (hyd) ctx2.push(indent2(`__place(${anchor}, ${endAnchor}, __cl, ${parent});`));
31324
31479
  ctx2.push(`};`);
@@ -31358,13 +31513,19 @@ function emitForLoop(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget) {
31358
31513
  ctx2.push(`const ${endAnchor} = document.createComment('for-end');`);
31359
31514
  emitHydrateFenceAnchoring(ctx2, anchor, endAnchor, parent === "$root", budget || void 0);
31360
31515
  const renderLoop = ctx2.n();
31516
+ const forHasBreak = bodyHasBreak(node.bodyTemplate);
31517
+ const forBreakVar = forHasBreak ? ctx2.n() : null;
31361
31518
  ctx2.push(`const ${renderLoop} = ${ctx2.isAsyncScope ? "async () => {" : "() => {"}`);
31362
31519
  if (!hyd) ctx2.push(indent2(`const __p = ${anchor}.parentNode;`));
31363
31520
  if (!hyd) ctx2.push(indent2(`const __b = document.createDocumentFragment();`));
31364
31521
  if (hyd) ctx2.push(indent2(`const __cl = [];`));
31522
+ if (forBreakVar) ctx2.push(indent2(`let ${forBreakVar} = false;`));
31523
+ const savedForBreakFlag = ctx2.breakFlag;
31524
+ ctx2.breakFlag = forBreakVar;
31365
31525
  if (node.kind === "for-in") {
31366
31526
  const srcExpr = transformTracked(node.condition, tracked2);
31367
31527
  ctx2.push(indent2(`for (${node.init} of (Array.isArray(${srcExpr}) ? ${srcExpr} : (${srcExpr} == null ? [] : Object.keys(${srcExpr})))) {`));
31528
+ if (forBreakVar) ctx2.push(indent2(indent2(`if (${forBreakVar}) break;`)));
31368
31529
  for (const n of node.bodyTemplate) {
31369
31530
  const v = emitNode(ctx2, n, tracked2, effectsVar, hyd ? parentVar : "__b", "__components", 0, budget || void 0);
31370
31531
  if (v) {
@@ -31381,6 +31542,7 @@ function emitForLoop(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget) {
31381
31542
  if (updatePart.endsWith(";")) updatePart = updatePart.slice(0, -1).trim();
31382
31543
  const head = initPart ? `${initPart}; ${condExpr}` : `; ${condExpr}`;
31383
31544
  ctx2.push(indent2(`for (${head}; ${updatePart}) {`));
31545
+ if (forBreakVar) ctx2.push(indent2(indent2(`if (${forBreakVar}) break;`)));
31384
31546
  for (const n of node.bodyTemplate) {
31385
31547
  const v = emitNode(ctx2, n, tracked2, effectsVar, hyd ? parentVar : "__b", "__components", 0, budget || void 0);
31386
31548
  if (v) {
@@ -31390,6 +31552,7 @@ function emitForLoop(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget) {
31390
31552
  }
31391
31553
  ctx2.push(indent2(`}`));
31392
31554
  }
31555
+ ctx2.breakFlag = savedForBreakFlag;
31393
31556
  if (!hyd) ctx2.push(indent2(`__p.insertBefore(__b, ${endAnchor});`));
31394
31557
  if (hyd) ctx2.push(indent2(`__place(${anchor}, ${endAnchor}, __cl, ${parent});`));
31395
31558
  ctx2.push(`};`);
@@ -31550,6 +31713,27 @@ function emitSwitchBlock(ctx2, node, tracked2, parentVar, skipK = 0, regionBudge
31550
31713
  }`);
31551
31714
  return null;
31552
31715
  }
31716
+ function bodyHasBreak(nodes) {
31717
+ for (const n of nodes) {
31718
+ if (n instanceof BreakSignal) return true;
31719
+ if (n instanceof OpaqueDynamicRegion) {
31720
+ if (bodyHasBreak([...n.consequentNodes, ...n.alternateNodes])) return true;
31721
+ } else if (n instanceof SwitchBlock) {
31722
+ for (const c of n.cases) if (bodyHasBreak(c.body)) return true;
31723
+ } else if (n instanceof TryCatch) {
31724
+ if (bodyHasBreak([...n.bodyTemplate, ...n.catchBody])) return true;
31725
+ } else if (n instanceof StaticNode) {
31726
+ if (bodyHasBreak(n.children)) return true;
31727
+ } else if (n instanceof ComponentCall) {
31728
+ if (bodyHasBreak(n.children)) return true;
31729
+ } else if (n instanceof ServerBlock || n instanceof ClientBlock || n instanceof HeadBlock) {
31730
+ if (bodyHasBreak(n.children)) return true;
31731
+ } else if (n instanceof PropSlot) {
31732
+ if (bodyHasBreak(n.body)) return true;
31733
+ }
31734
+ }
31735
+ return false;
31736
+ }
31553
31737
  function emitMap(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionBudget) {
31554
31738
  const arrExpr = transformTracked(node.expression, tracked2);
31555
31739
  const itemVar = node.itemVariable;
@@ -31582,9 +31766,13 @@ function emitMap(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionBu
31582
31766
  ctx2.push(`let ${effectsVar} = [];`);
31583
31767
  ctx2.push(`const ${endAnchor} = document.createComment('map-end');`);
31584
31768
  const renderItem = ctx2.n();
31769
+ const hasBreak = bodyHasBreak(node.bodyTemplate);
31770
+ const breakVar = hasBreak ? ctx2.n() : null;
31771
+ if (breakVar) ctx2.push(`let ${breakVar} = false;`);
31585
31772
  const indexParam = node.indexVariable ? ", __i" : "";
31586
31773
  ctx2.push(`const ${renderItem} = ${ctx2.isAsyncScope ? "async " : ""}(${itemVar}${indexParam}, __e, __r${hyd ? ", __cl" : ""}${hydKeyed ? ", __root" : ""}) => {`);
31587
31774
  ctx2.push(indent2(`__r = __r || ${endAnchor};`));
31775
+ if (breakVar) ctx2.push(indent2(`if (${breakVar}) return;`));
31588
31776
  if (node.indexVariable) ctx2.push(indent2(`const ${node.indexVariable} = __i;`));
31589
31777
  if (hyd) {
31590
31778
  ctx2.push(indent2(`const __p = ${anchor}.parentNode;`));
@@ -31593,6 +31781,8 @@ function emitMap(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionBu
31593
31781
  ctx2.push(indent2(`const __it = document.createDocumentFragment();`));
31594
31782
  }
31595
31783
  if (hydKeyed) ctx2.rootClaim = true;
31784
+ const savedMapBreak = ctx2.breakFlag;
31785
+ ctx2.breakFlag = breakVar;
31596
31786
  for (const n of node.bodyTemplate) {
31597
31787
  const v = emitNode(ctx2, n, tracked2, "__e", hyd ? void 0 : "__it", "__components", 0, budget || void 0);
31598
31788
  if (v) {
@@ -31605,6 +31795,7 @@ function emitMap(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionBu
31605
31795
  }
31606
31796
  }
31607
31797
  }
31798
+ ctx2.breakFlag = savedMapBreak;
31608
31799
  if (hydKeyed) ctx2.rootClaim = false;
31609
31800
  if (!hyd) ctx2.push(indent2(`if (__it.childNodes.length > 0) __p.insertBefore(__it, __r);`));
31610
31801
  ctx2.push(`};`);
@@ -31640,11 +31831,12 @@ function emitMap(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionBu
31640
31831
  const keyFnSrc = `(${itemVar}${node.indexVariable ? `, ${node.indexVariable}` : ""}) => ${keyExpr}`;
31641
31832
  const reconciler = ctx2.n();
31642
31833
  const initList = ctx2.n();
31834
+ const breakReset = breakVar ? `${breakVar} = false; ` : "";
31643
31835
  ctx2.push(`let ${reconciler} = () => {};`);
31644
31836
  if (hydKeyed) {
31645
- ctx2.push(`const ${initList} = () => { ${reconciler} = reconcileHydrated(${anchor}, ${endAnchor}, ${arrExpr}, ${keyFnSrc}, (${itemVar}, __i, __e, __root) => ${renderItem}(${itemVar}${indexParam ? ", __i, __e" : ", __e"}, null, __root), __hydrate, ${parent}, ${skipK}); };`);
31837
+ ctx2.push(`const ${initList} = () => { ${breakReset}${reconciler} = reconcileHydrated(${anchor}, ${endAnchor}, ${arrExpr}, ${keyFnSrc}, (${itemVar}, __i, __e, __root) => ${renderItem}(${itemVar}${indexParam ? ", __i, __e" : ", __e"}, null, __root), __hydrate, ${parent}, ${skipK}); };`);
31646
31838
  } else {
31647
- ctx2.push(`const ${initList} = () => { ${reconciler} = reconcile(${anchor}, ${endAnchor}, ${arrExpr}, ${keyFnSrc}, (${itemVar}, __i, __e) => ${renderItem}(${itemVar}${indexParam ? ", __i, __e" : ", __e"})); };`);
31839
+ ctx2.push(`const ${initList} = () => { ${breakReset}${reconciler} = reconcile(${anchor}, ${endAnchor}, ${arrExpr}, ${keyFnSrc}, (${itemVar}, __i, __e) => ${renderItem}(${itemVar}${indexParam ? ", __i, __e" : ", __e"})); };`);
31648
31840
  }
31649
31841
  if (emptyRenderName) {
31650
31842
  const isEmptyVar = ctx2.n();
@@ -31655,7 +31847,7 @@ function emitMap(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionBu
31655
31847
  const __new = ${hasItems}();
31656
31848
  if (__first) { __first = false; __new; return; }
31657
31849
  if (__new !== ${isEmptyVar}) {
31658
- if (__new) ${reconciler}(${arrExpr});
31850
+ if (__new) {${breakVar ? ` ${breakVar} = false;` : ""} ${reconciler}(${arrExpr}); }
31659
31851
  return;
31660
31852
  }
31661
31853
  ${isEmptyVar} = !__new;
@@ -31669,22 +31861,25 @@ function emitMap(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionBu
31669
31861
  if (!reactiveSource) return null;
31670
31862
  pushEffect(`let __first = true;`, `effect(() => {
31671
31863
  const __nv = ${arrExpr};
31672
- if (__first) { __first = false; __nv; ${reconciler}(${arrExpr}); return; }
31673
- ${reconciler}(${arrExpr});
31864
+ if (__first) { __first = false; __nv; ${breakReset}${reconciler}(${arrExpr}); return; }
31865
+ ${breakVar ? `if (${breakVar}) ${breakVar} = false;` : ""}${reconciler}(${arrExpr});
31674
31866
  })`);
31675
31867
  }
31676
31868
  } else {
31677
31869
  const renderAllItems = (ind, collect) => {
31678
31870
  const lines = [];
31871
+ if (breakVar) lines.push(`${ind}${breakVar} = false;`);
31679
31872
  if (node.indexVariable) {
31680
31873
  lines.push(`${ind}let __i = 0;`);
31681
31874
  lines.push(`${ind}for (const ${itemVar} of ${arrExpr}) {`);
31682
31875
  lines.push(`${ind} ${aw}${renderItem}(${itemVar}, __i, ${effectsVar}${collect ? `, null, ${collect}` : ""});`);
31683
31876
  lines.push(`${ind} __i++;`);
31877
+ if (breakVar) lines.push(`${ind} if (${breakVar}) break;`);
31684
31878
  lines.push(`${ind}}`);
31685
31879
  } else {
31686
31880
  lines.push(`${ind}for (const ${itemVar} of ${arrExpr}) {`);
31687
31881
  lines.push(`${ind} ${aw}${renderItem}(${itemVar}, ${effectsVar}${collect ? `, null, ${collect}` : ""});`);
31882
+ if (breakVar) lines.push(`${ind} if (${breakVar}) break;`);
31688
31883
  lines.push(`${ind}}`);
31689
31884
  }
31690
31885
  return lines.join("\n");
@@ -31770,8 +31965,19 @@ function generateComponent(comp, importedNames = /* @__PURE__ */ new Set(), hydr
31770
31965
  ctx2.push(indent2(`let __pendingChild = null;`));
31771
31966
  const paramInit = buildParamInit2(comp.paramNames, comp.propsAlias);
31772
31967
  if (paramInit) ctx2.push(indent2(paramInit));
31968
+ const deferredTrackDecls = /* @__PURE__ */ new Set();
31969
+ {
31970
+ const declaredSoFar = /* @__PURE__ */ new Set();
31971
+ for (const node of comp.body) {
31972
+ if (node instanceof TrackDecl) {
31973
+ if (initReadsAnyOf(node.init, declaredSoFar)) deferredTrackDecls.add(node);
31974
+ continue;
31975
+ }
31976
+ for (const name of runtimeDeclaredNames(node)) declaredSoFar.add(name);
31977
+ }
31978
+ }
31773
31979
  for (const node of comp.body) {
31774
- if (node instanceof TrackDecl) {
31980
+ if (node instanceof TrackDecl && !deferredTrackDecls.has(node)) {
31775
31981
  emitNode(ctx2, node, tracked2, null);
31776
31982
  }
31777
31983
  }
@@ -31798,7 +32004,10 @@ function generateComponent(comp, importedNames = /* @__PURE__ */ new Set(), hydr
31798
32004
  }
31799
32005
  }
31800
32006
  for (const node of comp.body) {
31801
- if (node instanceof TrackDecl) continue;
32007
+ if (node instanceof TrackDecl) {
32008
+ if (deferredTrackDecls.has(node)) emitNode(ctx2, node, tracked2, null);
32009
+ continue;
32010
+ }
31802
32011
  const v = emitNode(ctx2, node, tracked2, null, void 0, "__components", topPendingSkip, topBudget || void 0);
31803
32012
  if (v) {
31804
32013
  if (ctx2.hydrate) {
@@ -32257,6 +32466,9 @@ var init_client_codegen = __esm({
32257
32466
  walker = "__hydrate";
32258
32467
  asyncComps = /* @__PURE__ */ new Set();
32259
32468
  isAsyncScope = false;
32469
+ // While emitting a loop body, names the boolean flag a `break` sets (see
32470
+ // BreakSignal). Null outside a break-capable loop body.
32471
+ breakFlag = null;
32260
32472
  constructor(alloc) {
32261
32473
  this.alloc = alloc ?? { c: 0 };
32262
32474
  }
@@ -32978,6 +33190,7 @@ function irNodeToJS(node, importedNames, isAsync = false, tracked2) {
32978
33190
  }
32979
33191
  return semicolonizeStatement(transformTracked(node, tracked2 || /* @__PURE__ */ new Map()));
32980
33192
  }
33193
+ if (node instanceof BreakSignal) return `break;`;
32981
33194
  if (node instanceof SlotNode) {
32982
33195
  if (__vskMarkerless) return `__out.push(props.children || '');`;
32983
33196
  const sid = `s${nextVskId()}`;
@@ -33128,14 +33341,15 @@ function mapRegionToJS(node, isAsync = false, tracked2) {
33128
33341
  }
33129
33342
  const loopArr = arrVar || arr;
33130
33343
  if (node.indexVariable) {
33131
- lines.push("let __i = 0;");
33344
+ const counter = `__i${nextVskId()}`;
33345
+ lines.push(`let ${counter} = 0;`);
33132
33346
  lines.push(`for (const ${item} of ${loopArr}) {`);
33133
- lines.push(indent(`const ${node.indexVariable} = __i;`));
33347
+ lines.push(indent(`const ${node.indexVariable} = ${counter};`));
33134
33348
  for (const n of bodyForItem) {
33135
33349
  const code = irNodeToJS(n, null, isAsync, tracked2);
33136
33350
  if (code) lines.push(indent(code));
33137
33351
  }
33138
- lines.push(indent("__i++;"));
33352
+ lines.push(indent(`${counter}++;`));
33139
33353
  lines.push(`}`);
33140
33354
  } else {
33141
33355
  lines.push(`for (const ${item} of ${loopArr}) {`);
@@ -34218,6 +34432,94 @@ var init_server_render = __esm({
34218
34432
  }
34219
34433
  });
34220
34434
 
34435
+ // ../adapter/src/default-pages.ts
34436
+ function escapeDefaultPageHtml(value) {
34437
+ return String(value ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
34438
+ }
34439
+ function renderDefaultPage(opts = {}) {
34440
+ const status = opts.status ?? 404;
34441
+ const title = escapeDefaultPageHtml(opts.title ?? `${status} \u2014 Vesk`);
34442
+ const message = escapeDefaultPageHtml(opts.message ?? "This page could not be found.");
34443
+ const url = opts.url ? escapeDefaultPageHtml(opts.url) : "";
34444
+ const headExtra = opts.headExtra || "";
34445
+ const homeHref = opts.homeHref === void 0 ? "/" : opts.homeHref;
34446
+ const homeLabel = escapeDefaultPageHtml(opts.homeLabel ?? "Back to home");
34447
+ const variant = `vsk-page${opts.accentStatus ? " vsk-page--error" : ""}`;
34448
+ const action = homeHref === null ? "" : `<a class="vsk-page__btn" href="${escapeDefaultPageHtml(homeHref)}">${homeLabel}</a>`;
34449
+ return `<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="robots" content="noindex"><title>${title}</title><style>${DEFAULT_PAGE_CSS}</style>` + headExtra + `</head><body><main class="${variant}" data-vesk-default-page="${status}"><div class="vsk-page__card"><p class="vsk-page__brand"><b>Vesk</b> \xB7 built-in error page</p><div class="vsk-page__row"><span class="vsk-page__status">${status}</span><span class="vsk-page__msg">${message}</span></div>` + (url ? `<p class="vsk-page__detail">${url}</p>` : "") + (action ? `<div class="vsk-page__actions">${action}</div>` : "") + "</div></main></body></html>";
34450
+ }
34451
+ function renderDefaultNotFoundPage(opts = {}) {
34452
+ return renderDefaultPage({
34453
+ status: 404,
34454
+ title: "404 \u2014 Not Found",
34455
+ message: "This page could not be found.",
34456
+ url: opts.url,
34457
+ headExtra: opts.headExtra
34458
+ });
34459
+ }
34460
+ function renderDefaultErrorPage(opts = {}) {
34461
+ const status = opts.status ?? 500;
34462
+ return renderDefaultPage({
34463
+ status,
34464
+ title: `${status} \u2014 Internal Server Error`,
34465
+ message: opts.message || "Internal Server Error",
34466
+ url: opts.url,
34467
+ headExtra: opts.headExtra,
34468
+ accentStatus: true,
34469
+ homeHref: null
34470
+ });
34471
+ }
34472
+ function renderDefaultErrorFragment(opts = {}) {
34473
+ const status = opts.status ?? 500;
34474
+ const message = escapeDefaultPageHtml(opts.message || "Internal Server Error");
34475
+ return '<div data-vesk-default-error-fragment="' + status + '" style="display:flex;align-items:center;justify-content:center;min-height:60vh;padding:32px"><div style="display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"><div style="display:flex;align-items:center"><span style="font-size:24px;font-weight:500;line-height:49px;padding-right:23px;margin-right:20px;border-right:1px solid currentColor;opacity:.85">' + status + '</span><span style="font-size:14px;line-height:49px;opacity:.7">' + message + "</span></div></div></div>";
34476
+ }
34477
+ var DEFAULT_PAGE_CSS;
34478
+ var init_default_pages = __esm({
34479
+ "../adapter/src/default-pages.ts"() {
34480
+ "use strict";
34481
+ DEFAULT_PAGE_CSS = [
34482
+ ":root{color-scheme:light;",
34483
+ "--vsk-bg:oklch(0.941 0.014 88);",
34484
+ "--vsk-fg:oklch(0.185 0.008 62);",
34485
+ "--vsk-surface:oklch(0.965 0.012 88);",
34486
+ "--vsk-muted:oklch(0.475 0.014 72);",
34487
+ "--vsk-accent:oklch(0.560 0.140 42);",
34488
+ "--vsk-border:oklch(0.86 0.012 82);",
34489
+ "--vsk-border-strong:oklch(0.72 0.014 80);",
34490
+ '--vsk-font:"Space Grotesk",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;',
34491
+ '--vsk-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;}',
34492
+ "@media (prefers-color-scheme:dark){:root{color-scheme:dark;",
34493
+ "--vsk-bg:oklch(0.155 0.006 60);",
34494
+ "--vsk-fg:oklch(0.931 0.014 88);",
34495
+ "--vsk-surface:oklch(0.196 0.008 70);",
34496
+ "--vsk-muted:oklch(0.618 0.016 80);",
34497
+ "--vsk-accent:oklch(0.632 0.132 45);",
34498
+ "--vsk-border:oklch(0.29 0.009 75);",
34499
+ "--vsk-border-strong:oklch(0.40 0.011 75);}}",
34500
+ "*{box-sizing:border-box}",
34501
+ "html,body{margin:0;min-height:100%}",
34502
+ "body{background:var(--vsk-bg);color:var(--vsk-fg);font-family:var(--vsk-font);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}",
34503
+ ".vsk-page{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px}",
34504
+ ".vsk-page__card{width:100%;max-width:540px;border:1px solid var(--vsk-border);background:var(--vsk-surface);padding:clamp(28px,6vw,44px);text-align:center}",
34505
+ "@supports (background:color-mix(in oklab,red,red)){.vsk-page__card{background:color-mix(in oklab,var(--vsk-surface) 60%,transparent)}}",
34506
+ ".vsk-page__brand{margin:0 0 26px;font-family:var(--vsk-mono);font-size:10px;line-height:1;letter-spacing:.24em;text-transform:uppercase;color:var(--vsk-muted)}",
34507
+ ".vsk-page__brand b{color:var(--vsk-fg);font-weight:600}",
34508
+ ".vsk-page__row{display:flex;align-items:center;justify-content:center;gap:0;flex-wrap:wrap}",
34509
+ ".vsk-page__status{font-size:clamp(34px,9vw,46px);font-weight:600;line-height:1;letter-spacing:-.03em;padding-right:22px;margin-right:22px;border-right:1px solid var(--vsk-border-strong)}",
34510
+ ".vsk-page--error .vsk-page__status{color:var(--vsk-accent)}",
34511
+ ".vsk-page__msg{font-family:var(--vsk-mono);font-size:13px;line-height:1.5;color:var(--vsk-muted);text-align:left;max-width:270px}",
34512
+ "@media (max-width:440px){.vsk-page__row{flex-direction:column}.vsk-page__status{padding:0 0 16px;margin:0 0 16px;border-right:0;border-bottom:1px solid var(--vsk-border-strong)}.vsk-page__msg{text-align:center}}",
34513
+ ".vsk-page__detail{margin:20px 0 0;font-family:var(--vsk-mono);font-size:11px;line-height:1.6;color:var(--vsk-muted);word-break:break-all}",
34514
+ ".vsk-page__actions{margin-top:30px;display:flex;justify-content:center;gap:10px;flex-wrap:wrap}",
34515
+ ".vsk-page__btn{display:inline-block;padding:11px 22px;font-size:13px;font-weight:500;line-height:1;text-decoration:none;border:1px solid var(--vsk-fg);background:var(--vsk-fg);color:var(--vsk-bg);transition:opacity .18s cubic-bezier(.2,0,0,1)}",
34516
+ ".vsk-page__btn:hover{opacity:.86}",
34517
+ ".vsk-page__btn--ghost{background:transparent;color:var(--vsk-fg);border-color:var(--vsk-border-strong)}",
34518
+ ".vsk-page__btn--ghost:hover{background:var(--vsk-fg);color:var(--vsk-bg);border-color:var(--vsk-fg);opacity:1}"
34519
+ ].join("");
34520
+ }
34521
+ });
34522
+
34221
34523
  // ../adapter/src/paths.ts
34222
34524
  import { resolve as resolve11, sep as sep2 } from "node:path";
34223
34525
  import { existsSync as existsSync12, statSync as statSync4, readFileSync as readFileSync12 } from "node:fs";
@@ -35804,6 +36106,7 @@ function generatePlatformHandlerSource(input) {
35804
36106
  const prerenderedList = prerenderedPaths.length > 0 ? `const __prerendered = new Set(${JSON.stringify(prerenderedPaths)});
35805
36107
  ` : "const __prerendered = new Set();\n";
35806
36108
  const isrCache = "const __isrCache = new Map();";
36109
+ const defaultNotFoundLine = `const __defaultNotFoundHtml = ${JSON.stringify(renderDefaultNotFoundPage())};`;
35807
36110
  const serverStoreLine = hasEvents ? "const __serverStore = globalThis.__vesk_server_ctx || {};" : "";
35808
36111
  const eventsStartLine = hasEvents ? " await __eventsStart({ server: null });" : "";
35809
36112
  const eventsRequestLine = hasEvents ? " await __eventsRequest(mwCtx);" : "";
@@ -35817,6 +36120,7 @@ ${mwImport}
35817
36120
  ${eventsImport}
35818
36121
  ${prerenderedList}
35819
36122
  ${isrCache}
36123
+ ${defaultNotFoundLine}
35820
36124
  const __routes = [${routeEntries.join(",\n")}];
35821
36125
 
35822
36126
  async function __invokeRoute(route, request) {
@@ -35830,7 +36134,7 @@ async function __invokeRoute(route, request) {
35830
36134
  });
35831
36135
  }
35832
36136
  if (e && typeof e === 'object' && e.name === 'NotFoundError') {
35833
- return new Response('<!DOCTYPE html><html><body><h1>404</h1><p>Not Found</p></body></html>', {
36137
+ return new Response(__defaultNotFoundHtml, {
35834
36138
  status: 404,
35835
36139
  headers: { 'Content-Type': 'text/html' },
35836
36140
  });
@@ -35957,7 +36261,7 @@ ${eventsRequestLine}
35957
36261
  return response;
35958
36262
  }
35959
36263
 
35960
- return new Response('<!DOCTYPE html><html><body><h1>404</h1><p>Not Found</p></body></html>', {
36264
+ return new Response(__defaultNotFoundHtml, {
35961
36265
  status: 404,
35962
36266
  headers: { 'Content-Type': 'text/html' },
35963
36267
  });
@@ -36052,6 +36356,7 @@ var __dirname5;
36052
36356
  var init_platform_handler = __esm({
36053
36357
  "../adapter/src/platform-handler.ts"() {
36054
36358
  "use strict";
36359
+ init_default_pages();
36055
36360
  __dirname5 = dirname13(fileURLToPath4(import.meta.url));
36056
36361
  }
36057
36362
  });
@@ -48501,6 +48806,7 @@ function resolveCssUrls(opts) {
48501
48806
  }
48502
48807
 
48503
48808
  // ../adapter/src/ssr-function.ts
48809
+ init_default_pages();
48504
48810
  function resolveErrorFile(sourceDir, appDir) {
48505
48811
  const rel = relative(appDir, sourceDir).split("/").filter(Boolean);
48506
48812
  for (let depth = rel.length; depth >= 0; depth--) {
@@ -48701,7 +49007,7 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
48701
49007
  " const result = await renderPage('', _errorComp, props, __componentRegistry, { hydrate: true, cached: _errorCompiled });",
48702
49008
  " return result.body;",
48703
49009
  " } catch {",
48704
- " return '<h1>500 \\u2014 Internal Server Error</h1>';",
49010
+ ` return ${JSON.stringify(renderDefaultErrorFragment())};`,
48705
49011
  " }",
48706
49012
  "}",
48707
49013
  "",
@@ -50907,6 +51213,7 @@ async function loadVeskConfig2(projectDir) {
50907
51213
  }
50908
51214
 
50909
51215
  // ../adapter/src/prod-server.ts
51216
+ init_default_pages();
50910
51217
  var __dirname4 = dirname10(fileURLToPath3(import.meta.url));
50911
51218
  async function deliverResponse(res, response) {
50912
51219
  res.writeHead(response.status, Object.fromEntries(response.headers));
@@ -51367,7 +51674,7 @@ async function startProdServer(outDir, options) {
51367
51674
  }
51368
51675
  if (err.name === "NotFoundError") {
51369
51676
  res.writeHead(404, { "Content-Type": "text/html" });
51370
- res.end(notFoundHtml || "<!DOCTYPE html><html><body><h1>404</h1><p>Not Found</p></body></html>");
51677
+ res.end(notFoundHtml || renderDefaultNotFoundPage({ url: url.pathname, headExtra: bakedHeadExtra }));
51371
51678
  return;
51372
51679
  }
51373
51680
  console.error("vesk ssr error:", err.message);
@@ -51395,7 +51702,7 @@ async function startProdServer(outDir, options) {
51395
51702
  }
51396
51703
  }
51397
51704
  res.writeHead(500, { "Content-Type": "text/html" });
51398
- res.end(errorHtml || "<!DOCTYPE html><html><body><h1>500</h1><pre>Internal Server Error</pre></body></html>");
51705
+ res.end(errorHtml || renderDefaultErrorPage({ message: process.env.NODE_ENV !== "production" ? err.message : void 0, url: url.pathname, headExtra: bakedHeadExtra }));
51399
51706
  return;
51400
51707
  }
51401
51708
  }
@@ -51403,7 +51710,7 @@ async function startProdServer(outDir, options) {
51403
51710
  }
51404
51711
  }
51405
51712
  res.writeHead(404, { "Content-Type": "text/html" });
51406
- res.end(notFoundHtml || "<!DOCTYPE html><html><body><h1>404</h1><p>Not Found</p></body></html>");
51713
+ res.end(notFoundHtml || renderDefaultNotFoundPage({ url: url.pathname, headExtra: bakedHeadExtra }));
51407
51714
  });
51408
51715
  try {
51409
51716
  await eventsMod?.executeStart?.({ server, port, host });
@@ -52421,15 +52728,38 @@ function transformTracked2(irNode, tracked2) {
52421
52728
  }
52422
52729
  function collectTrackedNames2(body) {
52423
52730
  const names = /* @__PURE__ */ new Map();
52731
+ collectTrackedNamesInto2(body, names);
52732
+ return names;
52733
+ }
52734
+ function collectTrackedNamesInto2(body, names) {
52424
52735
  for (const node of body) {
52425
52736
  if (node instanceof TrackDecl) {
52426
52737
  const cellName = node.rawName || node.name;
52427
52738
  names.set(node.name, { cellName, kind: "virtual" });
52428
52739
  if (node.rawName)
52429
52740
  names.set(node.rawName, { cellName, kind: "cell" });
52741
+ } else if (node instanceof StaticNode || node instanceof ServerBlock || node instanceof ClientBlock || node instanceof HeadBlock) {
52742
+ collectTrackedNamesInto2(node.children, names);
52743
+ } else if (node instanceof ComponentCall) {
52744
+ collectTrackedNamesInto2(node.children, names);
52745
+ } else if (node instanceof PropSlot) {
52746
+ collectTrackedNamesInto2(node.body, names);
52747
+ } else if (node instanceof MapRegion) {
52748
+ collectTrackedNamesInto2(node.bodyTemplate, names);
52749
+ collectTrackedNamesInto2(node.alternateNodes, names);
52750
+ } else if (node instanceof OpaqueDynamicRegion) {
52751
+ collectTrackedNamesInto2(node.consequentNodes, names);
52752
+ collectTrackedNamesInto2(node.alternateNodes, names);
52753
+ } else if (node instanceof WhileLoop || node instanceof ForLoop) {
52754
+ collectTrackedNamesInto2(node.bodyTemplate, names);
52755
+ } else if (node instanceof TryCatch) {
52756
+ collectTrackedNamesInto2(node.bodyTemplate, names);
52757
+ collectTrackedNamesInto2(node.catchBody, names);
52758
+ } else if (node instanceof SwitchBlock) {
52759
+ for (const c of node.cases)
52760
+ collectTrackedNamesInto2(c.body, names);
52430
52761
  }
52431
52762
  }
52432
- return names;
52433
52763
  }
52434
52764
  function collectTrackedDeps2(value, tracked2) {
52435
52765
  const ast = value?.ast;
@@ -52469,6 +52799,64 @@ function transformTrackedInit2(init, tracked2) {
52469
52799
  return init;
52470
52800
  return transformTracked2({ raw: init, ast: expr }, tracked2);
52471
52801
  }
52802
+ function runtimeDeclaredNames2(node) {
52803
+ if (!(node instanceof RuntimeStatement))
52804
+ return [];
52805
+ const stmt = node.ast;
52806
+ if (!stmt || stmt.type !== "VariableDeclaration" || !stmt.declarations)
52807
+ return [];
52808
+ const out = [];
52809
+ for (const d of stmt.declarations) {
52810
+ if (d.id && d.id.type === "Identifier" && typeof d.id.name === "string")
52811
+ out.push(d.id.name);
52812
+ }
52813
+ return out;
52814
+ }
52815
+ function initReadsAnyOf2(init, names) {
52816
+ if (!init || names.size === 0)
52817
+ return false;
52818
+ let expr = null;
52819
+ try {
52820
+ const prog = parse4(`(${init})`);
52821
+ expr = prog.body?.[0]?.type === "ExpressionStatement" ? prog.body[0].expression ?? null : null;
52822
+ } catch {
52823
+ return false;
52824
+ }
52825
+ if (!expr)
52826
+ return false;
52827
+ let found = false;
52828
+ const walk9 = (n) => {
52829
+ if (found || !n || typeof n !== "object")
52830
+ return;
52831
+ if (Array.isArray(n)) {
52832
+ for (const c of n)
52833
+ walk9(c);
52834
+ return;
52835
+ }
52836
+ const t = n.type;
52837
+ if (typeof t !== "string")
52838
+ return;
52839
+ if (t === "Identifier") {
52840
+ if (names.has(n.name))
52841
+ found = true;
52842
+ return;
52843
+ }
52844
+ if (t === "MemberExpression") {
52845
+ const m = n;
52846
+ walk9(m.object);
52847
+ if (m.computed)
52848
+ walk9(m.property);
52849
+ return;
52850
+ }
52851
+ for (const key of Object.keys(n)) {
52852
+ if (key === "loc" || key === "range" || key === "start" || key === "end")
52853
+ continue;
52854
+ walk9(n[key]);
52855
+ }
52856
+ };
52857
+ walk9(expr);
52858
+ return found;
52859
+ }
52472
52860
  var NON_BUBBLING_EVENTS2 = /* @__PURE__ */ new Set([
52473
52861
  "focus",
52474
52862
  "blur",
@@ -52544,6 +52932,9 @@ var Ctx2 = class {
52544
52932
  walker = "__hydrate";
52545
52933
  asyncComps = /* @__PURE__ */ new Set();
52546
52934
  isAsyncScope = false;
52935
+ // While emitting a loop body, names the boolean flag a `break` sets (see
52936
+ // BreakSignal). Null outside a break-capable loop body.
52937
+ breakFlag = null;
52547
52938
  constructor(alloc) {
52548
52939
  this.alloc = alloc ?? { c: 0 };
52549
52940
  }
@@ -52631,6 +53022,11 @@ function emitNode2(ctx2, node, tracked2, effectsVar, parentVar, compPrefix = "__
52631
53022
  ctx2.push(semicolonizeStatement2(transformTracked2(node, tracked2)));
52632
53023
  return null;
52633
53024
  }
53025
+ if (node instanceof BreakSignal) {
53026
+ if (ctx2.breakFlag)
53027
+ ctx2.push(`${ctx2.breakFlag} = true;`);
53028
+ return null;
53029
+ }
52634
53030
  if (node instanceof SlotNode) {
52635
53031
  if (!parentVar) {
52636
53032
  if (ctx2.hydrate) {
@@ -53543,6 +53939,8 @@ function emitWhileLoop2(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget
53543
53939
  ctx2.push(`const ${endAnchor} = document.createComment('while-end');`);
53544
53940
  emitHydrateFenceAnchoring2(ctx2, anchor, endAnchor, parent === "$root", budget || void 0);
53545
53941
  const renderLoop = ctx2.n();
53942
+ const hasBreak = bodyHasBreak2(node.bodyTemplate);
53943
+ const breakVar = hasBreak ? ctx2.n() : null;
53546
53944
  ctx2.push(`const ${renderLoop} = ${ctx2.isAsyncScope ? "async () => {" : "() => {"}`);
53547
53945
  if (!hyd)
53548
53946
  ctx2.push(indent3(`const __p = ${anchor}.parentNode;`));
@@ -53550,8 +53948,14 @@ function emitWhileLoop2(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget
53550
53948
  ctx2.push(indent3(`const __b = document.createDocumentFragment();`));
53551
53949
  if (hyd)
53552
53950
  ctx2.push(indent3(`const __cl = [];`));
53951
+ if (breakVar)
53952
+ ctx2.push(indent3(`let ${breakVar} = false;`));
53953
+ const savedBreakFlag = ctx2.breakFlag;
53954
+ ctx2.breakFlag = breakVar;
53553
53955
  if (node.isDoWhile) {
53554
53956
  ctx2.push(indent3(`do {`));
53957
+ if (breakVar)
53958
+ ctx2.push(indent3(indent3(`if (${breakVar}) break;`)));
53555
53959
  for (const n of node.bodyTemplate) {
53556
53960
  const v = emitNode2(ctx2, n, tracked2, effectsVar, hyd ? parentVar : "__b", "__components", 0, budget || void 0);
53557
53961
  if (v) {
@@ -53564,6 +53968,8 @@ function emitWhileLoop2(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget
53564
53968
  ctx2.push(indent3(`} while (${condExpr});`));
53565
53969
  } else {
53566
53970
  ctx2.push(indent3(`while (${condExpr}) {`));
53971
+ if (breakVar)
53972
+ ctx2.push(indent3(indent3(`if (${breakVar}) break;`)));
53567
53973
  for (const n of node.bodyTemplate) {
53568
53974
  const v = emitNode2(ctx2, n, tracked2, effectsVar, hyd ? parentVar : "__b", "__components", 0, budget || void 0);
53569
53975
  if (v) {
@@ -53575,6 +53981,7 @@ function emitWhileLoop2(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget
53575
53981
  }
53576
53982
  ctx2.push(indent3(`}`));
53577
53983
  }
53984
+ ctx2.breakFlag = savedBreakFlag;
53578
53985
  if (!hyd)
53579
53986
  ctx2.push(indent3(`__p.insertBefore(__b, ${endAnchor});`));
53580
53987
  if (hyd)
@@ -53618,6 +54025,8 @@ function emitForLoop2(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget)
53618
54025
  ctx2.push(`const ${endAnchor} = document.createComment('for-end');`);
53619
54026
  emitHydrateFenceAnchoring2(ctx2, anchor, endAnchor, parent === "$root", budget || void 0);
53620
54027
  const renderLoop = ctx2.n();
54028
+ const forHasBreak = bodyHasBreak2(node.bodyTemplate);
54029
+ const forBreakVar = forHasBreak ? ctx2.n() : null;
53621
54030
  ctx2.push(`const ${renderLoop} = ${ctx2.isAsyncScope ? "async () => {" : "() => {"}`);
53622
54031
  if (!hyd)
53623
54032
  ctx2.push(indent3(`const __p = ${anchor}.parentNode;`));
@@ -53625,9 +54034,15 @@ function emitForLoop2(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget)
53625
54034
  ctx2.push(indent3(`const __b = document.createDocumentFragment();`));
53626
54035
  if (hyd)
53627
54036
  ctx2.push(indent3(`const __cl = [];`));
54037
+ if (forBreakVar)
54038
+ ctx2.push(indent3(`let ${forBreakVar} = false;`));
54039
+ const savedForBreakFlag = ctx2.breakFlag;
54040
+ ctx2.breakFlag = forBreakVar;
53628
54041
  if (node.kind === "for-in") {
53629
54042
  const srcExpr = transformTracked2(node.condition, tracked2);
53630
54043
  ctx2.push(indent3(`for (${node.init} of (Array.isArray(${srcExpr}) ? ${srcExpr} : (${srcExpr} == null ? [] : Object.keys(${srcExpr})))) {`));
54044
+ if (forBreakVar)
54045
+ ctx2.push(indent3(indent3(`if (${forBreakVar}) break;`)));
53631
54046
  for (const n of node.bodyTemplate) {
53632
54047
  const v = emitNode2(ctx2, n, tracked2, effectsVar, hyd ? parentVar : "__b", "__components", 0, budget || void 0);
53633
54048
  if (v) {
@@ -53648,6 +54063,8 @@ function emitForLoop2(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget)
53648
54063
  updatePart = updatePart.slice(0, -1).trim();
53649
54064
  const head = initPart ? `${initPart}; ${condExpr}` : `; ${condExpr}`;
53650
54065
  ctx2.push(indent3(`for (${head}; ${updatePart}) {`));
54066
+ if (forBreakVar)
54067
+ ctx2.push(indent3(indent3(`if (${forBreakVar}) break;`)));
53651
54068
  for (const n of node.bodyTemplate) {
53652
54069
  const v = emitNode2(ctx2, n, tracked2, effectsVar, hyd ? parentVar : "__b", "__components", 0, budget || void 0);
53653
54070
  if (v) {
@@ -53659,6 +54076,7 @@ function emitForLoop2(ctx2, node, tracked2, parentVar, skipK = 0, regionBudget)
53659
54076
  }
53660
54077
  ctx2.push(indent3(`}`));
53661
54078
  }
54079
+ ctx2.breakFlag = savedForBreakFlag;
53662
54080
  if (!hyd)
53663
54081
  ctx2.push(indent3(`__p.insertBefore(__b, ${endAnchor});`));
53664
54082
  if (hyd)
@@ -53830,6 +54248,36 @@ function emitSwitchBlock2(ctx2, node, tracked2, parentVar, skipK = 0, regionBudg
53830
54248
  }`);
53831
54249
  return null;
53832
54250
  }
54251
+ function bodyHasBreak2(nodes) {
54252
+ for (const n of nodes) {
54253
+ if (n instanceof BreakSignal)
54254
+ return true;
54255
+ if (n instanceof OpaqueDynamicRegion) {
54256
+ if (bodyHasBreak2([...n.consequentNodes, ...n.alternateNodes]))
54257
+ return true;
54258
+ } else if (n instanceof SwitchBlock) {
54259
+ for (const c of n.cases)
54260
+ if (bodyHasBreak2(c.body))
54261
+ return true;
54262
+ } else if (n instanceof TryCatch) {
54263
+ if (bodyHasBreak2([...n.bodyTemplate, ...n.catchBody]))
54264
+ return true;
54265
+ } else if (n instanceof StaticNode) {
54266
+ if (bodyHasBreak2(n.children))
54267
+ return true;
54268
+ } else if (n instanceof ComponentCall) {
54269
+ if (bodyHasBreak2(n.children))
54270
+ return true;
54271
+ } else if (n instanceof ServerBlock || n instanceof ClientBlock || n instanceof HeadBlock) {
54272
+ if (bodyHasBreak2(n.children))
54273
+ return true;
54274
+ } else if (n instanceof PropSlot) {
54275
+ if (bodyHasBreak2(n.body))
54276
+ return true;
54277
+ }
54278
+ }
54279
+ return false;
54280
+ }
53833
54281
  function emitMap2(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionBudget) {
53834
54282
  const arrExpr = transformTracked2(node.expression, tracked2);
53835
54283
  const itemVar = node.itemVariable;
@@ -53863,9 +54311,15 @@ function emitMap2(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionB
53863
54311
  ctx2.push(`let ${effectsVar} = [];`);
53864
54312
  ctx2.push(`const ${endAnchor} = document.createComment('map-end');`);
53865
54313
  const renderItem = ctx2.n();
54314
+ const hasBreak = bodyHasBreak2(node.bodyTemplate);
54315
+ const breakVar = hasBreak ? ctx2.n() : null;
54316
+ if (breakVar)
54317
+ ctx2.push(`let ${breakVar} = false;`);
53866
54318
  const indexParam = node.indexVariable ? ", __i" : "";
53867
54319
  ctx2.push(`const ${renderItem} = ${ctx2.isAsyncScope ? "async " : ""}(${itemVar}${indexParam}, __e, __r${hyd ? ", __cl" : ""}${hydKeyed ? ", __root" : ""}) => {`);
53868
54320
  ctx2.push(indent3(`__r = __r || ${endAnchor};`));
54321
+ if (breakVar)
54322
+ ctx2.push(indent3(`if (${breakVar}) return;`));
53869
54323
  if (node.indexVariable)
53870
54324
  ctx2.push(indent3(`const ${node.indexVariable} = __i;`));
53871
54325
  if (hyd) {
@@ -53876,6 +54330,8 @@ function emitMap2(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionB
53876
54330
  }
53877
54331
  if (hydKeyed)
53878
54332
  ctx2.rootClaim = true;
54333
+ const savedMapBreak = ctx2.breakFlag;
54334
+ ctx2.breakFlag = breakVar;
53879
54335
  for (const n of node.bodyTemplate) {
53880
54336
  const v = emitNode2(ctx2, n, tracked2, "__e", hyd ? void 0 : "__it", "__components", 0, budget || void 0);
53881
54337
  if (v) {
@@ -53888,6 +54344,7 @@ function emitMap2(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionB
53888
54344
  }
53889
54345
  }
53890
54346
  }
54347
+ ctx2.breakFlag = savedMapBreak;
53891
54348
  if (hydKeyed)
53892
54349
  ctx2.rootClaim = false;
53893
54350
  if (!hyd)
@@ -53931,11 +54388,12 @@ function emitMap2(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionB
53931
54388
  const keyFnSrc = `(${itemVar}${node.indexVariable ? `, ${node.indexVariable}` : ""}) => ${keyExpr}`;
53932
54389
  const reconciler = ctx2.n();
53933
54390
  const initList = ctx2.n();
54391
+ const breakReset = breakVar ? `${breakVar} = false; ` : "";
53934
54392
  ctx2.push(`let ${reconciler} = () => {};`);
53935
54393
  if (hydKeyed) {
53936
- ctx2.push(`const ${initList} = () => { ${reconciler} = reconcileHydrated(${anchor}, ${endAnchor}, ${arrExpr}, ${keyFnSrc}, (${itemVar}, __i, __e, __root) => ${renderItem}(${itemVar}${indexParam ? ", __i, __e" : ", __e"}, null, __root), __hydrate, ${parent}, ${skipK}); };`);
54394
+ ctx2.push(`const ${initList} = () => { ${breakReset}${reconciler} = reconcileHydrated(${anchor}, ${endAnchor}, ${arrExpr}, ${keyFnSrc}, (${itemVar}, __i, __e, __root) => ${renderItem}(${itemVar}${indexParam ? ", __i, __e" : ", __e"}, null, __root), __hydrate, ${parent}, ${skipK}); };`);
53937
54395
  } else {
53938
- ctx2.push(`const ${initList} = () => { ${reconciler} = reconcile(${anchor}, ${endAnchor}, ${arrExpr}, ${keyFnSrc}, (${itemVar}, __i, __e) => ${renderItem}(${itemVar}${indexParam ? ", __i, __e" : ", __e"})); };`);
54396
+ ctx2.push(`const ${initList} = () => { ${breakReset}${reconciler} = reconcile(${anchor}, ${endAnchor}, ${arrExpr}, ${keyFnSrc}, (${itemVar}, __i, __e) => ${renderItem}(${itemVar}${indexParam ? ", __i, __e" : ", __e"})); };`);
53939
54397
  }
53940
54398
  if (emptyRenderName) {
53941
54399
  const isEmptyVar = ctx2.n();
@@ -53947,7 +54405,7 @@ function emitMap2(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionB
53947
54405
  const __new = ${hasItems}();
53948
54406
  if (__first) { __first = false; __new; return; }
53949
54407
  if (__new !== ${isEmptyVar}) {
53950
- if (__new) ${reconciler}(${arrExpr});
54408
+ if (__new) {${breakVar ? ` ${breakVar} = false;` : ""} ${reconciler}(${arrExpr}); }
53951
54409
  return;
53952
54410
  }
53953
54411
  ${isEmptyVar} = !__new;
@@ -53962,22 +54420,28 @@ function emitMap2(ctx2, node, tracked2, effTarget, parentVar, skipK = 0, regionB
53962
54420
  return null;
53963
54421
  pushEffect(`let __first = true;`, `effect(() => {
53964
54422
  const __nv = ${arrExpr};
53965
- if (__first) { __first = false; __nv; ${reconciler}(${arrExpr}); return; }
53966
- ${reconciler}(${arrExpr});
54423
+ if (__first) { __first = false; __nv; ${breakReset}${reconciler}(${arrExpr}); return; }
54424
+ ${breakVar ? `if (${breakVar}) ${breakVar} = false;` : ""}${reconciler}(${arrExpr});
53967
54425
  })`);
53968
54426
  }
53969
54427
  } else {
53970
54428
  const renderAllItems = (ind, collect) => {
53971
54429
  const lines = [];
54430
+ if (breakVar)
54431
+ lines.push(`${ind}${breakVar} = false;`);
53972
54432
  if (node.indexVariable) {
53973
54433
  lines.push(`${ind}let __i = 0;`);
53974
54434
  lines.push(`${ind}for (const ${itemVar} of ${arrExpr}) {`);
53975
54435
  lines.push(`${ind} ${aw}${renderItem}(${itemVar}, __i, ${effectsVar}${collect ? `, null, ${collect}` : ""});`);
53976
54436
  lines.push(`${ind} __i++;`);
54437
+ if (breakVar)
54438
+ lines.push(`${ind} if (${breakVar}) break;`);
53977
54439
  lines.push(`${ind}}`);
53978
54440
  } else {
53979
54441
  lines.push(`${ind}for (const ${itemVar} of ${arrExpr}) {`);
53980
54442
  lines.push(`${ind} ${aw}${renderItem}(${itemVar}, ${effectsVar}${collect ? `, null, ${collect}` : ""});`);
54443
+ if (breakVar)
54444
+ lines.push(`${ind} if (${breakVar}) break;`);
53981
54445
  lines.push(`${ind}}`);
53982
54446
  }
53983
54447
  return lines.join("\n");
@@ -54070,8 +54534,21 @@ function generateComponent2(comp, importedNames = /* @__PURE__ */ new Set(), hyd
54070
54534
  const paramInit = buildParamInit3(comp.paramNames, comp.propsAlias);
54071
54535
  if (paramInit)
54072
54536
  ctx2.push(indent3(paramInit));
54537
+ const deferredTrackDecls = /* @__PURE__ */ new Set();
54538
+ {
54539
+ const declaredSoFar = /* @__PURE__ */ new Set();
54540
+ for (const node of comp.body) {
54541
+ if (node instanceof TrackDecl) {
54542
+ if (initReadsAnyOf2(node.init, declaredSoFar))
54543
+ deferredTrackDecls.add(node);
54544
+ continue;
54545
+ }
54546
+ for (const name of runtimeDeclaredNames2(node))
54547
+ declaredSoFar.add(name);
54548
+ }
54549
+ }
54073
54550
  for (const node of comp.body) {
54074
- if (node instanceof TrackDecl) {
54551
+ if (node instanceof TrackDecl && !deferredTrackDecls.has(node)) {
54075
54552
  emitNode2(ctx2, node, tracked2, null);
54076
54553
  }
54077
54554
  }
@@ -54094,8 +54571,11 @@ function generateComponent2(comp, importedNames = /* @__PURE__ */ new Set(), hyd
54094
54571
  }
54095
54572
  }
54096
54573
  for (const node of comp.body) {
54097
- if (node instanceof TrackDecl)
54574
+ if (node instanceof TrackDecl) {
54575
+ if (deferredTrackDecls.has(node))
54576
+ emitNode2(ctx2, node, tracked2, null);
54098
54577
  continue;
54578
+ }
54099
54579
  const v = emitNode2(ctx2, node, tracked2, null, void 0, "__components", topPendingSkip, topBudget || void 0);
54100
54580
  if (v) {
54101
54581
  if (ctx2.hydrate) {
@@ -61847,6 +62327,71 @@ function createVeskTools(deps) {
61847
62327
  return tools;
61848
62328
  }
61849
62329
 
62330
+ // ../adapter/dist/default-pages.js
62331
+ function escapeDefaultPageHtml2(value) {
62332
+ return String(value ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
62333
+ }
62334
+ var DEFAULT_PAGE_CSS2 = [
62335
+ ":root{color-scheme:light;",
62336
+ "--vsk-bg:oklch(0.941 0.014 88);",
62337
+ "--vsk-fg:oklch(0.185 0.008 62);",
62338
+ "--vsk-surface:oklch(0.965 0.012 88);",
62339
+ "--vsk-muted:oklch(0.475 0.014 72);",
62340
+ "--vsk-accent:oklch(0.560 0.140 42);",
62341
+ "--vsk-border:oklch(0.86 0.012 82);",
62342
+ "--vsk-border-strong:oklch(0.72 0.014 80);",
62343
+ '--vsk-font:"Space Grotesk",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;',
62344
+ '--vsk-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;}',
62345
+ "@media (prefers-color-scheme:dark){:root{color-scheme:dark;",
62346
+ "--vsk-bg:oklch(0.155 0.006 60);",
62347
+ "--vsk-fg:oklch(0.931 0.014 88);",
62348
+ "--vsk-surface:oklch(0.196 0.008 70);",
62349
+ "--vsk-muted:oklch(0.618 0.016 80);",
62350
+ "--vsk-accent:oklch(0.632 0.132 45);",
62351
+ "--vsk-border:oklch(0.29 0.009 75);",
62352
+ "--vsk-border-strong:oklch(0.40 0.011 75);}}",
62353
+ "*{box-sizing:border-box}",
62354
+ "html,body{margin:0;min-height:100%}",
62355
+ "body{background:var(--vsk-bg);color:var(--vsk-fg);font-family:var(--vsk-font);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}",
62356
+ ".vsk-page{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px}",
62357
+ ".vsk-page__card{width:100%;max-width:540px;border:1px solid var(--vsk-border);background:var(--vsk-surface);padding:clamp(28px,6vw,44px);text-align:center}",
62358
+ "@supports (background:color-mix(in oklab,red,red)){.vsk-page__card{background:color-mix(in oklab,var(--vsk-surface) 60%,transparent)}}",
62359
+ ".vsk-page__brand{margin:0 0 26px;font-family:var(--vsk-mono);font-size:10px;line-height:1;letter-spacing:.24em;text-transform:uppercase;color:var(--vsk-muted)}",
62360
+ ".vsk-page__brand b{color:var(--vsk-fg);font-weight:600}",
62361
+ ".vsk-page__row{display:flex;align-items:center;justify-content:center;gap:0;flex-wrap:wrap}",
62362
+ ".vsk-page__status{font-size:clamp(34px,9vw,46px);font-weight:600;line-height:1;letter-spacing:-.03em;padding-right:22px;margin-right:22px;border-right:1px solid var(--vsk-border-strong)}",
62363
+ ".vsk-page--error .vsk-page__status{color:var(--vsk-accent)}",
62364
+ ".vsk-page__msg{font-family:var(--vsk-mono);font-size:13px;line-height:1.5;color:var(--vsk-muted);text-align:left;max-width:270px}",
62365
+ "@media (max-width:440px){.vsk-page__row{flex-direction:column}.vsk-page__status{padding:0 0 16px;margin:0 0 16px;border-right:0;border-bottom:1px solid var(--vsk-border-strong)}.vsk-page__msg{text-align:center}}",
62366
+ ".vsk-page__detail{margin:20px 0 0;font-family:var(--vsk-mono);font-size:11px;line-height:1.6;color:var(--vsk-muted);word-break:break-all}",
62367
+ ".vsk-page__actions{margin-top:30px;display:flex;justify-content:center;gap:10px;flex-wrap:wrap}",
62368
+ ".vsk-page__btn{display:inline-block;padding:11px 22px;font-size:13px;font-weight:500;line-height:1;text-decoration:none;border:1px solid var(--vsk-fg);background:var(--vsk-fg);color:var(--vsk-bg);transition:opacity .18s cubic-bezier(.2,0,0,1)}",
62369
+ ".vsk-page__btn:hover{opacity:.86}",
62370
+ ".vsk-page__btn--ghost{background:transparent;color:var(--vsk-fg);border-color:var(--vsk-border-strong)}",
62371
+ ".vsk-page__btn--ghost:hover{background:var(--vsk-fg);color:var(--vsk-bg);border-color:var(--vsk-fg);opacity:1}"
62372
+ ].join("");
62373
+ function renderDefaultPage2(opts = {}) {
62374
+ const status = opts.status ?? 404;
62375
+ const title = escapeDefaultPageHtml2(opts.title ?? `${status} \u2014 Vesk`);
62376
+ const message = escapeDefaultPageHtml2(opts.message ?? "This page could not be found.");
62377
+ const url = opts.url ? escapeDefaultPageHtml2(opts.url) : "";
62378
+ const headExtra = opts.headExtra || "";
62379
+ const homeHref = opts.homeHref === void 0 ? "/" : opts.homeHref;
62380
+ const homeLabel = escapeDefaultPageHtml2(opts.homeLabel ?? "Back to home");
62381
+ const variant = `vsk-page${opts.accentStatus ? " vsk-page--error" : ""}`;
62382
+ const action = homeHref === null ? "" : `<a class="vsk-page__btn" href="${escapeDefaultPageHtml2(homeHref)}">${homeLabel}</a>`;
62383
+ return `<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="robots" content="noindex"><title>${title}</title><style>${DEFAULT_PAGE_CSS2}</style>` + headExtra + `</head><body><main class="${variant}" data-vesk-default-page="${status}"><div class="vsk-page__card"><p class="vsk-page__brand"><b>Vesk</b> \xB7 built-in error page</p><div class="vsk-page__row"><span class="vsk-page__status">${status}</span><span class="vsk-page__msg">${message}</span></div>` + (url ? `<p class="vsk-page__detail">${url}</p>` : "") + (action ? `<div class="vsk-page__actions">${action}</div>` : "") + "</div></main></body></html>";
62384
+ }
62385
+ function renderDefaultNotFoundPage2(opts = {}) {
62386
+ return renderDefaultPage2({
62387
+ status: 404,
62388
+ title: "404 \u2014 Not Found",
62389
+ message: "This page could not be found.",
62390
+ url: opts.url,
62391
+ headExtra: opts.headExtra
62392
+ });
62393
+ }
62394
+
61850
62395
  // ../adapter/dist/css.js
61851
62396
  import { readFileSync as readFileSync33, existsSync as existsSync37 } from "node:fs";
61852
62397
  import { resolve as resolve33 } from "node:path";
@@ -61878,6 +62423,7 @@ import { WebSocketServer } from "ws";
61878
62423
  import { readFileSync as readFileSync34, existsSync as existsSync38, writeFileSync as writeFileSync19 } from "node:fs";
61879
62424
  import { resolve as resolve34, dirname as dirname24 } from "node:path";
61880
62425
  import { fileURLToPath as fileURLToPath7 } from "node:url";
62426
+ init_default_pages();
61881
62427
  init_paths();
61882
62428
 
61883
62429
  // ../adapter/src/error-codeframe.ts
@@ -64276,7 +64822,7 @@ Object.defineProperty(__components, ${JSON.stringify(cname)}, { get: () => __com
64276
64822
  }
64277
64823
  logRequest(404);
64278
64824
  res.writeHead(404, { "Content-Type": "text/html" });
64279
- res.end(notFoundHtml || `<!DOCTYPE html><html><body><h1>404</h1><p>${url.pathname}</p></body></html>`);
64825
+ res.end(notFoundHtml || renderDefaultNotFoundPage2({ url: url.pathname }));
64280
64826
  return;
64281
64827
  }
64282
64828
  const urlParts = url.pathname.split("/").filter(Boolean);
@@ -64575,7 +65121,7 @@ ${prettifyHtml(body)}
64575
65121
  }
64576
65122
  logRequest(404);
64577
65123
  res.writeHead(404, { "Content-Type": "text/html" });
64578
- res.end(notFoundHtml || "<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>");
65124
+ res.end(notFoundHtml || renderDefaultNotFoundPage2({ url: url.pathname }));
64579
65125
  } else {
64580
65126
  let devPayload = null;
64581
65127
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vesk/vesk-cli",
3
- "version": "0.2.60",
3
+ "version": "0.2.62",
4
4
  "type": "module",
5
5
  "description": "Vesk — compiler-first framework for the post-VDOM web. vesk dev, vesk build.",
6
6
  "bin": {
@@ -8,10 +8,10 @@
8
8
  },
9
9
  "main": "./dist/cli.js",
10
10
  "dependencies": {
11
- "@vesk/adapter": "^0.2.60",
12
- "@vesk/compiler": "^0.2.60",
13
- "@vesk/plugin-tailwind": "^0.2.60",
14
- "@vesk/runtime": "^0.2.60",
11
+ "@vesk/adapter": "^0.2.62",
12
+ "@vesk/compiler": "^0.2.62",
13
+ "@vesk/plugin-tailwind": "^0.2.62",
14
+ "@vesk/runtime": "^0.2.62",
15
15
  "esrap": "^2.3.0",
16
16
  "typescript": "^5.8.0",
17
17
  "ws": "^8.18.0",