@vesk/vesk-cli 0.2.59 → 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.
- package/dist/cli.js +308 -35
- 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
|
-
|
|
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() {
|
|
@@ -18320,6 +18390,20 @@ function tokenizeCode(code) {
|
|
|
18320
18390
|
}
|
|
18321
18391
|
});
|
|
18322
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
|
+
}
|
|
18323
18407
|
function containsIdentifier(code, name) {
|
|
18324
18408
|
const tokens = tokenizeCode(code);
|
|
18325
18409
|
if (tokens !== null) {
|
|
@@ -18511,33 +18595,33 @@ function manualExtractImportNames(importText) {
|
|
|
18511
18595
|
}
|
|
18512
18596
|
return names;
|
|
18513
18597
|
}
|
|
18514
|
-
function hasTopLevelValueDeclaration(code, name) {
|
|
18515
|
-
const
|
|
18516
|
-
if (
|
|
18598
|
+
function hasTopLevelValueDeclaration(code, name, tokens) {
|
|
18599
|
+
const t = tokens == null ? tokenizeCode(code) : tokens;
|
|
18600
|
+
if (t === null) return false;
|
|
18517
18601
|
const declWords = ["const", "let", "var", "function", "class"];
|
|
18518
|
-
for (let i = 1; i <
|
|
18519
|
-
if (
|
|
18520
|
-
const prev =
|
|
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];
|
|
18521
18605
|
if (!prev || !declWords.includes(prev.value)) continue;
|
|
18522
18606
|
if (i >= 2) {
|
|
18523
|
-
const pp2 =
|
|
18607
|
+
const pp2 = t[i - 2];
|
|
18524
18608
|
if (pp2 && pp2.label === "name" && pp2.value === "export") continue;
|
|
18525
18609
|
}
|
|
18526
18610
|
return true;
|
|
18527
18611
|
}
|
|
18528
18612
|
return false;
|
|
18529
18613
|
}
|
|
18530
|
-
function findSpecifierExports(code) {
|
|
18531
|
-
const
|
|
18532
|
-
if (
|
|
18614
|
+
function findSpecifierExports(code, tokens) {
|
|
18615
|
+
const t = tokens == null ? tokenizeCode(code) : tokens;
|
|
18616
|
+
if (t === null) return [];
|
|
18533
18617
|
const out = [];
|
|
18534
|
-
for (let i = 0; i <
|
|
18535
|
-
if (
|
|
18536
|
-
if (!
|
|
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;
|
|
18537
18621
|
let k = i + 2;
|
|
18538
18622
|
let depth = 1;
|
|
18539
|
-
for (; k <
|
|
18540
|
-
const lbl =
|
|
18623
|
+
for (; k < t.length; k++) {
|
|
18624
|
+
const lbl = t[k].label;
|
|
18541
18625
|
if (lbl === "string") {
|
|
18542
18626
|
continue;
|
|
18543
18627
|
}
|
|
@@ -18548,8 +18632,8 @@ function findSpecifierExports(code) {
|
|
|
18548
18632
|
}
|
|
18549
18633
|
}
|
|
18550
18634
|
let isReexport = false;
|
|
18551
|
-
for (let j = k + 1; j <
|
|
18552
|
-
const lbl =
|
|
18635
|
+
for (let j = k + 1; j < t.length; j++) {
|
|
18636
|
+
const lbl = t[j].label;
|
|
18553
18637
|
if (lbl === "string") {
|
|
18554
18638
|
isReexport = true;
|
|
18555
18639
|
break;
|
|
@@ -18557,10 +18641,10 @@ function findSpecifierExports(code) {
|
|
|
18557
18641
|
if (lbl === ";" || lbl === "export" || lbl === "import" || lbl === "}") break;
|
|
18558
18642
|
}
|
|
18559
18643
|
if (depth !== 0 || isReexport) continue;
|
|
18560
|
-
const pairs = readSpecifierPairs(code,
|
|
18644
|
+
const pairs = readSpecifierPairs(code, t[i + 1].end, t[k].end);
|
|
18561
18645
|
if (pairs === null) continue;
|
|
18562
|
-
const stmtEnd =
|
|
18563
|
-
for (const [local, exported] of pairs) out.push({ local, exported, start:
|
|
18646
|
+
const stmtEnd = t[k].end;
|
|
18647
|
+
for (const [local, exported] of pairs) out.push({ local, exported, start: t[i].start, end: stmtEnd });
|
|
18564
18648
|
i = k;
|
|
18565
18649
|
}
|
|
18566
18650
|
return out;
|
|
@@ -18620,12 +18704,14 @@ function stripTrackDeclMarkers(text, base, node) {
|
|
|
18620
18704
|
}
|
|
18621
18705
|
return out + text.slice(prev);
|
|
18622
18706
|
}
|
|
18707
|
+
var QUOTED_LABELS;
|
|
18623
18708
|
var init_tokens = __esm({
|
|
18624
18709
|
"../compiler/src/tokens.ts"() {
|
|
18625
18710
|
"use strict";
|
|
18626
18711
|
init_parser();
|
|
18627
18712
|
init_vesk_plugin();
|
|
18628
18713
|
init_scan();
|
|
18714
|
+
QUOTED_LABELS = /* @__PURE__ */ new Set(["string", "template", "`", "backQuote"]);
|
|
18629
18715
|
}
|
|
18630
18716
|
});
|
|
18631
18717
|
|
|
@@ -18649,7 +18735,7 @@ function offsetToLineCol(source, offset2) {
|
|
|
18649
18735
|
}
|
|
18650
18736
|
return { line, column };
|
|
18651
18737
|
}
|
|
18652
|
-
function preprocessForClauses(source) {
|
|
18738
|
+
function preprocessForClauses(source, delimiters) {
|
|
18653
18739
|
const annotations = [];
|
|
18654
18740
|
const chars = source.split("");
|
|
18655
18741
|
const isString = (ch) => ch === '"' || ch === "'" || ch === "`";
|
|
@@ -18657,6 +18743,10 @@ function preprocessForClauses(source) {
|
|
|
18657
18743
|
while (i < source.length) {
|
|
18658
18744
|
const ch = source[i];
|
|
18659
18745
|
if (isString(ch)) {
|
|
18746
|
+
if (delimiters && !delimiters.has(i)) {
|
|
18747
|
+
i++;
|
|
18748
|
+
continue;
|
|
18749
|
+
}
|
|
18660
18750
|
const quote = ch;
|
|
18661
18751
|
let j = i + 1;
|
|
18662
18752
|
let tplDepth = 0;
|
|
@@ -19011,9 +19101,11 @@ function parseGeneratedJs(source) {
|
|
|
19011
19101
|
}
|
|
19012
19102
|
function parse4(source, options = {}) {
|
|
19013
19103
|
const ParserClass = createBaseParser();
|
|
19014
|
-
const
|
|
19104
|
+
const sourceTokens = tokenizeCode(source);
|
|
19105
|
+
const delimiters = sourceTokens === null ? null : collectStringDelimiters(source, sourceTokens);
|
|
19106
|
+
const { code, annotations } = preprocessForClauses(blankGenericArrowTypeParams(blankComments(source)), delimiters);
|
|
19015
19107
|
const vskSource = !options.filename || String(options.filename).endsWith(".vsk");
|
|
19016
|
-
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)) : [];
|
|
19017
19109
|
let parseable = code;
|
|
19018
19110
|
if (specifierExports.length > 0) {
|
|
19019
19111
|
const edits = specifierExports.map((e) => code.slice(e.start, e.end)).map((text) => text.split("").map((ch) => ch === "\n" ? "\n" : " ").join(""));
|
|
@@ -30399,8 +30491,13 @@ function emitNode(ctx2, node, tracked2, effectsVar, parentVar, compPrefix = "__c
|
|
|
30399
30491
|
if (node instanceof SlotNode) {
|
|
30400
30492
|
if (!parentVar) {
|
|
30401
30493
|
if (ctx2.hydrate) {
|
|
30494
|
+
const promptExpr = ctx2.markerless && (regionBudget || skipK > 0) ? markerlessSkipExpr(regionBudget, skipK) : null;
|
|
30402
30495
|
ctx2.push(`if (props.children !== undefined && props.children !== null) {`);
|
|
30403
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
|
+
}
|
|
30404
30501
|
ctx2.push(` __pendingChild = props.children(__hydrate);`);
|
|
30405
30502
|
ctx2.push(` } else if (__hydrate && __hydrate.root) {`);
|
|
30406
30503
|
ctx2.push(` __hydrate.root.appendChild(toDomNode(props.children));`);
|
|
@@ -35794,6 +35891,20 @@ ${serverStoreLine}
|
|
|
35794
35891
|
});
|
|
35795
35892
|
}
|
|
35796
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
|
+
|
|
35797
35908
|
${eventsStartLine}
|
|
35798
35909
|
let mwCtx = { params: {}, url, locals: ${localsSeed}, cookies: {}, request, resolveUrl(u) { return new URL(u, request.url).href; }, set() {}, get() { return undefined; } };
|
|
35799
35910
|
if (${hasMwLiteral}) {
|
|
@@ -46693,7 +46804,7 @@ function offsetToLineCol3(source, offset2) {
|
|
|
46693
46804
|
}
|
|
46694
46805
|
return { line, column };
|
|
46695
46806
|
}
|
|
46696
|
-
function preprocessForClauses2(source) {
|
|
46807
|
+
function preprocessForClauses2(source, delimiters) {
|
|
46697
46808
|
const annotations = [];
|
|
46698
46809
|
const chars = source.split("");
|
|
46699
46810
|
const isString = (ch) => ch === '"' || ch === "'" || ch === "`";
|
|
@@ -46701,6 +46812,10 @@ function preprocessForClauses2(source) {
|
|
|
46701
46812
|
while (i < source.length) {
|
|
46702
46813
|
const ch = source[i];
|
|
46703
46814
|
if (isString(ch)) {
|
|
46815
|
+
if (delimiters && !delimiters.has(i)) {
|
|
46816
|
+
i++;
|
|
46817
|
+
continue;
|
|
46818
|
+
}
|
|
46704
46819
|
const quote = ch;
|
|
46705
46820
|
let j = i + 1;
|
|
46706
46821
|
let tplDepth = 0;
|
|
@@ -47077,9 +47192,11 @@ function createBaseParser2() {
|
|
|
47077
47192
|
}
|
|
47078
47193
|
function parse5(source, options = {}) {
|
|
47079
47194
|
const ParserClass = createBaseParser2();
|
|
47080
|
-
const
|
|
47195
|
+
const sourceTokens = tokenizeCode(source);
|
|
47196
|
+
const delimiters = sourceTokens === null ? null : collectStringDelimiters(source, sourceTokens);
|
|
47197
|
+
const { code, annotations } = preprocessForClauses2(blankGenericArrowTypeParams2(blankComments(source)), delimiters);
|
|
47081
47198
|
const vskSource = !options.filename || String(options.filename).endsWith(".vsk");
|
|
47082
|
-
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)) : [];
|
|
47083
47200
|
let parseable = code;
|
|
47084
47201
|
if (specifierExports.length > 0) {
|
|
47085
47202
|
const edits = specifierExports.map((e) => code.slice(e.start, e.end)).map((text) => text.split("").map((ch) => ch === "\n" ? "\n" : " ").join(""));
|
|
@@ -48034,6 +48151,7 @@ async function bundleRuntime(appDir, outDir) {
|
|
|
48034
48151
|
`import { renderPage, renderFullPage, renderPageStream, compileFile, setRuntimeModule, setVskHydrate, hydratePrecompile, assertSameOrigin, withSsrStore } from ${JSON.stringify(resolve3(compilerRoot, "server-codegen.js"))};`,
|
|
48035
48152
|
`import { parseCookies } from ${JSON.stringify(resolve3(compilerRoot, "server-cookies.js"))};`,
|
|
48036
48153
|
`import * as __veskRuntime from ${JSON.stringify(resolve3(runtimeRoot, "index-server.js"))};`,
|
|
48154
|
+
`import * as __persistence from ${JSON.stringify(resolve3(runtimeRoot, "store-persistence.js"))};`,
|
|
48037
48155
|
"",
|
|
48038
48156
|
"// Inject runtime module so server-codegen can find components like NavLink, Link, etc.",
|
|
48039
48157
|
"setRuntimeModule(__veskRuntime);",
|
|
@@ -48099,6 +48217,40 @@ async function bundleRuntime(appDir, outDir) {
|
|
|
48099
48217
|
" return '/ssr-data.js?t=' + token;",
|
|
48100
48218
|
"}",
|
|
48101
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
|
+
"",
|
|
48102
48254
|
"// Re-export runtime classes used by API routes",
|
|
48103
48255
|
"export const VeskRequest = __veskRuntime.VeskRequest;",
|
|
48104
48256
|
"export const PayloadTooLargeError = __veskRuntime.PayloadTooLargeError;",
|
|
@@ -48409,6 +48561,51 @@ function buildParamExtraction(node, urlParts) {
|
|
|
48409
48561
|
walk9(node);
|
|
48410
48562
|
return parts;
|
|
48411
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
|
+
}
|
|
48412
48609
|
function generateSsrFunction(routeNode, appDir, outDir, componentMap, options) {
|
|
48413
48610
|
const ancestorLayouts = options?.ancestorLayouts || [];
|
|
48414
48611
|
const middlewareCode = options?.middlewareCode || null;
|
|
@@ -48510,6 +48707,7 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
|
|
|
48510
48707
|
"",
|
|
48511
48708
|
"async function __renderHtml(params, requestUrl) {",
|
|
48512
48709
|
" return withSsrStore(async () => {",
|
|
48710
|
+
" resetPersistedStoreKeys();",
|
|
48513
48711
|
" let page;",
|
|
48514
48712
|
" let caughtError = null;",
|
|
48515
48713
|
" const __expose = process.env.NODE_ENV !== 'production';",
|
|
@@ -48530,7 +48728,7 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
|
|
|
48530
48728
|
" if (_inner.head) _head = _inner.head + _head;",
|
|
48531
48729
|
" }",
|
|
48532
48730
|
" const html = await renderFullPage('', _layoutCompList[0], { params, children: _body }, __componentRegistry, { hydrate: true, cached: _layoutCompiledList[0]" + bakedOptions + clientScriptOption + dataScriptOption + ", pageHead: _head });",
|
|
48533
|
-
" 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 });",
|
|
48534
48732
|
" });",
|
|
48535
48733
|
"}",
|
|
48536
48734
|
""
|
|
@@ -48549,25 +48747,48 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
|
|
|
48549
48747
|
"async function __renderHtml(params, requestUrl) {",
|
|
48550
48748
|
" return withSsrStore(async () => {",
|
|
48551
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 || '';",
|
|
48552
48758
|
" try {",
|
|
48553
48759
|
" stream = renderPageStream('', _comp, { params }, __componentRegistry, { hydrate: true, cached: _compiled" + bakedOptions + clientScriptOption + dataScriptOption + " });",
|
|
48554
48760
|
" } catch (err) {",
|
|
48555
48761
|
" if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
|
|
48556
48762
|
" const html = await __renderErrorFullPage(params, requestUrl, err);",
|
|
48557
|
-
" return new Response(html, { headers: { 'Content-Type': 'text/html' }, status: 500 });",
|
|
48763
|
+
" return new Response(__injectStoreInit(html), { headers: { 'Content-Type': 'text/html' }, status: 500 });",
|
|
48558
48764
|
" }",
|
|
48559
48765
|
" return new Response(new ReadableStream({",
|
|
48560
48766
|
" async start(controller) {",
|
|
48561
48767
|
" const enc = new TextEncoder();",
|
|
48768
|
+
" let __tail = null;",
|
|
48769
|
+
" resetPersistedStoreKeys(__streamToken);",
|
|
48562
48770
|
" try {",
|
|
48563
48771
|
" for await (const chunk of stream) {",
|
|
48564
|
-
" controller.enqueue(enc.encode(
|
|
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);",
|
|
48565
48786
|
" }",
|
|
48566
48787
|
" } catch (err) {",
|
|
48567
48788
|
" if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
|
|
48568
48789
|
" try {",
|
|
48569
48790
|
" const html = await __renderErrorFullPage(params, requestUrl, err);",
|
|
48570
|
-
" controller.enqueue(enc.encode(html));",
|
|
48791
|
+
" controller.enqueue(enc.encode(__injectStoreInit(html)));",
|
|
48571
48792
|
" } catch {}",
|
|
48572
48793
|
" }",
|
|
48573
48794
|
" controller.close();",
|
|
@@ -48578,6 +48799,7 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
|
|
|
48578
48799
|
""
|
|
48579
48800
|
].join("\n");
|
|
48580
48801
|
}
|
|
48802
|
+
const persistCode = persistedStoreSsrCode();
|
|
48581
48803
|
let dataCode;
|
|
48582
48804
|
const exposeErr = "process.env.NODE_ENV !== 'production'";
|
|
48583
48805
|
const dataNavCleanup = [
|
|
@@ -48591,6 +48813,9 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
|
|
|
48591
48813
|
// process-global token — the cross-request data-slot race, for good. The
|
|
48592
48814
|
// token dies with the withSsrStore scope wrapped around this block instead.
|
|
48593
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();",
|
|
48594
48819
|
" }"
|
|
48595
48820
|
];
|
|
48596
48821
|
const dataNavWrap = (body) => [
|
|
@@ -48775,7 +49000,7 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
|
|
|
48775
49000
|
""
|
|
48776
49001
|
].join("\n");
|
|
48777
49002
|
const funcCode = [
|
|
48778
|
-
"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';",
|
|
48779
49004
|
"",
|
|
48780
49005
|
middlewareCode || "",
|
|
48781
49006
|
registryCode,
|
|
@@ -48784,6 +49009,8 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
|
|
|
48784
49009
|
paramsCode,
|
|
48785
49010
|
htmlFnCode,
|
|
48786
49011
|
"",
|
|
49012
|
+
persistCode,
|
|
49013
|
+
"",
|
|
48787
49014
|
"export async function handle(request) {",
|
|
48788
49015
|
" const url = new URL(request.url);",
|
|
48789
49016
|
" const params = __paramsFor(url.pathname);",
|
|
@@ -50918,6 +51145,15 @@ async function startProdServer(outDir, options) {
|
|
|
50918
51145
|
res.end(lines.join("\n") || "// no ssr data");
|
|
50919
51146
|
return;
|
|
50920
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
|
+
}
|
|
50921
51157
|
if (url.pathname === "/_vesk/runtime.js") {
|
|
50922
51158
|
const clientFile = buildConfig?.assets?.client?.file || "client.js";
|
|
50923
51159
|
const clientPath = resolve13(staticDir, clientFile);
|
|
@@ -51224,6 +51460,29 @@ async function resolveCompilerApi(name) {
|
|
|
51224
51460
|
}
|
|
51225
51461
|
return import(`@vesk/compiler/src/${name.replace(/\.js$/, "")}`);
|
|
51226
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
|
+
}
|
|
51227
51486
|
function filterActivePlugins2(plugins, records) {
|
|
51228
51487
|
if (!records || records.length === 0)
|
|
51229
51488
|
return plugins;
|
|
@@ -51357,6 +51616,14 @@ async function build2(appDir, options) {
|
|
|
51357
51616
|
console.error("vesk build: no routes found in", appDir);
|
|
51358
51617
|
return;
|
|
51359
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
|
+
}
|
|
51360
51627
|
const projectRoot = resolve21(appDir, "..");
|
|
51361
51628
|
const componentsDir = resolve21(projectRoot, "components");
|
|
51362
51629
|
const componentMap = scanComponents2(componentsDir);
|
|
@@ -52367,8 +52634,14 @@ function emitNode2(ctx2, node, tracked2, effectsVar, parentVar, compPrefix = "__
|
|
|
52367
52634
|
if (node instanceof SlotNode) {
|
|
52368
52635
|
if (!parentVar) {
|
|
52369
52636
|
if (ctx2.hydrate) {
|
|
52637
|
+
const promptExpr = ctx2.markerless && (regionBudget || skipK > 0) ? markerlessSkipExpr2(regionBudget, skipK) : null;
|
|
52370
52638
|
ctx2.push(`if (props.children !== undefined && props.children !== null) {`);
|
|
52371
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
|
+
}
|
|
52372
52645
|
ctx2.push(` __pendingChild = props.children(__hydrate);`);
|
|
52373
52646
|
ctx2.push(` } else if (__hydrate && __hydrate.root) {`);
|
|
52374
52647
|
ctx2.push(` __hydrate.root.appendChild(toDomNode(props.children));`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/vesk-cli",
|
|
3
|
-
"version": "0.2.
|
|
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.
|
|
12
|
-
"@vesk/compiler": "^0.2.
|
|
13
|
-
"@vesk/plugin-tailwind": "^0.2.
|
|
14
|
-
"@vesk/runtime": "^0.2.
|
|
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",
|