@vesk/vesk-cli 0.2.58 → 0.2.60

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 +649 -50
  2. package/package.json +5 -5
package/dist/cli.js CHANGED
@@ -889,6 +889,9 @@ function block(flags, fn, state = null, co) {
889
889
  }
890
890
  if (active_block !== null) {
891
891
  push_block(newBlock, active_block);
892
+ } else {
893
+ newBlock.p = get_orphan_root();
894
+ push_block(newBlock, newBlock.p);
892
895
  }
893
896
  if ((flags & EFFECT_BLOCK) !== 0) {
894
897
  schedule_update(newBlock);
@@ -978,6 +981,7 @@ function is_destroyed(target_block) {
978
981
  }
979
982
  function destroy_block(block2, remove_dom = true) {
980
983
  block2.f ^= DESTROYED;
984
+ unsubscribe_reaction(block2);
981
985
  let removed = false;
982
986
  const f = block2.f;
983
987
  if (remove_dom && (f & (BRANCH_BLOCK | ROOT_BLOCK)) !== 0 && (f & TRY_BLOCK) === 0 || (f & HEAD_BLOCK) !== 0) {
@@ -1013,6 +1017,28 @@ var init_ripple_utils = __esm({
1013
1017
  });
1014
1018
 
1015
1019
  // ../runtime/src/ripple-runtime.ts
1020
+ function get_orphan_root() {
1021
+ if (orphan_root === null) {
1022
+ orphan_root = {
1023
+ co: null,
1024
+ d: null,
1025
+ first: null,
1026
+ f: ROOT_BLOCK,
1027
+ fn: null,
1028
+ last: null,
1029
+ next: null,
1030
+ p: null,
1031
+ prev: null,
1032
+ s: null,
1033
+ t: null,
1034
+ tc: null
1035
+ };
1036
+ }
1037
+ return orphan_root;
1038
+ }
1039
+ function is_orphan(block2) {
1040
+ return block2 === null || block2 === void 0 || block2 === orphan_root;
1041
+ }
1016
1042
  function increment_clock() {
1017
1043
  return ++clock;
1018
1044
  }
@@ -1138,6 +1164,7 @@ function run_block(block2) {
1138
1164
  try {
1139
1165
  active_block = block2;
1140
1166
  active_reaction = block2;
1167
+ unsubscribe_reaction(block2);
1141
1168
  active_component = block2.co;
1142
1169
  destroy_non_branch_children(block2);
1143
1170
  run_teardown(block2);
@@ -1167,10 +1194,10 @@ function run_block(block2) {
1167
1194
  }
1168
1195
  }
1169
1196
  function tracked(v, block2, get2, set2) {
1170
- return new TrackedValue(v, block2 || active_block, get2 || set2 ? { get: get2, set: set2 } : empty_get_set);
1197
+ return new TrackedValue(v, block2 || active_block || get_orphan_root(), get2 || set2 ? { get: get2, set: set2 } : empty_get_set);
1171
1198
  }
1172
1199
  function derived(fn, block2, get2, set2) {
1173
- return new DerivedValue(fn, block2 || active_block, get2 || set2 ? { get: get2, set: set2 } : empty_get_set);
1200
+ return new DerivedValue(fn, block2 || active_block || get_orphan_root(), get2 || set2 ? { get: get2, set: set2 } : empty_get_set);
1174
1201
  }
1175
1202
  function track(v, b, get2, set2) {
1176
1203
  if (is_ripple_object(v)) {
@@ -1193,6 +1220,9 @@ function track(v, b, get2, set2) {
1193
1220
  }
1194
1221
  function create_dependency(tracked2) {
1195
1222
  const reaction = active_reaction;
1223
+ if (is_orphan(tracked2.b)) {
1224
+ (tracked2.r ??= /* @__PURE__ */ new Set()).add(reaction);
1225
+ }
1196
1226
  const existing = reaction.d;
1197
1227
  if (existing !== null) {
1198
1228
  reaction.d = existing.n;
@@ -1367,6 +1397,7 @@ function queue_microtask(fn) {
1367
1397
  }
1368
1398
  function schedule_update(block2) {
1369
1399
  if (block2 === null) return;
1400
+ if (block2.p === get_orphan_root() && globalThis.__vsk_ssr) return;
1370
1401
  if (scheduler_mode === FLUSH_MICROTASK) {
1371
1402
  queue_microtask();
1372
1403
  }
@@ -1426,6 +1457,36 @@ function register_dependency(tracked2) {
1426
1457
  current2.n = dependency;
1427
1458
  }
1428
1459
  }
1460
+ function unsubscribe_reaction(reaction) {
1461
+ if (reaction === null) return;
1462
+ let dep = reaction.d;
1463
+ while (dep !== null) {
1464
+ const t = dep.t;
1465
+ if (is_orphan(t.b) && t.r !== null) {
1466
+ t.r.delete(reaction);
1467
+ }
1468
+ dep = dep.n;
1469
+ }
1470
+ }
1471
+ function schedule_ownerless_update(tracked2, visited) {
1472
+ const subscribers = tracked2.r;
1473
+ if (subscribers === null) return;
1474
+ for (const reaction of Array.from(subscribers)) {
1475
+ if (visited !== null) {
1476
+ if (visited.has(reaction)) continue;
1477
+ visited.add(reaction);
1478
+ }
1479
+ if (reaction.f & DESTROYED) {
1480
+ subscribers.delete(reaction);
1481
+ continue;
1482
+ }
1483
+ if ((reaction.f & DERIVED) !== 0) {
1484
+ schedule_ownerless_update(reaction, visited ?? /* @__PURE__ */ new Set());
1485
+ continue;
1486
+ }
1487
+ schedule_update(reaction);
1488
+ }
1489
+ }
1429
1490
  function get_derived(computed) {
1430
1491
  update_derived(computed);
1431
1492
  if (tracking) {
@@ -1493,7 +1554,11 @@ function set(tracked2, value) {
1493
1554
  }
1494
1555
  tracked2.__v = value;
1495
1556
  tracked2.c = increment_clock();
1496
- schedule_update(tracked_block);
1557
+ if (!is_orphan(tracked_block)) {
1558
+ schedule_update(tracked_block);
1559
+ } else {
1560
+ schedule_ownerless_update(tracked2, null);
1561
+ }
1497
1562
  }
1498
1563
  }
1499
1564
  function untrack2(fn) {
@@ -1590,7 +1655,7 @@ function pop_component() {
1590
1655
  }
1591
1656
  active_component = component.p;
1592
1657
  }
1593
- var FLUSH_MICROTASK, FLUSH_SYNC, active_block, active_reaction, active_scope, active_component, is_mutating_allowed, old_values, scheduler_mode, is_micro_task_queued, clock, queued_root_blocks, disable_scoped_flush, queued_microtasks, flush_count, queued_post_block_flush, active_dependency, tracking, teardown, empty_get_set, TrackedValue, DerivedValue;
1658
+ var FLUSH_MICROTASK, FLUSH_SYNC, active_block, active_reaction, active_scope, active_component, is_mutating_allowed, old_values, orphan_root, scheduler_mode, is_micro_task_queued, clock, queued_root_blocks, disable_scoped_flush, queued_microtasks, flush_count, queued_post_block_flush, active_dependency, tracking, teardown, empty_get_set, TrackedValue, DerivedValue;
1594
1659
  var init_ripple_runtime = __esm({
1595
1660
  "../runtime/src/ripple-runtime.ts"() {
1596
1661
  "use strict";
@@ -1605,6 +1670,7 @@ var init_ripple_runtime = __esm({
1605
1670
  active_component = null;
1606
1671
  is_mutating_allowed = true;
1607
1672
  old_values = /* @__PURE__ */ new Map();
1673
+ orphan_root = null;
1608
1674
  scheduler_mode = FLUSH_MICROTASK;
1609
1675
  is_micro_task_queued = false;
1610
1676
  clock = 0;
@@ -1623,6 +1689,7 @@ var init_ripple_runtime = __esm({
1623
1689
  c;
1624
1690
  d;
1625
1691
  f;
1692
+ r;
1626
1693
  __v;
1627
1694
  constructor(v, block2, a) {
1628
1695
  this.a = a;
@@ -1630,6 +1697,7 @@ var init_ripple_runtime = __esm({
1630
1697
  this.c = 0;
1631
1698
  this.d = null;
1632
1699
  this.f = TRACKED;
1700
+ this.r = null;
1633
1701
  this.__v = v;
1634
1702
  }
1635
1703
  get() {
@@ -1670,6 +1738,7 @@ var init_ripple_runtime = __esm({
1670
1738
  d;
1671
1739
  f;
1672
1740
  fn;
1741
+ r;
1673
1742
  __v;
1674
1743
  constructor(fn, block2, a) {
1675
1744
  this.a = a;
@@ -1680,6 +1749,7 @@ var init_ripple_runtime = __esm({
1680
1749
  this.d = null;
1681
1750
  this.f = DERIVED;
1682
1751
  this.fn = fn;
1752
+ this.r = null;
1683
1753
  this.__v = UNINITIALIZED;
1684
1754
  }
1685
1755
  get() {
@@ -3369,6 +3439,17 @@ ${String(this.root.outerHTML).slice(0, 800)}` : ""),
3369
3439
  // callee's first claim and resets the deposit so later claims stay
3370
3440
  // positional against the advancing cursor. Consumed synchronously on the
3371
3441
  // same walker reference the call was made through.
3442
+ //
3443
+ // The deposit is ALSO consumed implicitly by the next claim made through this
3444
+ // walker when the caller passed no explicit skipK. A component written in plain
3445
+ // JS (lucide-vesk icons are the common case) never calls `takeSkipK`, so
3446
+ // before this the deposit was silently dropped: the icon's `nextElement("svg")`
3447
+ // claimed the slot still holding the STATIC residue in front of it
3448
+ // (`<button><span>Apply Now</span><svg/></button>`), the descriptor missed on
3449
+ // `<span>`, and the walker detached server-rendered content that no client
3450
+ // program had any intention of replacing. Implicit consumption keeps static
3451
+ // residue out of the way for plain-JS components exactly as it is for
3452
+ // compiled ones.
3372
3453
  inheritOffset = 0;
3373
3454
  injectSkipK(n) {
3374
3455
  this.inheritOffset = n;
@@ -3382,7 +3463,11 @@ ${String(this.root.outerHTML).slice(0, 800)}` : ""),
3382
3463
  if (globalThis.__vesk_hydrate_debug) {
3383
3464
  console.error("[hyd-dbg] claimAt", tag, "skip=", skipK, "idx=", this.idx, "els=", this.els.length);
3384
3465
  }
3385
- let target = this.advancePastSkippable(this.idx + (skipK || 0));
3466
+ let offset2 = skipK || 0;
3467
+ const inherited = this.inheritOffset;
3468
+ this.inheritOffset = 0;
3469
+ if (!offset2) offset2 = inherited;
3470
+ let target = this.advancePastSkippable(this.idx + offset2);
3386
3471
  if (target > this.els.length) target = this.idx;
3387
3472
  while (target < this.els.length) {
3388
3473
  const el = this.els[target];
@@ -18305,6 +18390,20 @@ function tokenizeCode(code) {
18305
18390
  }
18306
18391
  });
18307
18392
  }
18393
+ function collectStringDelimiters(code, tokens) {
18394
+ const t = tokens == null ? tokenizeCode(code) : tokens;
18395
+ if (t === null) return null;
18396
+ const starts = /* @__PURE__ */ new Set();
18397
+ let ti = 0;
18398
+ for (let i = 0; i < code.length; i++) {
18399
+ const c = code.charCodeAt(i);
18400
+ if (c !== 34 && c !== 39 && c !== 96) continue;
18401
+ while (ti < t.length && t[ti].end <= i) ti++;
18402
+ const covered = ti < t.length && t[ti].start <= i;
18403
+ if (!covered || QUOTED_LABELS.has(t[ti].label)) starts.add(i);
18404
+ }
18405
+ return starts;
18406
+ }
18308
18407
  function containsIdentifier(code, name) {
18309
18408
  const tokens = tokenizeCode(code);
18310
18409
  if (tokens !== null) {
@@ -18496,33 +18595,33 @@ function manualExtractImportNames(importText) {
18496
18595
  }
18497
18596
  return names;
18498
18597
  }
18499
- function hasTopLevelValueDeclaration(code, name) {
18500
- const tokens = tokenizeCode(code);
18501
- if (tokens === null) return false;
18598
+ function hasTopLevelValueDeclaration(code, name, tokens) {
18599
+ const t = tokens == null ? tokenizeCode(code) : tokens;
18600
+ if (t === null) return false;
18502
18601
  const declWords = ["const", "let", "var", "function", "class"];
18503
- for (let i = 1; i < tokens.length; i++) {
18504
- if (tokens[i].label !== "name" || tokens[i].value !== name) continue;
18505
- const prev = tokens[i - 1];
18602
+ for (let i = 1; i < t.length; i++) {
18603
+ if (t[i].label !== "name" || t[i].value !== name) continue;
18604
+ const prev = t[i - 1];
18506
18605
  if (!prev || !declWords.includes(prev.value)) continue;
18507
18606
  if (i >= 2) {
18508
- const pp2 = tokens[i - 2];
18607
+ const pp2 = t[i - 2];
18509
18608
  if (pp2 && pp2.label === "name" && pp2.value === "export") continue;
18510
18609
  }
18511
18610
  return true;
18512
18611
  }
18513
18612
  return false;
18514
18613
  }
18515
- function findSpecifierExports(code) {
18516
- const tokens = tokenizeCode(code);
18517
- if (tokens === null) return [];
18614
+ function findSpecifierExports(code, tokens) {
18615
+ const t = tokens == null ? tokenizeCode(code) : tokens;
18616
+ if (t === null) return [];
18518
18617
  const out = [];
18519
- for (let i = 0; i < tokens.length; i++) {
18520
- if (tokens[i].label !== "export") continue;
18521
- if (!tokens[i + 1] || tokens[i + 1].label !== "{") continue;
18618
+ for (let i = 0; i < t.length; i++) {
18619
+ if (t[i].label !== "export") continue;
18620
+ if (!t[i + 1] || t[i + 1].label !== "{") continue;
18522
18621
  let k = i + 2;
18523
18622
  let depth = 1;
18524
- for (; k < tokens.length; k++) {
18525
- const lbl = tokens[k].label;
18623
+ for (; k < t.length; k++) {
18624
+ const lbl = t[k].label;
18526
18625
  if (lbl === "string") {
18527
18626
  continue;
18528
18627
  }
@@ -18533,8 +18632,8 @@ function findSpecifierExports(code) {
18533
18632
  }
18534
18633
  }
18535
18634
  let isReexport = false;
18536
- for (let j = k + 1; j < tokens.length; j++) {
18537
- const lbl = tokens[j].label;
18635
+ for (let j = k + 1; j < t.length; j++) {
18636
+ const lbl = t[j].label;
18538
18637
  if (lbl === "string") {
18539
18638
  isReexport = true;
18540
18639
  break;
@@ -18542,10 +18641,10 @@ function findSpecifierExports(code) {
18542
18641
  if (lbl === ";" || lbl === "export" || lbl === "import" || lbl === "}") break;
18543
18642
  }
18544
18643
  if (depth !== 0 || isReexport) continue;
18545
- const pairs = readSpecifierPairs(code, tokens[i + 1].end, tokens[k].end);
18644
+ const pairs = readSpecifierPairs(code, t[i + 1].end, t[k].end);
18546
18645
  if (pairs === null) continue;
18547
- const stmtEnd = tokens[k].end;
18548
- for (const [local, exported] of pairs) out.push({ local, exported, start: tokens[i].start, end: stmtEnd });
18646
+ const stmtEnd = t[k].end;
18647
+ for (const [local, exported] of pairs) out.push({ local, exported, start: t[i].start, end: stmtEnd });
18549
18648
  i = k;
18550
18649
  }
18551
18650
  return out;
@@ -18605,12 +18704,14 @@ function stripTrackDeclMarkers(text, base, node) {
18605
18704
  }
18606
18705
  return out + text.slice(prev);
18607
18706
  }
18707
+ var QUOTED_LABELS;
18608
18708
  var init_tokens = __esm({
18609
18709
  "../compiler/src/tokens.ts"() {
18610
18710
  "use strict";
18611
18711
  init_parser();
18612
18712
  init_vesk_plugin();
18613
18713
  init_scan();
18714
+ QUOTED_LABELS = /* @__PURE__ */ new Set(["string", "template", "`", "backQuote"]);
18614
18715
  }
18615
18716
  });
18616
18717
 
@@ -18634,7 +18735,7 @@ function offsetToLineCol(source, offset2) {
18634
18735
  }
18635
18736
  return { line, column };
18636
18737
  }
18637
- function preprocessForClauses(source) {
18738
+ function preprocessForClauses(source, delimiters) {
18638
18739
  const annotations = [];
18639
18740
  const chars = source.split("");
18640
18741
  const isString = (ch) => ch === '"' || ch === "'" || ch === "`";
@@ -18642,6 +18743,10 @@ function preprocessForClauses(source) {
18642
18743
  while (i < source.length) {
18643
18744
  const ch = source[i];
18644
18745
  if (isString(ch)) {
18746
+ if (delimiters && !delimiters.has(i)) {
18747
+ i++;
18748
+ continue;
18749
+ }
18645
18750
  const quote = ch;
18646
18751
  let j = i + 1;
18647
18752
  let tplDepth = 0;
@@ -18996,9 +19101,11 @@ function parseGeneratedJs(source) {
18996
19101
  }
18997
19102
  function parse4(source, options = {}) {
18998
19103
  const ParserClass = createBaseParser();
18999
- const { code, annotations } = preprocessForClauses(blankGenericArrowTypeParams(blankComments(source)));
19104
+ const sourceTokens = tokenizeCode(source);
19105
+ const delimiters = sourceTokens === null ? null : collectStringDelimiters(source, sourceTokens);
19106
+ const { code, annotations } = preprocessForClauses(blankGenericArrowTypeParams(blankComments(source)), delimiters);
19000
19107
  const vskSource = !options.filename || String(options.filename).endsWith(".vsk");
19001
- const specifierExports = vskSource ? findSpecifierExports(code).filter((e) => !hasTopLevelValueDeclaration(code, e.local)) : [];
19108
+ const specifierExports = vskSource && sourceTokens !== null ? findSpecifierExports(code, sourceTokens).filter((e) => !hasTopLevelValueDeclaration(code, e.local, sourceTokens)) : [];
19002
19109
  let parseable = code;
19003
19110
  if (specifierExports.length > 0) {
19004
19111
  const edits = specifierExports.map((e) => code.slice(e.start, e.end)).map((text) => text.split("").map((ch) => ch === "\n" ? "\n" : " ").join(""));
@@ -21909,6 +22016,7 @@ function warnStaleConstBindings(comp, file) {
21909
22016
  for (const d of st.declarations || []) {
21910
22017
  if (d.id?.type !== "Identifier" || !d.init) continue;
21911
22018
  if (reactive.has(d.id.name)) continue;
22019
+ if (d.init.type === "ArrowFunctionExpression" || d.init.type === "FunctionExpression") continue;
21912
22020
  if (d.init.type === "Identifier" && reactive.has(d.init.name)) continue;
21913
22021
  const seen = /* @__PURE__ */ new Set();
21914
22022
  collectIdentifiers(d.init, seen);
@@ -30383,8 +30491,13 @@ function emitNode(ctx2, node, tracked2, effectsVar, parentVar, compPrefix = "__c
30383
30491
  if (node instanceof SlotNode) {
30384
30492
  if (!parentVar) {
30385
30493
  if (ctx2.hydrate) {
30494
+ const promptExpr = ctx2.markerless && (regionBudget || skipK > 0) ? markerlessSkipExpr(regionBudget, skipK) : null;
30386
30495
  ctx2.push(`if (props.children !== undefined && props.children !== null) {`);
30387
30496
  ctx2.push(` if (typeof props.children === 'function') {`);
30497
+ if (promptExpr) {
30498
+ ctx2.push(` ${ctx2.walker}.injectSkipK(${promptExpr});`);
30499
+ if (regionBudget && ctx2.markerless) ctx2.push(` ${regionBudget} = 0;`);
30500
+ }
30388
30501
  ctx2.push(` __pendingChild = props.children(__hydrate);`);
30389
30502
  ctx2.push(` } else if (__hydrate && __hydrate.root) {`);
30390
30503
  ctx2.push(` __hydrate.root.appendChild(toDomNode(props.children));`);
@@ -30704,6 +30817,9 @@ function isReactiveExpression(node, tracked2) {
30704
30817
  if (!ast) return false;
30705
30818
  let reactive = false;
30706
30819
  walk4(ast, tracked2, {
30820
+ CallExpression() {
30821
+ reactive = true;
30822
+ },
30707
30823
  Identifier(n, context) {
30708
30824
  if (reactive) return;
30709
30825
  const parent = context.path.at(-1);
@@ -30831,7 +30947,7 @@ function emitComponentCall(ctx2, node, tracked2, effectsVar, parentVar, compPref
30831
30947
  ctx2.push(`return $f; })();`);
30832
30948
  propsEntries.push(`children: ${frag}`);
30833
30949
  }
30834
- if (ctx2.markerless && promptExpr && !plainTarget) {
30950
+ if (ctx2.markerless && promptExpr) {
30835
30951
  ctx2.push(`${walkerArg}.injectSkipK(${promptExpr});`);
30836
30952
  }
30837
30953
  ctx2.push(`let ${v} = undefined;`);
@@ -35775,6 +35891,20 @@ ${serverStoreLine}
35775
35891
  });
35776
35892
  }
35777
35893
 
35894
+ // Persisted-store pre-paint payload (buildStorePrePaintPayload) \u2014 same
35895
+ // token-stash/consume contract as /ssr-data.js, own store so neither handoff
35896
+ // can eat the other.
35897
+ if (pathname === '/store-init.js') {
35898
+ const initToken = url.searchParams.get('t') || '';
35899
+ const initStore = (globalThis.__vsk_store_init_payload_store || {});
35900
+ const initPayload = initStore[initToken];
35901
+ if (initPayload !== undefined) delete initStore[initToken];
35902
+ return new Response(initPayload ?? '// no store init', {
35903
+ status: 200,
35904
+ headers: { 'Content-Type': 'application/javascript', 'Cache-Control': 'no-store' },
35905
+ });
35906
+ }
35907
+
35778
35908
  ${eventsStartLine}
35779
35909
  let mwCtx = { params: {}, url, locals: ${localsSeed}, cookies: {}, request, resolveUrl(u) { return new URL(u, request.url).href; }, set() {}, get() { return undefined; } };
35780
35910
  if (${hasMwLiteral}) {
@@ -46674,7 +46804,7 @@ function offsetToLineCol3(source, offset2) {
46674
46804
  }
46675
46805
  return { line, column };
46676
46806
  }
46677
- function preprocessForClauses2(source) {
46807
+ function preprocessForClauses2(source, delimiters) {
46678
46808
  const annotations = [];
46679
46809
  const chars = source.split("");
46680
46810
  const isString = (ch) => ch === '"' || ch === "'" || ch === "`";
@@ -46682,6 +46812,10 @@ function preprocessForClauses2(source) {
46682
46812
  while (i < source.length) {
46683
46813
  const ch = source[i];
46684
46814
  if (isString(ch)) {
46815
+ if (delimiters && !delimiters.has(i)) {
46816
+ i++;
46817
+ continue;
46818
+ }
46685
46819
  const quote = ch;
46686
46820
  let j = i + 1;
46687
46821
  let tplDepth = 0;
@@ -47058,9 +47192,11 @@ function createBaseParser2() {
47058
47192
  }
47059
47193
  function parse5(source, options = {}) {
47060
47194
  const ParserClass = createBaseParser2();
47061
- const { code, annotations } = preprocessForClauses2(blankGenericArrowTypeParams2(blankComments(source)));
47195
+ const sourceTokens = tokenizeCode(source);
47196
+ const delimiters = sourceTokens === null ? null : collectStringDelimiters(source, sourceTokens);
47197
+ const { code, annotations } = preprocessForClauses2(blankGenericArrowTypeParams2(blankComments(source)), delimiters);
47062
47198
  const vskSource = !options.filename || String(options.filename).endsWith(".vsk");
47063
- const specifierExports = vskSource ? findSpecifierExports(code).filter((e) => !hasTopLevelValueDeclaration(code, e.local)) : [];
47199
+ const specifierExports = vskSource && sourceTokens !== null ? findSpecifierExports(code, sourceTokens).filter((e) => !hasTopLevelValueDeclaration(code, e.local, sourceTokens)) : [];
47064
47200
  let parseable = code;
47065
47201
  if (specifierExports.length > 0) {
47066
47202
  const edits = specifierExports.map((e) => code.slice(e.start, e.end)).map((text) => text.split("").map((ch) => ch === "\n" ? "\n" : " ").join(""));
@@ -48015,6 +48151,7 @@ async function bundleRuntime(appDir, outDir) {
48015
48151
  `import { renderPage, renderFullPage, renderPageStream, compileFile, setRuntimeModule, setVskHydrate, hydratePrecompile, assertSameOrigin, withSsrStore } from ${JSON.stringify(resolve3(compilerRoot, "server-codegen.js"))};`,
48016
48152
  `import { parseCookies } from ${JSON.stringify(resolve3(compilerRoot, "server-cookies.js"))};`,
48017
48153
  `import * as __veskRuntime from ${JSON.stringify(resolve3(runtimeRoot, "index-server.js"))};`,
48154
+ `import * as __persistence from ${JSON.stringify(resolve3(runtimeRoot, "store-persistence.js"))};`,
48018
48155
  "",
48019
48156
  "// Inject runtime module so server-codegen can find components like NavLink, Link, etc.",
48020
48157
  "setRuntimeModule(__veskRuntime);",
@@ -48080,6 +48217,40 @@ async function bundleRuntime(appDir, outDir) {
48080
48217
  " return '/ssr-data.js?t=' + token;",
48081
48218
  "}",
48082
48219
  "",
48220
+ "// Persisted-store SSR continuity. `installPersistedStoreServerHooks` installs the",
48221
+ "// adapter-side read hook; `get/getReset` handle the per-request key registry",
48222
+ "// the server drains into the pre-paint payload. The init payload is delivered",
48223
+ "// as an origin-served script (/store-init.js?t=...) exactly like /ssr-data.js",
48224
+ "// so strict CSP (no unsafe-inline) cannot block it; it is never inlined.",
48225
+ "export const installPersistedStoreServerHooks = __persistence.installPersistedStoreServerHooks;",
48226
+ "export const persistedStoreCookieName = __persistence.persistedStoreCookieName;",
48227
+ "export const getPersistedStoreKeys = __persistence.getPersistedStoreKeys;",
48228
+ "export const resetPersistedStoreKeys = __persistence.resetPersistedStoreKeys;",
48229
+ "export const buildStorePrePaintPayload = __persistence.buildStorePrePaintPayload;",
48230
+ "export const storeInitScriptTag = __persistence.storeInitScriptTag;",
48231
+ "",
48232
+ "// Stash the pre-paint payload under a CSPRNG token and return the origin URL",
48233
+ "// the blocking <head> script points at. Own token store (NOT __vsk_ssr_payload_store)",
48234
+ "// so consuming the page hydration handoff never eats the store-init payload",
48235
+ "// and vice versa. Same 100-entry bound as /ssr-data.js.",
48236
+ "export function storeInitScriptGlobal(payload) {",
48237
+ " if (!payload) return null;",
48238
+ " const bytes = new Uint8Array(12);",
48239
+ " crypto.getRandomValues(bytes);",
48240
+ " let tk = '';",
48241
+ " for (const b of bytes) tk += b.toString(16).padStart(2, '0');",
48242
+ " const token = tk;",
48243
+ " const store = (globalThis.__vsk_store_init_payload_store ||= {});",
48244
+ " store[token] = payload;",
48245
+ " const keys = Object.keys(store);",
48246
+ " if (keys.length > 100) {",
48247
+ " for (let i = 0; i < keys.length - 100; i++) {",
48248
+ " delete store[keys[i]];",
48249
+ " }",
48250
+ " }",
48251
+ " return '/store-init.js?t=' + token;",
48252
+ "}",
48253
+ "",
48083
48254
  "// Re-export runtime classes used by API routes",
48084
48255
  "export const VeskRequest = __veskRuntime.VeskRequest;",
48085
48256
  "export const PayloadTooLargeError = __veskRuntime.PayloadTooLargeError;",
@@ -48390,6 +48561,51 @@ function buildParamExtraction(node, urlParts) {
48390
48561
  walk9(node);
48391
48562
  return parts;
48392
48563
  }
48564
+ function persistedStoreSsrCode() {
48565
+ return [
48566
+ "// \u2500\u2500 Persisted-store SSR continuity (createStore / createPathStore persist) \u2500\u2500",
48567
+ "// Reads a persisted store's cookie value through the adapter request context.",
48568
+ "// Client writes mirror URL-encoded; decode on the way back (best effort).",
48569
+ "function __persistRead(key) {",
48570
+ " const cookieName = persistedStoreCookieName(key);",
48571
+ " const req = globalThis.__vesk_request;",
48572
+ " if (!req) return null;",
48573
+ " const c = req.cookies || {};",
48574
+ " const v = typeof c.get === 'function' ? c.get(cookieName) : c[cookieName];",
48575
+ " if (v == null) return null;",
48576
+ " try { return decodeURIComponent(String(v)); } catch { return String(v); }",
48577
+ "}",
48578
+ "",
48579
+ "// Drain this request's registered persisted keys into a served pre-paint",
48580
+ "// script (/store-init.js?t=...) then forget them. `token` selects the",
48581
+ "// render's bucket for callers outside the ALS scope (the no-layout stream",
48582
+ "// path captures its token at the renderPageStream call site); the layout",
48583
+ "// path runs this inside the scope and relies on the ambient token.",
48584
+ "function __storeInitTag(token) {",
48585
+ " const keys = getPersistedStoreKeys(token);",
48586
+ " if (keys.length === 0) { resetPersistedStoreKeys(token); return ''; }",
48587
+ " const values = {};",
48588
+ " for (let __i = 0; __i < keys.length; __i++) values[keys[__i]] = __persistRead(keys[__i]);",
48589
+ " resetPersistedStoreKeys(token);",
48590
+ " const payload = buildStorePrePaintPayload(values);",
48591
+ " const url = storeInitScriptGlobal(payload);",
48592
+ " return url ? storeInitScriptTag(url) : '';",
48593
+ "}",
48594
+ "",
48595
+ "// Inject the blocking store-init <script src> into a full HTML string",
48596
+ "// (before </head>; append if the document has no head).",
48597
+ "function __injectStoreInit(html) {",
48598
+ " const tag = __storeInitTag();",
48599
+ " if (tag === '') return html;",
48600
+ " const idx = html.lastIndexOf('</head>');",
48601
+ " if (idx === -1) return html + tag;",
48602
+ " return html.slice(0, idx) + tag + html.slice(idx);",
48603
+ "}",
48604
+ "",
48605
+ "installPersistedStoreServerHooks({ read: __persistRead });",
48606
+ ""
48607
+ ].join("\n");
48608
+ }
48393
48609
  function generateSsrFunction(routeNode, appDir, outDir, componentMap, options) {
48394
48610
  const ancestorLayouts = options?.ancestorLayouts || [];
48395
48611
  const middlewareCode = options?.middlewareCode || null;
@@ -48491,6 +48707,7 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
48491
48707
  "",
48492
48708
  "async function __renderHtml(params, requestUrl) {",
48493
48709
  " return withSsrStore(async () => {",
48710
+ " resetPersistedStoreKeys();",
48494
48711
  " let page;",
48495
48712
  " let caughtError = null;",
48496
48713
  " const __expose = process.env.NODE_ENV !== 'production';",
@@ -48511,7 +48728,7 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
48511
48728
  " if (_inner.head) _head = _inner.head + _head;",
48512
48729
  " }",
48513
48730
  " const html = await renderFullPage('', _layoutCompList[0], { params, children: _body }, __componentRegistry, { hydrate: true, cached: _layoutCompiledList[0]" + bakedOptions + clientScriptOption + dataScriptOption + ", pageHead: _head });",
48514
- " return new Response(html, { headers: { 'Content-Type': 'text/html' }, status: caughtError ? 500 : 200 });",
48731
+ " return new Response(__injectStoreInit(html), { headers: { 'Content-Type': 'text/html' }, status: caughtError ? 500 : 200 });",
48515
48732
  " });",
48516
48733
  "}",
48517
48734
  ""
@@ -48530,25 +48747,48 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
48530
48747
  "async function __renderHtml(params, requestUrl) {",
48531
48748
  " return withSsrStore(async () => {",
48532
48749
  " let stream;",
48750
+ // The streamed no-layout page emits its <head> before the component body
48751
+ // renders, so its persisted stores don't exist yet when the head is
48752
+ // flushed — the pre-paint tag therefore goes into the final chunk, right
48753
+ // before </body> (still a blocking, pre-paint script). Capture the render
48754
+ // token now (renderPageStream adopts this exact ambient store) so the
48755
+ // registry drain in the consumer's start() can hit the right bucket even
48756
+ // though it runs outside the ALS scope.
48757
+ " const __streamToken = globalThis.__vsk_ssr_token || '';",
48533
48758
  " try {",
48534
48759
  " stream = renderPageStream('', _comp, { params }, __componentRegistry, { hydrate: true, cached: _compiled" + bakedOptions + clientScriptOption + dataScriptOption + " });",
48535
48760
  " } catch (err) {",
48536
48761
  " if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
48537
48762
  " const html = await __renderErrorFullPage(params, requestUrl, err);",
48538
- " return new Response(html, { headers: { 'Content-Type': 'text/html' }, status: 500 });",
48763
+ " return new Response(__injectStoreInit(html), { headers: { 'Content-Type': 'text/html' }, status: 500 });",
48539
48764
  " }",
48540
48765
  " return new Response(new ReadableStream({",
48541
48766
  " async start(controller) {",
48542
48767
  " const enc = new TextEncoder();",
48768
+ " let __tail = null;",
48769
+ " resetPersistedStoreKeys(__streamToken);",
48543
48770
  " try {",
48544
48771
  " for await (const chunk of stream) {",
48545
- " controller.enqueue(enc.encode(chunk));",
48772
+ " if (__tail !== null) controller.enqueue(enc.encode(__tail));",
48773
+ " __tail = chunk;",
48774
+ " }",
48775
+ " if (__tail !== null) {",
48776
+ " const __tag = __storeInitTag(__streamToken);",
48777
+ " if (__tag !== '') {",
48778
+ " const __bi = __tail.lastIndexOf('</body>');",
48779
+ " __tail = __bi === -1 ? __tail + __tag : __tail.slice(0, __bi) + __tag + __tail.slice(__bi);",
48780
+ " }",
48781
+ " controller.enqueue(enc.encode(__tail));",
48782
+ " } else {",
48783
+ " // Empty stream (no chunks) \u2014 nothing to attach the tag to; just",
48784
+ " // clear the registry so a later render can't inherit these keys.",
48785
+ " resetPersistedStoreKeys(__streamToken);",
48546
48786
  " }",
48547
48787
  " } catch (err) {",
48548
48788
  " if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
48549
48789
  " try {",
48550
48790
  " const html = await __renderErrorFullPage(params, requestUrl, err);",
48551
- " controller.enqueue(enc.encode(html));",
48791
+ " controller.enqueue(enc.encode(__injectStoreInit(html)));",
48552
48792
  " } catch {}",
48553
48793
  " }",
48554
48794
  " controller.close();",
@@ -48559,6 +48799,7 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
48559
48799
  ""
48560
48800
  ].join("\n");
48561
48801
  }
48802
+ const persistCode = persistedStoreSsrCode();
48562
48803
  let dataCode;
48563
48804
  const exposeErr = "process.env.NODE_ENV !== 'production'";
48564
48805
  const dataNavCleanup = [
@@ -48572,6 +48813,9 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
48572
48813
  // process-global token — the cross-request data-slot race, for good. The
48573
48814
  // token dies with the withSsrStore scope wrapped around this block instead.
48574
48815
  " delete globalThis.__vsk_ssr_data;",
48816
+ // SPA data-nav only runs renderPage, so the persisted-store registration
48817
+ // bucket would otherwise keep this request's keys forever.
48818
+ " resetPersistedStoreKeys();",
48575
48819
  " }"
48576
48820
  ];
48577
48821
  const dataNavWrap = (body) => [
@@ -48756,7 +49000,7 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
48756
49000
  ""
48757
49001
  ].join("\n");
48758
49002
  const funcCode = [
48759
- "import { renderFullPage, renderPageStream, renderPage, hydratePrecompile, parseCookies, getAction, validateActionInput, issuesToFieldMap, storeDataScriptGlobal, withSsrStore, assertSameOrigin, VeskRequest } from '../runtime.js';",
49003
+ "import { renderFullPage, renderPageStream, renderPage, hydratePrecompile, parseCookies, getAction, validateActionInput, issuesToFieldMap, storeDataScriptGlobal, withSsrStore, assertSameOrigin, VeskRequest, installPersistedStoreServerHooks, persistedStoreCookieName, getPersistedStoreKeys, resetPersistedStoreKeys, buildStorePrePaintPayload, storeInitScriptGlobal, storeInitScriptTag } from '../runtime.js';",
48760
49004
  "",
48761
49005
  middlewareCode || "",
48762
49006
  registryCode,
@@ -48765,6 +49009,8 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
48765
49009
  paramsCode,
48766
49010
  htmlFnCode,
48767
49011
  "",
49012
+ persistCode,
49013
+ "",
48768
49014
  "export async function handle(request) {",
48769
49015
  " const url = new URL(request.url);",
48770
49016
  " const params = __paramsFor(url.pathname);",
@@ -49528,6 +49774,34 @@ function demoteExports(code) {
49528
49774
  function chunkHasImports(headLen, mergeAborted) {
49529
49775
  return headLen > 0 || mergeAborted;
49530
49776
  }
49777
+ function runtimeImportsOf(filePath) {
49778
+ let text;
49779
+ try {
49780
+ text = readFileSync11(filePath, "utf8");
49781
+ } catch {
49782
+ return [];
49783
+ }
49784
+ const names = [];
49785
+ const pattern2 = /import\s+(type\s+)?\{([^}]*)\}\s*from\s*['"]@vesk\/runtime[^'"]*['"]/g;
49786
+ for (const match of text.matchAll(pattern2)) {
49787
+ if (match[1]) continue;
49788
+ for (const part of match[2].split(",")) {
49789
+ const cleaned = part.trim().replace(/^type\s+/, "");
49790
+ if (!cleaned) continue;
49791
+ const name = cleaned.split(/\s+as\s+/)[0].trim();
49792
+ if (name) names.push(name);
49793
+ }
49794
+ }
49795
+ return names;
49796
+ }
49797
+ function sharedRuntimeResolver(shimPath) {
49798
+ return {
49799
+ name: "vesk-shared-runtime",
49800
+ setup(build4) {
49801
+ build4.onResolve({ filter: /^@vesk\/runtime(\/.*)?$/ }, () => ({ path: shimPath }));
49802
+ }
49803
+ };
49804
+ }
49531
49805
  var ChunkImports = class {
49532
49806
  bySource = /* @__PURE__ */ new Map();
49533
49807
  aborted = false;
@@ -49625,6 +49899,20 @@ var ChunkImports = class {
49625
49899
  get reason() {
49626
49900
  return this.abortReason;
49627
49901
  }
49902
+ /** Every import source this chunk's merged block pulls in (absolute paths). */
49903
+ sources() {
49904
+ return this.aborted ? [] : [...this.bySource.keys()];
49905
+ }
49906
+ /**
49907
+ * The named bindings this chunk imports from `source`, so a shared-module
49908
+ * shim can re-export exactly what consumers use (re-exporting `*` from the
49909
+ * real module would drag it back into the chunk being built).
49910
+ */
49911
+ bindingsFor(source) {
49912
+ const group = this.bySource.get(source);
49913
+ if (!group) return { named: [], hasDefault: false };
49914
+ return { named: [...group.named.keys()].sort(), hasDefault: !!group.default };
49915
+ }
49628
49916
  /** Renders the deduped import block (empty string when there are no imports). */
49629
49917
  render() {
49630
49918
  if (this.aborted || this.bySource.size === 0) return "";
@@ -49760,6 +50048,7 @@ async function generateClientBundle(routeTree, appDir, componentMap, options) {
49760
50048
  let cachedFileHits = 0;
49761
50049
  let compiledFiles = 0;
49762
50050
  let mainFromCache = false;
50051
+ let sharedModuleBundle = "";
49763
50052
  function mustReuseWithoutStat(filePath) {
49764
50053
  return !!only && !only.has(filePath);
49765
50054
  }
@@ -49945,7 +50234,7 @@ async function generateClientBundle(routeTree, appDir, componentMap, options) {
49945
50234
  if (!chunkImports.ok) console.error("[vesk] chunk import merge aborted for", chunkName + ":", chunkImports.reason);
49946
50235
  const head = chunkImports.render();
49947
50236
  const code = (head ? head + "\n\n" : "") + chunkCode.join("\n\n");
49948
- chunkEntries.push({ name: chunkName, code, node, imports: chunkHasImports(head.length, !chunkImports.ok) });
50237
+ chunkEntries.push({ name: chunkName, code, node, importsTable: chunkImports, imports: chunkHasImports(head.length, !chunkImports.ok) });
49949
50238
  }
49950
50239
  walkSplit2(node.children || [], [..._chain, node]);
49951
50240
  }
@@ -49974,7 +50263,7 @@ async function generateClientBundle(routeTree, appDir, componentMap, options) {
49974
50263
  if (!sharedImports.ok) console.error("[vesk] chunk import merge aborted for shared.js:", sharedImports.reason);
49975
50264
  const head = sharedImports.render();
49976
50265
  const code = (head ? head + "\n\n" : "") + sharedCode.join("\n\n");
49977
- chunkEntries.push({ name: "shared.js", code, node: null, imports: chunkHasImports(head.length, !sharedImports.ok) });
50266
+ chunkEntries.push({ name: "shared.js", code, node: null, importsTable: sharedImports, imports: chunkHasImports(head.length, !sharedImports.ok) });
49978
50267
  }
49979
50268
  const chunkIIFE = (body) => `(()=>{
49980
50269
  const __components = globalThis.__components || (globalThis.__components = {});
@@ -49982,6 +50271,98 @@ const __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});
49982
50271
  ${body}
49983
50272
  })();
49984
50273
  `;
50274
+ const sharedUsage = /* @__PURE__ */ new Map();
50275
+ for (const entry of chunkEntries) {
50276
+ for (const source of new Set(entry.importsTable.sources())) {
50277
+ sharedUsage.set(source, (sharedUsage.get(source) ?? 0) + 1);
50278
+ }
50279
+ }
50280
+ const isAppLocal = (source) => !source.includes("node_modules") && source.startsWith(resolve10(appDir, ".."));
50281
+ const sharedSources = [...sharedUsage.entries()].filter(([source, uses]) => uses > 1 && isAppLocal(source)).map(([source]) => source);
50282
+ if (process.env.VESK_DEBUG_SHARED) {
50283
+ console.error("[shared] candidates:", [...sharedUsage.entries()].map(([s, n]) => `${n}x ${s}`).join("\n"));
50284
+ console.error("[shared] selected:", sharedSources.join(", "));
50285
+ }
50286
+ const chunkAlias = {};
50287
+ let sharedBundleCode = "";
50288
+ const sharedRuntimeNames = /* @__PURE__ */ new Set();
50289
+ if (sharedSources.length > 0) {
50290
+ const tmpBase = mkdtempSync(join7(resolve10(appDir, ".."), "tmp-vesk-shared-"));
50291
+ try {
50292
+ const sharedEntry = join7(tmpBase, "shared-entry.js");
50293
+ const lines = [];
50294
+ const members = [];
50295
+ sharedSources.forEach((source, i) => {
50296
+ lines.push(`import * as m${i} from ${JSON.stringify(source)};`);
50297
+ members.push(` ${JSON.stringify(source)}: m${i},`);
50298
+ });
50299
+ lines.push(`globalThis.__veskShared = { ${members.join("\n")} };`);
50300
+ writeFileSync4(sharedEntry, lines.join("\n"));
50301
+ const appTsconfig = findTsconfigPath(appDir);
50302
+ const runtimeShim = join7(tmpBase, "runtime-shim.js");
50303
+ const runtimeLines = [
50304
+ "// ONE runtime instance: the entry bundle publishes these on globalThis,",
50305
+ "// and route chunks import the same functions. A second bundled copy",
50306
+ "// would mean a second Cell class and a second currentEffect.",
50307
+ "const __r = (n) => (...args) => globalThis[n](...args);"
50308
+ ];
50309
+ for (const source of sharedSources) {
50310
+ for (const name of runtimeImportsOf(source)) sharedRuntimeNames.add(name);
50311
+ }
50312
+ for (const name of [...sharedRuntimeNames].sort()) {
50313
+ runtimeLines.push(`export const ${name} = __r(${JSON.stringify(name)});`);
50314
+ }
50315
+ writeFileSync4(runtimeShim, runtimeLines.join("\n") + "\n");
50316
+ const result = await build({
50317
+ entryPoints: [sharedEntry],
50318
+ bundle: true,
50319
+ format: "iife",
50320
+ platform: "browser",
50321
+ write: false,
50322
+ logLevel: "silent",
50323
+ loader: { ".js": "tsx" },
50324
+ legalComments: "none",
50325
+ // `@vesk/runtime` MUST stay the entry bundle's instance. Bundling a
50326
+ // second copy in here gives the app a second `Cell` class and a
50327
+ // second `currentEffect` variable: a store cell written from a click
50328
+ // notifies subscribers registered against the OTHER copy, so nothing
50329
+ // the store drives ever updates — writes land, no error, no repaint.
50330
+ plugins: [sharedRuntimeResolver(runtimeShim)],
50331
+ ...appTsconfig ? { tsconfig: appTsconfig } : {}
50332
+ });
50333
+ sharedBundleCode = result.outputFiles[0].text;
50334
+ sharedSources.forEach((source, i) => {
50335
+ const named = /* @__PURE__ */ new Set();
50336
+ let hasDefault = false;
50337
+ for (const entry of chunkEntries) {
50338
+ const bindings = entry.importsTable.bindingsFor(source);
50339
+ bindings.named.forEach((n) => named.add(n));
50340
+ hasDefault = hasDefault || bindings.hasDefault;
50341
+ }
50342
+ const shim = join7(tmpBase, `shim-${i}.js`);
50343
+ const shimLines = [`const m = globalThis.__veskShared[${JSON.stringify(source)}];`];
50344
+ if (hasDefault) shimLines.push(`export default m;`);
50345
+ for (const name of [...named].sort()) {
50346
+ shimLines.push(`export const ${name} = m[${JSON.stringify(name)}];`);
50347
+ }
50348
+ writeFileSync4(shim, shimLines.join("\n") + "\n");
50349
+ chunkAlias[source] = shim;
50350
+ });
50351
+ } catch (e) {
50352
+ console.error("[vesk] shared-module pass failed; falling back to per-chunk inlining:", e.message);
50353
+ sharedBundleCode = "";
50354
+ for (const key of Object.keys(chunkAlias)) delete chunkAlias[key];
50355
+ }
50356
+ }
50357
+ const sharedRedirectPlugin = Object.keys(chunkAlias).length > 0 ? {
50358
+ name: "vesk-shared-modules",
50359
+ setup(build4) {
50360
+ build4.onResolve({ filter: /.*/ }, (args2) => {
50361
+ const mapped = chunkAlias[args2.path];
50362
+ return mapped ? { path: mapped } : null;
50363
+ });
50364
+ }
50365
+ } : null;
49985
50366
  for (const entry of chunkEntries) {
49986
50367
  if (!entry.code.trim()) continue;
49987
50368
  let finalCode;
@@ -50010,6 +50391,13 @@ ${entry.code}
50010
50391
  // for a dependency stays in its own package; shipping every
50011
50392
  // module's header inside our own chunk adds nothing.
50012
50393
  legalComments: "none",
50394
+ // Shared app modules are NOT inlined here: the resolver below
50395
+ // redirects them to a generated shim reading
50396
+ // `globalThis.__veskShared`, so the single copy in
50397
+ // shared-modules.js serves every route chunk. (esbuild's `alias`
50398
+ // option only accepts bare package names, so this is a resolver
50399
+ // rather than a map.)
50400
+ ...sharedRedirectPlugin ? { plugins: [sharedRedirectPlugin] } : {},
50013
50401
  ...appTsconfig ? { tsconfig: appTsconfig } : {}
50014
50402
  });
50015
50403
  finalCode = result.outputFiles[0].text;
@@ -50037,13 +50425,15 @@ ${entry.code}
50037
50425
  chunks.push({ name: entry.name, code: finalCode });
50038
50426
  }
50039
50427
  annotate2(routeTree);
50040
- const mainKey = JSON.stringify(routeTree) + "|" + [...runtimeImportNames].sort().join(",") + `|${!!options?.hmr}|${!!options?.importRuntime}|${options?.routeDataCache ?? ""}`;
50428
+ sharedModuleBundle = sharedBundleCode;
50429
+ for (const name of sharedRuntimeNames) runtimeImportNames.add(name);
50430
+ const mainKey = JSON.stringify(routeTree) + "|" + [...runtimeImportNames].sort().join(",") + `|${!!options?.hmr}|${!!options?.importRuntime}|${options?.routeDataCache ?? ""}|${sharedModuleBundle.length}`;
50041
50431
  let main;
50042
50432
  if (cache2?.mainBundle && cache2.mainBundle.key === mainKey) {
50043
50433
  mainFromCache = true;
50044
50434
  main = cache2.mainBundle.code;
50045
50435
  } else {
50046
- main = await buildMainBundle(routeTree, runtimeDir, true, {}, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache);
50436
+ main = await buildMainBundle(routeTree, runtimeDir, true, {}, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache, sharedModuleBundle);
50047
50437
  if (cache2) cache2.mainBundle = { key: mainKey, code: main };
50048
50438
  }
50049
50439
  const transformedChunks = [];
@@ -50244,7 +50634,7 @@ export { ${unique.join(", ")} };
50244
50634
  function appendHmrGlobals(code) {
50245
50635
  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";
50246
50636
  }
50247
- async function buildMainBundle(routeTree, runtimeDir, codeSplit, mono, hmr, importRuntime, runtimeImportNames, routeDataCache) {
50637
+ async function buildMainBundle(routeTree, runtimeDir, codeSplit, mono, hmr, importRuntime, runtimeImportNames, routeDataCache, sharedModuleBundle = "") {
50248
50638
  const baseRuntimeImports = ["createFileRouter", "get", "set", "effect", "track", "destroy_block", "getActiveComponent", "setActiveComponent", "NavLink", "Link", "reactiveProps", "matchRoute", "ensureChunk", "toDomNode", "rerenderNode"];
50249
50639
  const allRuntimeImports = runtimeImportNames && runtimeImportNames.size > 0 ? [.../* @__PURE__ */ new Set([...baseRuntimeImports, ...runtimeImportNames])] : baseRuntimeImports;
50250
50640
  const runtimeGlobals = [
@@ -50313,7 +50703,11 @@ if (__pendChunks.length > 0 && typeof ensureChunk === 'function') {
50313
50703
  `).join("") + "globalThis.__runtime_comps = __runtime_comps;\nglobalThis.__cleanup = __cleanup;\nglobalThis.__place = __place;\n\n";
50314
50704
  const extraGlobals = [...runtimeImportNames || []].filter((n) => n && n !== "default").map((n) => `globalThis.${n} = ${n};
50315
50705
  `).join("");
50316
- const code2 = preamble + "const __components = globalThis.__components || (globalThis.__components = {});\nconst __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});\nconst __runtime_comps = __components;\n\n" + runtimeGlobals2 + extraGlobals + cleanupFn + placeFn + "globalThis.__components = __components;\n" + resolveNamesFn + updateComponentsFn + "const __routeTree = " + routeTreeJson + ";\n__resolveNames(__routeTree);\n" + pendCode + startRouterCode;
50706
+ const code2 = preamble + "const __components = globalThis.__components || (globalThis.__components = {});\nconst __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});\nconst __runtime_comps = __components;\n\n" + runtimeGlobals2 + extraGlobals + // Shared app modules run HERE: after the runtime bindings are published,
50707
+ // before anything can request a route chunk. Earlier (at the top of the
50708
+ // bundle) `globalThis.track` was still undefined, so every module-scope
50709
+ // cell in a store was created against a missing runtime.
50710
+ (sharedModuleBundle ? sharedModuleBundle + "\n" : "") + cleanupFn + placeFn + "globalThis.__components = __components;\n" + resolveNamesFn + updateComponentsFn + "const __routeTree = " + routeTreeJson + ";\n__resolveNames(__routeTree);\n" + pendCode + startRouterCode;
50317
50711
  return hmr ? appendHmrGlobals(code2) : code2;
50318
50712
  }
50319
50713
  const componentLines = mono?.componentLines || [];
@@ -50751,6 +51145,15 @@ async function startProdServer(outDir, options) {
50751
51145
  res.end(lines.join("\n") || "// no ssr data");
50752
51146
  return;
50753
51147
  }
51148
+ if (url.pathname === "/store-init.js") {
51149
+ const token = url.searchParams.get("t") || "";
51150
+ const store = globalThis.__vsk_store_init_payload_store;
51151
+ const payload = store?.[token];
51152
+ if (payload) delete store[token];
51153
+ res.writeHead(200, { "Content-Type": "application/javascript", "Cache-Control": "no-store" });
51154
+ res.end(payload ?? "// no store init");
51155
+ return;
51156
+ }
50754
51157
  if (url.pathname === "/_vesk/runtime.js") {
50755
51158
  const clientFile = buildConfig?.assets?.client?.file || "client.js";
50756
51159
  const clientPath = resolve13(staticDir, clientFile);
@@ -51057,6 +51460,29 @@ async function resolveCompilerApi(name) {
51057
51460
  }
51058
51461
  return import(`@vesk/compiler/src/${name.replace(/\.js$/, "")}`);
51059
51462
  }
51463
+ function findRouteConflicts(routeTree, appDir) {
51464
+ const projectRoot = resolve21(appDir, "..");
51465
+ const byPath = /* @__PURE__ */ new Map();
51466
+ const walk9 = (nodes) => {
51467
+ for (const node of nodes) {
51468
+ if (node.page) {
51469
+ const pageFile = join15(node.sourceDir, "page.vsk");
51470
+ const files = byPath.get(node.fullPath) ?? [];
51471
+ files.push(relative4(projectRoot, pageFile));
51472
+ byPath.set(node.fullPath, files);
51473
+ }
51474
+ if (node.children && node.children.length > 0)
51475
+ walk9(node.children);
51476
+ }
51477
+ };
51478
+ walk9(routeTree);
51479
+ const conflicts = [];
51480
+ for (const [fullPath, files] of byPath) {
51481
+ if (files.length > 1)
51482
+ conflicts.push({ fullPath, files });
51483
+ }
51484
+ return conflicts;
51485
+ }
51060
51486
  function filterActivePlugins2(plugins, records) {
51061
51487
  if (!records || records.length === 0)
51062
51488
  return plugins;
@@ -51190,6 +51616,14 @@ async function build2(appDir, options) {
51190
51616
  console.error("vesk build: no routes found in", appDir);
51191
51617
  return;
51192
51618
  }
51619
+ const routeConflicts = findRouteConflicts(routeTree, appDir);
51620
+ if (routeConflicts.length > 0) {
51621
+ for (const conflict of routeConflicts) {
51622
+ console.error(`vesk build: conflicting routes for ${conflict.fullPath}: ${conflict.files.join(", ")}`);
51623
+ }
51624
+ const first = routeConflicts[0];
51625
+ throw new Error(`conflicting routes: ${first.fullPath} is claimed by both ${first.files.join(" and ")}`);
51626
+ }
51193
51627
  const projectRoot = resolve21(appDir, "..");
51194
51628
  const componentsDir = resolve21(projectRoot, "components");
51195
51629
  const componentMap = scanComponents2(componentsDir);
@@ -52200,8 +52634,14 @@ function emitNode2(ctx2, node, tracked2, effectsVar, parentVar, compPrefix = "__
52200
52634
  if (node instanceof SlotNode) {
52201
52635
  if (!parentVar) {
52202
52636
  if (ctx2.hydrate) {
52637
+ const promptExpr = ctx2.markerless && (regionBudget || skipK > 0) ? markerlessSkipExpr2(regionBudget, skipK) : null;
52203
52638
  ctx2.push(`if (props.children !== undefined && props.children !== null) {`);
52204
52639
  ctx2.push(` if (typeof props.children === 'function') {`);
52640
+ if (promptExpr) {
52641
+ ctx2.push(` ${ctx2.walker}.injectSkipK(${promptExpr});`);
52642
+ if (regionBudget && ctx2.markerless)
52643
+ ctx2.push(` ${regionBudget} = 0;`);
52644
+ }
52205
52645
  ctx2.push(` __pendingChild = props.children(__hydrate);`);
52206
52646
  ctx2.push(` } else if (__hydrate && __hydrate.root) {`);
52207
52647
  ctx2.push(` __hydrate.root.appendChild(toDomNode(props.children));`);
@@ -52568,6 +53008,9 @@ function isReactiveExpression2(node, tracked2) {
52568
53008
  return false;
52569
53009
  let reactive = false;
52570
53010
  walk7(ast, tracked2, {
53011
+ CallExpression() {
53012
+ reactive = true;
53013
+ },
52571
53014
  Identifier(n, context) {
52572
53015
  if (reactive)
52573
53016
  return;
@@ -52713,7 +53156,7 @@ function emitComponentCall2(ctx2, node, tracked2, effectsVar, parentVar, compPre
52713
53156
  ctx2.push(`return $f; })();`);
52714
53157
  propsEntries.push(`children: ${frag}`);
52715
53158
  }
52716
- if (ctx2.markerless && promptExpr && !plainTarget) {
53159
+ if (ctx2.markerless && promptExpr) {
52717
53160
  ctx2.push(`${walkerArg}.injectSkipK(${promptExpr});`);
52718
53161
  }
52719
53162
  ctx2.push(`let ${v} = undefined;`);
@@ -55489,6 +55932,37 @@ function demoteExports2(code) {
55489
55932
  function chunkHasImports2(headLen, mergeAborted) {
55490
55933
  return headLen > 0 || mergeAborted;
55491
55934
  }
55935
+ function runtimeImportsOf2(filePath) {
55936
+ let text;
55937
+ try {
55938
+ text = readFileSync24(filePath, "utf8");
55939
+ } catch {
55940
+ return [];
55941
+ }
55942
+ const names = [];
55943
+ const pattern2 = /import\s+(type\s+)?\{([^}]*)\}\s*from\s*['"]@vesk\/runtime[^'"]*['"]/g;
55944
+ for (const match of text.matchAll(pattern2)) {
55945
+ if (match[1])
55946
+ continue;
55947
+ for (const part of match[2].split(",")) {
55948
+ const cleaned = part.trim().replace(/^type\s+/, "");
55949
+ if (!cleaned)
55950
+ continue;
55951
+ const name = cleaned.split(/\s+as\s+/)[0].trim();
55952
+ if (name)
55953
+ names.push(name);
55954
+ }
55955
+ }
55956
+ return names;
55957
+ }
55958
+ function sharedRuntimeResolver2(shimPath) {
55959
+ return {
55960
+ name: "vesk-shared-runtime",
55961
+ setup(build4) {
55962
+ build4.onResolve({ filter: /^@vesk\/runtime(\/.*)?$/ }, () => ({ path: shimPath }));
55963
+ }
55964
+ };
55965
+ }
55492
55966
  var ChunkImports2 = class {
55493
55967
  bySource = /* @__PURE__ */ new Map();
55494
55968
  aborted = false;
@@ -55596,6 +56070,21 @@ var ChunkImports2 = class {
55596
56070
  get reason() {
55597
56071
  return this.abortReason;
55598
56072
  }
56073
+ /** Every import source this chunk's merged block pulls in (absolute paths). */
56074
+ sources() {
56075
+ return this.aborted ? [] : [...this.bySource.keys()];
56076
+ }
56077
+ /**
56078
+ * The named bindings this chunk imports from `source`, so a shared-module
56079
+ * shim can re-export exactly what consumers use (re-exporting `*` from the
56080
+ * real module would drag it back into the chunk being built).
56081
+ */
56082
+ bindingsFor(source) {
56083
+ const group = this.bySource.get(source);
56084
+ if (!group)
56085
+ return { named: [], hasDefault: false };
56086
+ return { named: [...group.named.keys()].sort(), hasDefault: !!group.default };
56087
+ }
55599
56088
  /** Renders the deduped import block (empty string when there are no imports). */
55600
56089
  render() {
55601
56090
  if (this.aborted || this.bySource.size === 0)
@@ -55750,6 +56239,7 @@ async function generateClientBundle2(routeTree, appDir, componentMap, options) {
55750
56239
  let cachedFileHits = 0;
55751
56240
  let compiledFiles = 0;
55752
56241
  let mainFromCache = false;
56242
+ let sharedModuleBundle = "";
55753
56243
  function mustReuseWithoutStat(filePath) {
55754
56244
  return !!only && !only.has(filePath);
55755
56245
  }
@@ -55948,7 +56438,7 @@ async function generateClientBundle2(routeTree, appDir, componentMap, options) {
55948
56438
  console.error("[vesk] chunk import merge aborted for", chunkName + ":", chunkImports.reason);
55949
56439
  const head = chunkImports.render();
55950
56440
  const code = (head ? head + "\n\n" : "") + chunkCode.join("\n\n");
55951
- chunkEntries.push({ name: chunkName, code, node, imports: chunkHasImports2(head.length, !chunkImports.ok) });
56441
+ chunkEntries.push({ name: chunkName, code, node, importsTable: chunkImports, imports: chunkHasImports2(head.length, !chunkImports.ok) });
55952
56442
  }
55953
56443
  walkSplit2(node.children || [], [..._chain, node]);
55954
56444
  }
@@ -55978,7 +56468,7 @@ async function generateClientBundle2(routeTree, appDir, componentMap, options) {
55978
56468
  console.error("[vesk] chunk import merge aborted for shared.js:", sharedImports.reason);
55979
56469
  const head = sharedImports.render();
55980
56470
  const code = (head ? head + "\n\n" : "") + sharedCode.join("\n\n");
55981
- chunkEntries.push({ name: "shared.js", code, node: null, imports: chunkHasImports2(head.length, !sharedImports.ok) });
56471
+ chunkEntries.push({ name: "shared.js", code, node: null, importsTable: sharedImports, imports: chunkHasImports2(head.length, !sharedImports.ok) });
55982
56472
  }
55983
56473
  const chunkIIFE = (body) => `(()=>{
55984
56474
  const __components = globalThis.__components || (globalThis.__components = {});
@@ -55986,6 +56476,101 @@ const __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});
55986
56476
  ${body}
55987
56477
  })();
55988
56478
  `;
56479
+ const sharedUsage = /* @__PURE__ */ new Map();
56480
+ for (const entry of chunkEntries) {
56481
+ for (const source of new Set(entry.importsTable.sources())) {
56482
+ sharedUsage.set(source, (sharedUsage.get(source) ?? 0) + 1);
56483
+ }
56484
+ }
56485
+ const isAppLocal = (source) => !source.includes("node_modules") && source.startsWith(resolve24(appDir, ".."));
56486
+ const sharedSources = [...sharedUsage.entries()].filter(([source, uses]) => uses > 1 && isAppLocal(source)).map(([source]) => source);
56487
+ if (process.env.VESK_DEBUG_SHARED) {
56488
+ console.error("[shared] candidates:", [...sharedUsage.entries()].map(([s, n]) => `${n}x ${s}`).join("\n"));
56489
+ console.error("[shared] selected:", sharedSources.join(", "));
56490
+ }
56491
+ const chunkAlias = {};
56492
+ let sharedBundleCode = "";
56493
+ const sharedRuntimeNames = /* @__PURE__ */ new Set();
56494
+ if (sharedSources.length > 0) {
56495
+ const tmpBase = mkdtempSync2(join20(resolve24(appDir, ".."), "tmp-vesk-shared-"));
56496
+ try {
56497
+ const sharedEntry = join20(tmpBase, "shared-entry.js");
56498
+ const lines = [];
56499
+ const members = [];
56500
+ sharedSources.forEach((source, i) => {
56501
+ lines.push(`import * as m${i} from ${JSON.stringify(source)};`);
56502
+ members.push(` ${JSON.stringify(source)}: m${i},`);
56503
+ });
56504
+ lines.push(`globalThis.__veskShared = { ${members.join("\n")} };`);
56505
+ writeFileSync13(sharedEntry, lines.join("\n"));
56506
+ const appTsconfig = findTsconfigPath(appDir);
56507
+ const runtimeShim = join20(tmpBase, "runtime-shim.js");
56508
+ const runtimeLines = [
56509
+ "// ONE runtime instance: the entry bundle publishes these on globalThis,",
56510
+ "// and route chunks import the same functions. A second bundled copy",
56511
+ "// would mean a second Cell class and a second currentEffect.",
56512
+ "const __r = (n) => (...args) => globalThis[n](...args);"
56513
+ ];
56514
+ for (const source of sharedSources) {
56515
+ for (const name of runtimeImportsOf2(source))
56516
+ sharedRuntimeNames.add(name);
56517
+ }
56518
+ for (const name of [...sharedRuntimeNames].sort()) {
56519
+ runtimeLines.push(`export const ${name} = __r(${JSON.stringify(name)});`);
56520
+ }
56521
+ writeFileSync13(runtimeShim, runtimeLines.join("\n") + "\n");
56522
+ const result = await build3({
56523
+ entryPoints: [sharedEntry],
56524
+ bundle: true,
56525
+ format: "iife",
56526
+ platform: "browser",
56527
+ write: false,
56528
+ logLevel: "silent",
56529
+ loader: { ".js": "tsx" },
56530
+ legalComments: "none",
56531
+ // `@vesk/runtime` MUST stay the entry bundle's instance. Bundling a
56532
+ // second copy in here gives the app a second `Cell` class and a
56533
+ // second `currentEffect` variable: a store cell written from a click
56534
+ // notifies subscribers registered against the OTHER copy, so nothing
56535
+ // the store drives ever updates — writes land, no error, no repaint.
56536
+ plugins: [sharedRuntimeResolver2(runtimeShim)],
56537
+ ...appTsconfig ? { tsconfig: appTsconfig } : {}
56538
+ });
56539
+ sharedBundleCode = result.outputFiles[0].text;
56540
+ sharedSources.forEach((source, i) => {
56541
+ const named = /* @__PURE__ */ new Set();
56542
+ let hasDefault = false;
56543
+ for (const entry of chunkEntries) {
56544
+ const bindings = entry.importsTable.bindingsFor(source);
56545
+ bindings.named.forEach((n) => named.add(n));
56546
+ hasDefault = hasDefault || bindings.hasDefault;
56547
+ }
56548
+ const shim = join20(tmpBase, `shim-${i}.js`);
56549
+ const shimLines = [`const m = globalThis.__veskShared[${JSON.stringify(source)}];`];
56550
+ if (hasDefault)
56551
+ shimLines.push(`export default m;`);
56552
+ for (const name of [...named].sort()) {
56553
+ shimLines.push(`export const ${name} = m[${JSON.stringify(name)}];`);
56554
+ }
56555
+ writeFileSync13(shim, shimLines.join("\n") + "\n");
56556
+ chunkAlias[source] = shim;
56557
+ });
56558
+ } catch (e) {
56559
+ console.error("[vesk] shared-module pass failed; falling back to per-chunk inlining:", e.message);
56560
+ sharedBundleCode = "";
56561
+ for (const key of Object.keys(chunkAlias))
56562
+ delete chunkAlias[key];
56563
+ }
56564
+ }
56565
+ const sharedRedirectPlugin = Object.keys(chunkAlias).length > 0 ? {
56566
+ name: "vesk-shared-modules",
56567
+ setup(build4) {
56568
+ build4.onResolve({ filter: /.*/ }, (args2) => {
56569
+ const mapped = chunkAlias[args2.path];
56570
+ return mapped ? { path: mapped } : null;
56571
+ });
56572
+ }
56573
+ } : null;
55989
56574
  for (const entry of chunkEntries) {
55990
56575
  if (!entry.code.trim())
55991
56576
  continue;
@@ -56015,6 +56600,13 @@ ${entry.code}
56015
56600
  // for a dependency stays in its own package; shipping every
56016
56601
  // module's header inside our own chunk adds nothing.
56017
56602
  legalComments: "none",
56603
+ // Shared app modules are NOT inlined here: the resolver below
56604
+ // redirects them to a generated shim reading
56605
+ // `globalThis.__veskShared`, so the single copy in
56606
+ // shared-modules.js serves every route chunk. (esbuild's `alias`
56607
+ // option only accepts bare package names, so this is a resolver
56608
+ // rather than a map.)
56609
+ ...sharedRedirectPlugin ? { plugins: [sharedRedirectPlugin] } : {},
56018
56610
  ...appTsconfig ? { tsconfig: appTsconfig } : {}
56019
56611
  });
56020
56612
  finalCode = result.outputFiles[0].text;
@@ -56042,13 +56634,16 @@ ${entry.code}
56042
56634
  chunks.push({ name: entry.name, code: finalCode });
56043
56635
  }
56044
56636
  annotate2(routeTree);
56045
- const mainKey = JSON.stringify(routeTree) + "|" + [...runtimeImportNames].sort().join(",") + `|${!!options?.hmr}|${!!options?.importRuntime}|${options?.routeDataCache ?? ""}`;
56637
+ sharedModuleBundle = sharedBundleCode;
56638
+ for (const name of sharedRuntimeNames)
56639
+ runtimeImportNames.add(name);
56640
+ const mainKey = JSON.stringify(routeTree) + "|" + [...runtimeImportNames].sort().join(",") + `|${!!options?.hmr}|${!!options?.importRuntime}|${options?.routeDataCache ?? ""}|${sharedModuleBundle.length}`;
56046
56641
  let main;
56047
56642
  if (cache2?.mainBundle && cache2.mainBundle.key === mainKey) {
56048
56643
  mainFromCache = true;
56049
56644
  main = cache2.mainBundle.code;
56050
56645
  } else {
56051
- main = await buildMainBundle2(routeTree, runtimeDir, true, {}, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache);
56646
+ main = await buildMainBundle2(routeTree, runtimeDir, true, {}, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache, sharedModuleBundle);
56052
56647
  if (cache2)
56053
56648
  cache2.mainBundle = { key: mainKey, code: main };
56054
56649
  }
@@ -56265,7 +56860,7 @@ export { ${unique.join(", ")} };
56265
56860
  function appendHmrGlobals2(code) {
56266
56861
  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";
56267
56862
  }
56268
- async function buildMainBundle2(routeTree, runtimeDir, codeSplit, mono, hmr, importRuntime, runtimeImportNames, routeDataCache) {
56863
+ async function buildMainBundle2(routeTree, runtimeDir, codeSplit, mono, hmr, importRuntime, runtimeImportNames, routeDataCache, sharedModuleBundle = "") {
56269
56864
  const baseRuntimeImports = ["createFileRouter", "get", "set", "effect", "track", "destroy_block", "getActiveComponent", "setActiveComponent", "NavLink", "Link", "reactiveProps", "matchRoute", "ensureChunk", "toDomNode", "rerenderNode"];
56270
56865
  const allRuntimeImports = runtimeImportNames && runtimeImportNames.size > 0 ? [.../* @__PURE__ */ new Set([...baseRuntimeImports, ...runtimeImportNames])] : baseRuntimeImports;
56271
56866
  const runtimeGlobals = [
@@ -56334,7 +56929,11 @@ if (__pendChunks.length > 0 && typeof ensureChunk === 'function') {
56334
56929
  `).join("") + "globalThis.__runtime_comps = __runtime_comps;\nglobalThis.__cleanup = __cleanup;\nglobalThis.__place = __place;\n\n";
56335
56930
  const extraGlobals = [...runtimeImportNames || []].filter((n) => n && n !== "default").map((n) => `globalThis.${n} = ${n};
56336
56931
  `).join("");
56337
- const code2 = preamble + "const __components = globalThis.__components || (globalThis.__components = {});\nconst __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});\nconst __runtime_comps = __components;\n\n" + runtimeGlobals2 + extraGlobals + cleanupFn + placeFn + "globalThis.__components = __components;\n" + resolveNamesFn + updateComponentsFn + "const __routeTree = " + routeTreeJson + ";\n__resolveNames(__routeTree);\n" + pendCode + startRouterCode;
56932
+ const code2 = preamble + "const __components = globalThis.__components || (globalThis.__components = {});\nconst __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});\nconst __runtime_comps = __components;\n\n" + runtimeGlobals2 + extraGlobals + // Shared app modules run HERE: after the runtime bindings are published,
56933
+ // before anything can request a route chunk. Earlier (at the top of the
56934
+ // bundle) `globalThis.track` was still undefined, so every module-scope
56935
+ // cell in a store was created against a missing runtime.
56936
+ (sharedModuleBundle ? sharedModuleBundle + "\n" : "") + cleanupFn + placeFn + "globalThis.__components = __components;\n" + resolveNamesFn + updateComponentsFn + "const __routeTree = " + routeTreeJson + ";\n__resolveNames(__routeTree);\n" + pendCode + startRouterCode;
56338
56937
  return hmr ? appendHmrGlobals2(code2) : code2;
56339
56938
  }
56340
56939
  const componentLines = mono?.componentLines || [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vesk/vesk-cli",
3
- "version": "0.2.58",
3
+ "version": "0.2.60",
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.58",
12
- "@vesk/compiler": "^0.2.58",
13
- "@vesk/plugin-tailwind": "^0.2.58",
14
- "@vesk/runtime": "^0.2.58",
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",
15
15
  "esrap": "^2.3.0",
16
16
  "typescript": "^5.8.0",
17
17
  "ws": "^8.18.0",