@vesk/vesk-cli 0.2.25 → 0.2.26
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 +267 -61
- package/package.json +5 -5
package/dist/cli.js
CHANGED
|
@@ -2154,6 +2154,9 @@ function stripDirectTextNodes(el) {
|
|
|
2154
2154
|
if (el.childNodes[i].nodeType === 3) el.childNodes[i].remove();
|
|
2155
2155
|
}
|
|
2156
2156
|
}
|
|
2157
|
+
function captureSsrElementChildren(el) {
|
|
2158
|
+
el.__vsk_ssrEls = Array.prototype.slice.call(el.children);
|
|
2159
|
+
}
|
|
2157
2160
|
function assertFullyHydrated(container) {
|
|
2158
2161
|
let unclaimed = 0;
|
|
2159
2162
|
let sample = "";
|
|
@@ -2198,6 +2201,19 @@ function adoptElement(marker, tag) {
|
|
|
2198
2201
|
if (tag && el.tagName.toLowerCase() !== tag) return null;
|
|
2199
2202
|
marker.remove();
|
|
2200
2203
|
stripDirectTextNodes(el);
|
|
2204
|
+
captureSsrElementChildren(el);
|
|
2205
|
+
stampClaimed(el);
|
|
2206
|
+
return el;
|
|
2207
|
+
}
|
|
2208
|
+
function adoptElementRaw(marker, tag) {
|
|
2209
|
+
const el = marker.nextElementSibling;
|
|
2210
|
+
if (!el) {
|
|
2211
|
+
marker.remove();
|
|
2212
|
+
return null;
|
|
2213
|
+
}
|
|
2214
|
+
if (tag && el.tagName.toLowerCase() !== tag) return null;
|
|
2215
|
+
marker.remove();
|
|
2216
|
+
captureSsrElementChildren(el);
|
|
2201
2217
|
stampClaimed(el);
|
|
2202
2218
|
return el;
|
|
2203
2219
|
}
|
|
@@ -2205,30 +2221,6 @@ function createHydrateWalker(container, markerList) {
|
|
|
2205
2221
|
const markers = markerList || (container ? collectVskMarkers(container) : []);
|
|
2206
2222
|
return new WalkerEngine(container, markers);
|
|
2207
2223
|
}
|
|
2208
|
-
function createHydrateChildWalker(parentEl) {
|
|
2209
|
-
let childIdx = 0;
|
|
2210
|
-
const children = parentEl ? parentEl.children : [];
|
|
2211
|
-
return {
|
|
2212
|
-
root: parentEl,
|
|
2213
|
-
done() {
|
|
2214
|
-
return childIdx >= children.length;
|
|
2215
|
-
},
|
|
2216
|
-
nextElement(tag) {
|
|
2217
|
-
while (childIdx < children.length) {
|
|
2218
|
-
const child = children[childIdx++];
|
|
2219
|
-
if (!tag || child.tagName.toLowerCase() === tag) {
|
|
2220
|
-
stripDirectTextNodes(child);
|
|
2221
|
-
stampClaimed(child);
|
|
2222
|
-
return child;
|
|
2223
|
-
}
|
|
2224
|
-
}
|
|
2225
|
-
return document.createElement(tag || "div");
|
|
2226
|
-
},
|
|
2227
|
-
subWalker(rootEl) {
|
|
2228
|
-
return createHydrateChildWalker(rootEl);
|
|
2229
|
-
}
|
|
2230
|
-
};
|
|
2231
|
-
}
|
|
2232
2224
|
function hydrateViewport(container, componentFn, props, rootMargin = 500) {
|
|
2233
2225
|
if (document.readyState !== "complete") {
|
|
2234
2226
|
return new Promise((resolve39) => {
|
|
@@ -2375,6 +2367,13 @@ var init_hydrate = __esm({
|
|
|
2375
2367
|
root;
|
|
2376
2368
|
markers;
|
|
2377
2369
|
idx = 0;
|
|
2370
|
+
// Elements already adopted by an earlier claim in this walk. Marker-only SSR
|
|
2371
|
+
// can leave TWO `<!--vsk-->` marks on the same element (the call site and
|
|
2372
|
+
// the callee's own root marker — e.g. Link self-prefixes `<!--vsk-->` and
|
|
2373
|
+
// the shared walker claims its call-site marker), and a claim must never
|
|
2374
|
+
// adopt the same node twice: double-adoption strips its SSR text a second
|
|
2375
|
+
// time and shells the cursor so every later claim misses its element.
|
|
2376
|
+
adopted = /* @__PURE__ */ new WeakSet();
|
|
2378
2377
|
constructor(root3, markers) {
|
|
2379
2378
|
this.root = root3;
|
|
2380
2379
|
this.markers = markers.map((c) => ({ comment: c, state: "unclaimed" }));
|
|
@@ -2382,6 +2381,43 @@ var init_hydrate = __esm({
|
|
|
2382
2381
|
done() {
|
|
2383
2382
|
return this.idx >= this.markers.length;
|
|
2384
2383
|
}
|
|
2384
|
+
// A marker whose `nextElementSibling` was already adopted is a dead alias of
|
|
2385
|
+
// a live claim point (double-marker collision). Retire it and move on so the
|
|
2386
|
+
// cursor never claims a node twice.
|
|
2387
|
+
isAlreadyAdopted(tm, el) {
|
|
2388
|
+
if (el !== null && this.adopted.has(el)) {
|
|
2389
|
+
tm.state = "claimed";
|
|
2390
|
+
this.idx++;
|
|
2391
|
+
tm.comment.remove();
|
|
2392
|
+
return true;
|
|
2393
|
+
}
|
|
2394
|
+
return false;
|
|
2395
|
+
}
|
|
2396
|
+
recordAdopted(el) {
|
|
2397
|
+
this.adopted.add(el);
|
|
2398
|
+
}
|
|
2399
|
+
// Marker-only SSR can stack several `<!--vsk-->` marks before ONE element
|
|
2400
|
+
// (call-site marker + the callee's own root marker). The FIRST claim adopts
|
|
2401
|
+
// the element; the alias markers that immediately follow it are dead — they
|
|
2402
|
+
// point at an already-claimed node and must be physically retired so the
|
|
2403
|
+
// canary never counts them and a trailing alias never lingers in the DOM.
|
|
2404
|
+
retireAliases(el) {
|
|
2405
|
+
let i = this.idx;
|
|
2406
|
+
while (i < this.markers.length) {
|
|
2407
|
+
const tm = this.markers[i];
|
|
2408
|
+
if (tm.state === "claimed") {
|
|
2409
|
+
i++;
|
|
2410
|
+
continue;
|
|
2411
|
+
}
|
|
2412
|
+
if (tm.comment.nextElementSibling === el) {
|
|
2413
|
+
tm.state = "claimed";
|
|
2414
|
+
tm.comment.remove();
|
|
2415
|
+
i++;
|
|
2416
|
+
continue;
|
|
2417
|
+
}
|
|
2418
|
+
break;
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2385
2421
|
nextElement(tag) {
|
|
2386
2422
|
while (this.idx < this.markers.length) {
|
|
2387
2423
|
const tm = this.markers[this.idx];
|
|
@@ -2390,6 +2426,7 @@ var init_hydrate = __esm({
|
|
|
2390
2426
|
continue;
|
|
2391
2427
|
}
|
|
2392
2428
|
const el = tm.comment.nextElementSibling;
|
|
2429
|
+
if (this.isAlreadyAdopted(tm, el)) continue;
|
|
2393
2430
|
if (tag && el && el.tagName.toLowerCase() !== tag) {
|
|
2394
2431
|
break;
|
|
2395
2432
|
}
|
|
@@ -2399,6 +2436,8 @@ var init_hydrate = __esm({
|
|
|
2399
2436
|
tm.state = "claimed";
|
|
2400
2437
|
break;
|
|
2401
2438
|
}
|
|
2439
|
+
this.recordAdopted(adopted);
|
|
2440
|
+
this.retireAliases(adopted);
|
|
2402
2441
|
tm.state = "claimed";
|
|
2403
2442
|
return adopted;
|
|
2404
2443
|
}
|
|
@@ -2410,6 +2449,45 @@ ${String(this.root.outerHTML).slice(0, 800)}` : "")
|
|
|
2410
2449
|
}
|
|
2411
2450
|
return document.createElement(tag || "div");
|
|
2412
2451
|
}
|
|
2452
|
+
claimOnly(tag) {
|
|
2453
|
+
while (this.idx < this.markers.length) {
|
|
2454
|
+
const tm = this.markers[this.idx];
|
|
2455
|
+
if (tm.state === "claimed") {
|
|
2456
|
+
this.idx++;
|
|
2457
|
+
continue;
|
|
2458
|
+
}
|
|
2459
|
+
const el = tm.comment.nextElementSibling;
|
|
2460
|
+
if (this.isAlreadyAdopted(tm, el)) continue;
|
|
2461
|
+
if (tag && el && el.tagName.toLowerCase() !== tag) break;
|
|
2462
|
+
this.idx++;
|
|
2463
|
+
const adopted = adoptElementRaw(tm.comment, tag);
|
|
2464
|
+
if (adopted === null) {
|
|
2465
|
+
tm.state = "claimed";
|
|
2466
|
+
break;
|
|
2467
|
+
}
|
|
2468
|
+
this.recordAdopted(adopted);
|
|
2469
|
+
this.retireAliases(adopted);
|
|
2470
|
+
tm.state = "claimed";
|
|
2471
|
+
return adopted;
|
|
2472
|
+
}
|
|
2473
|
+
return document.createElement(tag || "div");
|
|
2474
|
+
}
|
|
2475
|
+
retireDetached() {
|
|
2476
|
+
while (this.idx < this.markers.length) {
|
|
2477
|
+
const tm = this.markers[this.idx];
|
|
2478
|
+
if (tm.state === "claimed") {
|
|
2479
|
+
this.idx++;
|
|
2480
|
+
continue;
|
|
2481
|
+
}
|
|
2482
|
+
const c = tm.comment;
|
|
2483
|
+
if (!c || !c.parentNode) {
|
|
2484
|
+
tm.state = "claimed";
|
|
2485
|
+
this.idx++;
|
|
2486
|
+
continue;
|
|
2487
|
+
}
|
|
2488
|
+
break;
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2413
2491
|
subWalker(rootEl) {
|
|
2414
2492
|
const subMarkers = this.markers.slice(this.idx).filter((m) => {
|
|
2415
2493
|
if (m.state === "claimed") return false;
|
|
@@ -2420,9 +2498,6 @@ ${String(this.root.outerHTML).slice(0, 800)}` : "")
|
|
|
2420
2498
|
});
|
|
2421
2499
|
this.idx += subMarkers.length;
|
|
2422
2500
|
for (const m of subMarkers) m.state = "claimed";
|
|
2423
|
-
if (subMarkers.length === 0 && rootEl && rootEl.tagName === "SPAN" && rootEl.style && rootEl.style.display === "contents") {
|
|
2424
|
-
return createHydrateChildWalker(rootEl);
|
|
2425
|
-
}
|
|
2426
2501
|
return new _WalkerEngine(rootEl, subMarkers.map((m) => m.comment));
|
|
2427
2502
|
}
|
|
2428
2503
|
claimByKey(key) {
|
|
@@ -2431,10 +2506,14 @@ ${String(this.root.outerHTML).slice(0, 800)}` : "")
|
|
|
2431
2506
|
const tm = this.markers[i];
|
|
2432
2507
|
if (tm.state === "claimed") continue;
|
|
2433
2508
|
const el = tm.comment.nextElementSibling;
|
|
2509
|
+
if (this.isAlreadyAdopted(tm, el)) continue;
|
|
2434
2510
|
if (el && el.getAttribute("data-vsk-key") === strKey) {
|
|
2435
2511
|
tm.state = "claimed";
|
|
2512
|
+
this.recordAdopted(el);
|
|
2513
|
+
this.retireAliases(el);
|
|
2436
2514
|
tm.comment.remove();
|
|
2437
2515
|
stripDirectTextNodes(el);
|
|
2516
|
+
captureSsrElementChildren(el);
|
|
2438
2517
|
stampClaimed(el);
|
|
2439
2518
|
return { el };
|
|
2440
2519
|
}
|
|
@@ -2448,6 +2527,7 @@ ${String(this.root.outerHTML).slice(0, 800)}` : "")
|
|
|
2448
2527
|
const tm = this.markers[i];
|
|
2449
2528
|
if (tm.state === "claimed") continue;
|
|
2450
2529
|
const el = tm.comment.nextElementSibling;
|
|
2530
|
+
if (el && this.adopted.has(el)) continue;
|
|
2451
2531
|
if (el && el.getAttribute("data-vsk-key") === strKey) return el;
|
|
2452
2532
|
}
|
|
2453
2533
|
return null;
|
|
@@ -2966,10 +3046,6 @@ function Link(props, registry, hydrate) {
|
|
|
2966
3046
|
const href = props.href || "#";
|
|
2967
3047
|
if (hydrate && hydrate.nextElement) {
|
|
2968
3048
|
let a2 = hydrate.nextElement("a");
|
|
2969
|
-
if (a2 && !a2.parentNode && hydrate.root) {
|
|
2970
|
-
const existing = hydrate.root.querySelector("a");
|
|
2971
|
-
if (existing) a2 = existing;
|
|
2972
|
-
}
|
|
2973
3049
|
const claimed = a2 ? a2.parentNode !== null : false;
|
|
2974
3050
|
if (!a2) a2 = document.createElement("a");
|
|
2975
3051
|
applyLinkDom(a2, props, href);
|
|
@@ -27563,15 +27639,21 @@ function emitStatic(ctx2, node, tracked2, effectsVar) {
|
|
|
27563
27639
|
ctx2.push(`${el}.setAttribute(${JSON.stringify(attr.name)}, ${JSON.stringify(escapeHtml4(attr.value))});`);
|
|
27564
27640
|
}
|
|
27565
27641
|
}
|
|
27642
|
+
let residueBefore = 0;
|
|
27566
27643
|
for (const child of children) {
|
|
27567
27644
|
const childVar = emitNode(ctx2, child, tracked2, effectsVar, el);
|
|
27568
27645
|
if (childVar) {
|
|
27569
27646
|
if (ctx2.hydrate) {
|
|
27570
|
-
|
|
27647
|
+
if (child instanceof TextNode || child instanceof DynamicBinding) {
|
|
27648
|
+
ctx2.push(`if (${childVar}.parentNode !== ${el}) { const __ssr = ${el}.__vsk_ssrEls || []; if (${residueBefore} < __ssr.length) ${el}.insertBefore(${childVar}, __ssr[${residueBefore}]); else ${el}.appendChild(${childVar}); }`);
|
|
27649
|
+
} else {
|
|
27650
|
+
ctx2.push(`if (${childVar}.parentNode !== ${el}) { if (!${el} || ${childVar}.parentNode == null || !${el}.contains(${childVar})) ${el}.appendChild(${childVar}); }`);
|
|
27651
|
+
}
|
|
27571
27652
|
} else {
|
|
27572
27653
|
ctx2.push(`${el}.appendChild(${childVar});`);
|
|
27573
27654
|
}
|
|
27574
27655
|
}
|
|
27656
|
+
residueBefore += ssrResidueEstimate(child);
|
|
27575
27657
|
}
|
|
27576
27658
|
for (const attr of dynAttrs) {
|
|
27577
27659
|
const target = attr.target || "";
|
|
@@ -27742,22 +27824,28 @@ function emitComponentCall(ctx2, node, tracked2, effectsVar, parentVar, compPref
|
|
|
27742
27824
|
}
|
|
27743
27825
|
const propsObj = `{ ${propsEntries.join(", ")} }`;
|
|
27744
27826
|
const v = ctx2.n();
|
|
27745
|
-
const awaitKw = ctx2.
|
|
27827
|
+
const awaitKw = ctx2.isAsyncScope ? "await " : "";
|
|
27746
27828
|
const calleeExpr = node.calleeExpr ? `(${node.calleeExpr})` : null;
|
|
27747
27829
|
if (ctx2.hydrate) {
|
|
27748
27830
|
const access = calleeExpr ?? (ctx2.importedNames.has(node.componentName) ? node.componentName : `__components[${JSON.stringify(node.componentName)}]`);
|
|
27749
|
-
const
|
|
27831
|
+
const plainTarget = !!(calleeExpr || ctx2.importedNames.has(node.componentName)) && !ctx2.selfClaimNames.has(node.componentName);
|
|
27832
|
+
const walkerArg = ctx2.walker;
|
|
27833
|
+
const maybeReplace = (v2) => {
|
|
27834
|
+
if (!plainTarget) return;
|
|
27835
|
+
ctx2.push(`if (${v2} && ${v2}.parentNode == null && ${v2}.nodeType !== 11) { const __sr = ${walkerArg}.claimOnly(); if (__sr && __sr.parentNode) __sr.parentNode.replaceChild(${v2}, __sr); }`);
|
|
27836
|
+
};
|
|
27837
|
+
const maybeRetire = () => {
|
|
27838
|
+
if (ctx2.selfClaimNames.has(node.componentName)) {
|
|
27839
|
+
ctx2.push(`${walkerArg}.retireDetached();`);
|
|
27840
|
+
}
|
|
27841
|
+
};
|
|
27750
27842
|
if (node.children.length > 0) {
|
|
27751
|
-
const walkerVar = ctx2.n();
|
|
27752
|
-
ctx2.push(`const ${walkerVar} = ${subScope()};`);
|
|
27753
27843
|
const frag = ctx2.n();
|
|
27754
27844
|
ctx2.push(`const ${frag} = (() => { const $f = document.createDocumentFragment();`);
|
|
27755
|
-
const savedWalker = ctx2.walker;
|
|
27756
27845
|
const savedEffects = ctx2.effects;
|
|
27757
27846
|
const wipeMount = ctx2.linkNames.has(node.componentName);
|
|
27758
27847
|
const savedHydrate = ctx2.hydrate;
|
|
27759
27848
|
if (wipeMount) ctx2.hydrate = false;
|
|
27760
|
-
ctx2.walker = walkerVar;
|
|
27761
27849
|
ctx2.effects = [];
|
|
27762
27850
|
for (const child of node.children) {
|
|
27763
27851
|
const childVar = emitNode(ctx2, child, tracked2, effectsVar, "$f");
|
|
@@ -27765,14 +27853,17 @@ function emitComponentCall(ctx2, node, tracked2, effectsVar, parentVar, compPref
|
|
|
27765
27853
|
}
|
|
27766
27854
|
for (const eff of ctx2.effects) ctx2.push(effectsVar ? `${effectsVar}.push(${effectBlockToHandlerExpr(eff)});` : eff);
|
|
27767
27855
|
ctx2.effects = savedEffects;
|
|
27768
|
-
ctx2.walker = savedWalker;
|
|
27769
27856
|
ctx2.hydrate = savedHydrate;
|
|
27770
27857
|
ctx2.push(`return $f; })();`);
|
|
27771
27858
|
propsEntries.push(`children: ${frag}`);
|
|
27772
|
-
ctx2.push(`const ${v} = ${awaitKw}${access}({ ${propsEntries.join(", ")} }, __registry, ${
|
|
27859
|
+
ctx2.push(`const ${v} = ${awaitKw}${access}({ ${propsEntries.join(", ")} }, __registry, ${walkerArg});`);
|
|
27860
|
+
maybeReplace(v);
|
|
27861
|
+
maybeRetire();
|
|
27773
27862
|
return v;
|
|
27774
27863
|
}
|
|
27775
|
-
ctx2.push(`const ${v} = ${awaitKw}${access}(${propsObj}, __registry, ${
|
|
27864
|
+
ctx2.push(`const ${v} = ${awaitKw}${access}(${propsObj}, __registry, ${walkerArg});`);
|
|
27865
|
+
maybeReplace(v);
|
|
27866
|
+
maybeRetire();
|
|
27776
27867
|
return v;
|
|
27777
27868
|
} else {
|
|
27778
27869
|
if (node.children.length > 0) {
|
|
@@ -28501,11 +28592,12 @@ ${renderAllItems(" ", null)}
|
|
|
28501
28592
|
function computeAsyncComponents(comps) {
|
|
28502
28593
|
return new Set(comps.filter((c) => c.isAsync).map((c) => c.name));
|
|
28503
28594
|
}
|
|
28504
|
-
function generateComponent(comp, importedNames = /* @__PURE__ */ new Set(), hydrate = false, asyncComps = /* @__PURE__ */ new Set(), linkNames = /* @__PURE__ */ new Set()) {
|
|
28595
|
+
function generateComponent(comp, importedNames = /* @__PURE__ */ new Set(), hydrate = false, asyncComps = /* @__PURE__ */ new Set(), linkNames = /* @__PURE__ */ new Set(), selfClaimNames = /* @__PURE__ */ new Set()) {
|
|
28505
28596
|
const tracked2 = collectTrackedNames(comp.body);
|
|
28506
28597
|
const ctx2 = new Ctx();
|
|
28507
28598
|
ctx2.importedNames = importedNames;
|
|
28508
28599
|
ctx2.linkNames = linkNames;
|
|
28600
|
+
ctx2.selfClaimNames = selfClaimNames;
|
|
28509
28601
|
ctx2.hydrate = hydrate;
|
|
28510
28602
|
ctx2.asyncComps = asyncComps;
|
|
28511
28603
|
ctx2.isAsyncScope = comp.isAsync || asyncComps.has(comp.name);
|
|
@@ -28529,10 +28621,16 @@ function generateComponent(comp, importedNames = /* @__PURE__ */ new Set(), hydr
|
|
|
28529
28621
|
const paramInit = buildParamInit2(comp.paramNames);
|
|
28530
28622
|
if (paramInit) ctx2.push(indent2(paramInit));
|
|
28531
28623
|
for (const node of comp.body) {
|
|
28624
|
+
if (node instanceof TrackDecl) {
|
|
28625
|
+
emitNode(ctx2, node, tracked2, null);
|
|
28626
|
+
}
|
|
28627
|
+
}
|
|
28628
|
+
for (const node of comp.body) {
|
|
28629
|
+
if (node instanceof TrackDecl) continue;
|
|
28532
28630
|
const v = emitNode(ctx2, node, tracked2, null);
|
|
28533
28631
|
if (v) {
|
|
28534
28632
|
if (ctx2.hydrate) {
|
|
28535
|
-
ctx2.push(indent2(`if (${v}.parentNode !== $root) { if (!$root || ${v}.parentNode == null || !$
|
|
28633
|
+
ctx2.push(indent2(`if (${v}.parentNode !== $root) { if (!$root || ${v}.parentNode == null || !${v}.parentNode.contains(${v})) $root.appendChild(${v}); }`));
|
|
28536
28634
|
} else {
|
|
28537
28635
|
ctx2.push(indent2(`$root.appendChild(${v});`));
|
|
28538
28636
|
}
|
|
@@ -28559,7 +28657,13 @@ function buildComponentMap(irRoot, hydrate = false) {
|
|
|
28559
28657
|
mapLines.push(`const __components = {};`);
|
|
28560
28658
|
const asyncComps = computeAsyncComponents(irRoot.components);
|
|
28561
28659
|
const linkNames = /* @__PURE__ */ new Set();
|
|
28660
|
+
const selfClaimNames = /* @__PURE__ */ new Set();
|
|
28661
|
+
const SELF_CLAIM_RUNTIME = /* @__PURE__ */ new Set(["Link", "NavLink", "Md", "Form", "Field", "LoadingIndicator"]);
|
|
28562
28662
|
for (const imp of irRoot.imports) {
|
|
28663
|
+
if (importModuleTarget(imp) !== "@vesk/runtime") continue;
|
|
28664
|
+
for (const pair of importBindingPairs(imp)) {
|
|
28665
|
+
if (SELF_CLAIM_RUNTIME.has(pair.imported)) selfClaimNames.add(pair.local);
|
|
28666
|
+
}
|
|
28563
28667
|
for (const pair of importBindingPairs(imp)) {
|
|
28564
28668
|
if (pair.imported === "Link" || pair.imported === "NavLink") linkNames.add(pair.local);
|
|
28565
28669
|
}
|
|
@@ -28569,11 +28673,11 @@ function buildComponentMap(irRoot, hydrate = false) {
|
|
|
28569
28673
|
const directNames = /* @__PURE__ */ new Set([...extractRuntimeNames(irRoot.imports), ...localValueImportNames(irRoot.imports), ...topValueNames]);
|
|
28570
28674
|
for (const comp of irRoot.components) {
|
|
28571
28675
|
if (hydrate && isStaticComponent(comp)) {
|
|
28572
|
-
const stub = `(props, __registry, __hydrate) => { return __hydrate.
|
|
28676
|
+
const stub = `(props, __registry, __hydrate) => { return __hydrate.claimOnly(); }`;
|
|
28573
28677
|
mapLines.push(`__components[${JSON.stringify(comp.name)}] = ${stub};`);
|
|
28574
28678
|
continue;
|
|
28575
28679
|
}
|
|
28576
|
-
const code = generateComponent(comp, directNames, hydrate, asyncComps, linkNames);
|
|
28680
|
+
const code = generateComponent(comp, directNames, hydrate, asyncComps, linkNames, selfClaimNames);
|
|
28577
28681
|
mapLines.push(`__components[${JSON.stringify(comp.name)}] = ${code};`);
|
|
28578
28682
|
}
|
|
28579
28683
|
mapLines.push(`function __cleanup(start, end) {`);
|
|
@@ -28602,6 +28706,32 @@ function buildComponentMap(irRoot, hydrate = false) {
|
|
|
28602
28706
|
mapLines.push(`}`);
|
|
28603
28707
|
return mapLines.join("\n\n");
|
|
28604
28708
|
}
|
|
28709
|
+
function ssrResidueEstimate(node) {
|
|
28710
|
+
if (Array.isArray(node)) {
|
|
28711
|
+
let total = 0;
|
|
28712
|
+
for (const n of node) total += ssrResidueEstimate(n);
|
|
28713
|
+
return total;
|
|
28714
|
+
}
|
|
28715
|
+
if (node instanceof StaticNode) return 1;
|
|
28716
|
+
if (node instanceof ComponentCall) return 1;
|
|
28717
|
+
if (node instanceof OpaqueDynamicRegion) {
|
|
28718
|
+
return Math.max(ssrResidueEstimate(node.consequentNodes), ssrResidueEstimate(node.alternateNodes));
|
|
28719
|
+
}
|
|
28720
|
+
if (node instanceof MapRegion) {
|
|
28721
|
+
return Math.max(ssrResidueEstimate(node.bodyTemplate), ssrResidueEstimate(node.alternateNodes));
|
|
28722
|
+
}
|
|
28723
|
+
if (node instanceof ForLoop) return ssrResidueEstimate(node.bodyTemplate);
|
|
28724
|
+
if (node instanceof WhileLoop) return ssrResidueEstimate(node.bodyTemplate);
|
|
28725
|
+
if (node instanceof SwitchBlock) {
|
|
28726
|
+
let max = 0;
|
|
28727
|
+
for (const c of node.cases) max = Math.max(max, ssrResidueEstimate(c.body));
|
|
28728
|
+
return max;
|
|
28729
|
+
}
|
|
28730
|
+
if (node instanceof TryCatch) {
|
|
28731
|
+
return Math.max(ssrResidueEstimate(node.bodyTemplate), ssrResidueEstimate(node.catchBody));
|
|
28732
|
+
}
|
|
28733
|
+
return 0;
|
|
28734
|
+
}
|
|
28605
28735
|
function isStaticIR(body) {
|
|
28606
28736
|
for (const node of body) {
|
|
28607
28737
|
if (node instanceof StaticNode) {
|
|
@@ -28831,6 +28961,7 @@ var init_client_codegen = __esm({
|
|
|
28831
28961
|
init_server_utils();
|
|
28832
28962
|
init_module_imports();
|
|
28833
28963
|
init_scan();
|
|
28964
|
+
init_tokens();
|
|
28834
28965
|
init_md_inline();
|
|
28835
28966
|
init_strip_ts();
|
|
28836
28967
|
NON_BUBBLING_EVENTS = /* @__PURE__ */ new Set([
|
|
@@ -28872,6 +29003,11 @@ var init_client_codegen = __esm({
|
|
|
28872
29003
|
c = 0;
|
|
28873
29004
|
importedNames = /* @__PURE__ */ new Set();
|
|
28874
29005
|
linkNames = /* @__PURE__ */ new Set();
|
|
29006
|
+
// Runtime component imports that claim their own SSR root via `nextElement`
|
|
29007
|
+
// (Link/NavLink/Md/Form/Field/LoadingIndicator) and return a DocumentFragment
|
|
29008
|
+
// when claimed. They need no call-site adoption guard — the guard targets
|
|
29009
|
+
// genuinely-plain components that never touch the walker.
|
|
29010
|
+
selfClaimNames = /* @__PURE__ */ new Set();
|
|
28875
29011
|
delegatedEvents = /* @__PURE__ */ new Set();
|
|
28876
29012
|
directEvents = /* @__PURE__ */ new Set();
|
|
28877
29013
|
hydrate = false;
|
|
@@ -29260,7 +29396,7 @@ function componentCallToJS(node, importedNames, isAsync = false, tracked2) {
|
|
|
29260
29396
|
lines.push(`const ${calleeVar} = ${callee};`);
|
|
29261
29397
|
const callExpr3 = `${awaitKw}${calleeVar}(${propsObj}, __registry, (${calleeVar}.__veskScope || __vesk))`;
|
|
29262
29398
|
if (__vskHydrate) {
|
|
29263
|
-
lines.push(`__out.push(${JSON.stringify(HYDRATE_COMPONENT_WRAPPER)} + (${callExpr3} || '')
|
|
29399
|
+
lines.push(`__out.push(${JSON.stringify(HYDRATE_COMPONENT_WRAPPER)} + (${callExpr3} || ''));`);
|
|
29264
29400
|
} else {
|
|
29265
29401
|
lines.push(`__out.push(${callExpr3} || '');`);
|
|
29266
29402
|
}
|
|
@@ -29364,7 +29500,7 @@ var init_server_jsgen = __esm({
|
|
|
29364
29500
|
init_scan();
|
|
29365
29501
|
init_server_utils();
|
|
29366
29502
|
init_module_imports();
|
|
29367
|
-
HYDRATE_COMPONENT_WRAPPER =
|
|
29503
|
+
HYDRATE_COMPONENT_WRAPPER = "<!--vsk-->";
|
|
29368
29504
|
__currentCompName = "";
|
|
29369
29505
|
}
|
|
29370
29506
|
});
|
|
@@ -40811,6 +40947,7 @@ init_actions();
|
|
|
40811
40947
|
init_server_utils();
|
|
40812
40948
|
init_module_imports();
|
|
40813
40949
|
init_scan();
|
|
40950
|
+
init_tokens();
|
|
40814
40951
|
init_md_inline();
|
|
40815
40952
|
init_strip_ts();
|
|
40816
40953
|
import { walk as walk6 } from "zimmerframe";
|
|
@@ -41032,6 +41169,11 @@ var Ctx2 = class {
|
|
|
41032
41169
|
c = 0;
|
|
41033
41170
|
importedNames = /* @__PURE__ */ new Set();
|
|
41034
41171
|
linkNames = /* @__PURE__ */ new Set();
|
|
41172
|
+
// Runtime component imports that claim their own SSR root via `nextElement`
|
|
41173
|
+
// (Link/NavLink/Md/Form/Field/LoadingIndicator) and return a DocumentFragment
|
|
41174
|
+
// when claimed. They need no call-site adoption guard — the guard targets
|
|
41175
|
+
// genuinely-plain components that never touch the walker.
|
|
41176
|
+
selfClaimNames = /* @__PURE__ */ new Set();
|
|
41035
41177
|
delegatedEvents = /* @__PURE__ */ new Set();
|
|
41036
41178
|
directEvents = /* @__PURE__ */ new Set();
|
|
41037
41179
|
hydrate = false;
|
|
@@ -41189,15 +41331,21 @@ function emitStatic2(ctx2, node, tracked2, effectsVar) {
|
|
|
41189
41331
|
ctx2.push(`${el}.setAttribute(${JSON.stringify(attr.name)}, ${JSON.stringify(escapeHtml5(attr.value))});`);
|
|
41190
41332
|
}
|
|
41191
41333
|
}
|
|
41334
|
+
let residueBefore = 0;
|
|
41192
41335
|
for (const child of children) {
|
|
41193
41336
|
const childVar = emitNode2(ctx2, child, tracked2, effectsVar, el);
|
|
41194
41337
|
if (childVar) {
|
|
41195
41338
|
if (ctx2.hydrate) {
|
|
41196
|
-
|
|
41339
|
+
if (child instanceof TextNode || child instanceof DynamicBinding) {
|
|
41340
|
+
ctx2.push(`if (${childVar}.parentNode !== ${el}) { const __ssr = ${el}.__vsk_ssrEls || []; if (${residueBefore} < __ssr.length) ${el}.insertBefore(${childVar}, __ssr[${residueBefore}]); else ${el}.appendChild(${childVar}); }`);
|
|
41341
|
+
} else {
|
|
41342
|
+
ctx2.push(`if (${childVar}.parentNode !== ${el}) { if (!${el} || ${childVar}.parentNode == null || !${el}.contains(${childVar})) ${el}.appendChild(${childVar}); }`);
|
|
41343
|
+
}
|
|
41197
41344
|
} else {
|
|
41198
41345
|
ctx2.push(`${el}.appendChild(${childVar});`);
|
|
41199
41346
|
}
|
|
41200
41347
|
}
|
|
41348
|
+
residueBefore += ssrResidueEstimate2(child);
|
|
41201
41349
|
}
|
|
41202
41350
|
for (const attr of dynAttrs) {
|
|
41203
41351
|
const target = attr.target || "";
|
|
@@ -41388,23 +41536,30 @@ function emitComponentCall2(ctx2, node, tracked2, effectsVar, parentVar, compPre
|
|
|
41388
41536
|
}
|
|
41389
41537
|
const propsObj = `{ ${propsEntries.join(", ")} }`;
|
|
41390
41538
|
const v = ctx2.n();
|
|
41391
|
-
const awaitKw = ctx2.
|
|
41539
|
+
const awaitKw = ctx2.isAsyncScope ? "await " : "";
|
|
41392
41540
|
const calleeExpr = node.calleeExpr ? `(${node.calleeExpr})` : null;
|
|
41393
41541
|
if (ctx2.hydrate) {
|
|
41394
41542
|
const access = calleeExpr ?? (ctx2.importedNames.has(node.componentName) ? node.componentName : `__components[${JSON.stringify(node.componentName)}]`);
|
|
41395
|
-
const
|
|
41543
|
+
const plainTarget = !!(calleeExpr || ctx2.importedNames.has(node.componentName)) && !ctx2.selfClaimNames.has(node.componentName);
|
|
41544
|
+
const walkerArg = ctx2.walker;
|
|
41545
|
+
const maybeReplace = (v2) => {
|
|
41546
|
+
if (!plainTarget)
|
|
41547
|
+
return;
|
|
41548
|
+
ctx2.push(`if (${v2} && ${v2}.parentNode == null && ${v2}.nodeType !== 11) { const __sr = ${walkerArg}.claimOnly(); if (__sr && __sr.parentNode) __sr.parentNode.replaceChild(${v2}, __sr); }`);
|
|
41549
|
+
};
|
|
41550
|
+
const maybeRetire = () => {
|
|
41551
|
+
if (ctx2.selfClaimNames.has(node.componentName)) {
|
|
41552
|
+
ctx2.push(`${walkerArg}.retireDetached();`);
|
|
41553
|
+
}
|
|
41554
|
+
};
|
|
41396
41555
|
if (node.children.length > 0) {
|
|
41397
|
-
const walkerVar = ctx2.n();
|
|
41398
|
-
ctx2.push(`const ${walkerVar} = ${subScope()};`);
|
|
41399
41556
|
const frag = ctx2.n();
|
|
41400
41557
|
ctx2.push(`const ${frag} = (() => { const $f = document.createDocumentFragment();`);
|
|
41401
|
-
const savedWalker = ctx2.walker;
|
|
41402
41558
|
const savedEffects = ctx2.effects;
|
|
41403
41559
|
const wipeMount = ctx2.linkNames.has(node.componentName);
|
|
41404
41560
|
const savedHydrate = ctx2.hydrate;
|
|
41405
41561
|
if (wipeMount)
|
|
41406
41562
|
ctx2.hydrate = false;
|
|
41407
|
-
ctx2.walker = walkerVar;
|
|
41408
41563
|
ctx2.effects = [];
|
|
41409
41564
|
for (const child of node.children) {
|
|
41410
41565
|
const childVar = emitNode2(ctx2, child, tracked2, effectsVar, "$f");
|
|
@@ -41414,14 +41569,17 @@ function emitComponentCall2(ctx2, node, tracked2, effectsVar, parentVar, compPre
|
|
|
41414
41569
|
for (const eff of ctx2.effects)
|
|
41415
41570
|
ctx2.push(effectsVar ? `${effectsVar}.push(${effectBlockToHandlerExpr2(eff)});` : eff);
|
|
41416
41571
|
ctx2.effects = savedEffects;
|
|
41417
|
-
ctx2.walker = savedWalker;
|
|
41418
41572
|
ctx2.hydrate = savedHydrate;
|
|
41419
41573
|
ctx2.push(`return $f; })();`);
|
|
41420
41574
|
propsEntries.push(`children: ${frag}`);
|
|
41421
|
-
ctx2.push(`const ${v} = ${awaitKw}${access}({ ${propsEntries.join(", ")} }, __registry, ${
|
|
41575
|
+
ctx2.push(`const ${v} = ${awaitKw}${access}({ ${propsEntries.join(", ")} }, __registry, ${walkerArg});`);
|
|
41576
|
+
maybeReplace(v);
|
|
41577
|
+
maybeRetire();
|
|
41422
41578
|
return v;
|
|
41423
41579
|
}
|
|
41424
|
-
ctx2.push(`const ${v} = ${awaitKw}${access}(${propsObj}, __registry, ${
|
|
41580
|
+
ctx2.push(`const ${v} = ${awaitKw}${access}(${propsObj}, __registry, ${walkerArg});`);
|
|
41581
|
+
maybeReplace(v);
|
|
41582
|
+
maybeRetire();
|
|
41425
41583
|
return v;
|
|
41426
41584
|
} else {
|
|
41427
41585
|
if (node.children.length > 0) {
|
|
@@ -42235,11 +42393,12 @@ ${renderAllItems(" ", null)}
|
|
|
42235
42393
|
function computeAsyncComponents2(comps) {
|
|
42236
42394
|
return new Set(comps.filter((c) => c.isAsync).map((c) => c.name));
|
|
42237
42395
|
}
|
|
42238
|
-
function generateComponent2(comp, importedNames = /* @__PURE__ */ new Set(), hydrate = false, asyncComps = /* @__PURE__ */ new Set(), linkNames = /* @__PURE__ */ new Set()) {
|
|
42396
|
+
function generateComponent2(comp, importedNames = /* @__PURE__ */ new Set(), hydrate = false, asyncComps = /* @__PURE__ */ new Set(), linkNames = /* @__PURE__ */ new Set(), selfClaimNames = /* @__PURE__ */ new Set()) {
|
|
42239
42397
|
const tracked2 = collectTrackedNames2(comp.body);
|
|
42240
42398
|
const ctx2 = new Ctx2();
|
|
42241
42399
|
ctx2.importedNames = importedNames;
|
|
42242
42400
|
ctx2.linkNames = linkNames;
|
|
42401
|
+
ctx2.selfClaimNames = selfClaimNames;
|
|
42243
42402
|
ctx2.hydrate = hydrate;
|
|
42244
42403
|
ctx2.asyncComps = asyncComps;
|
|
42245
42404
|
ctx2.isAsyncScope = comp.isAsync || asyncComps.has(comp.name);
|
|
@@ -42264,10 +42423,17 @@ function generateComponent2(comp, importedNames = /* @__PURE__ */ new Set(), hyd
|
|
|
42264
42423
|
if (paramInit)
|
|
42265
42424
|
ctx2.push(indent3(paramInit));
|
|
42266
42425
|
for (const node of comp.body) {
|
|
42426
|
+
if (node instanceof TrackDecl) {
|
|
42427
|
+
emitNode2(ctx2, node, tracked2, null);
|
|
42428
|
+
}
|
|
42429
|
+
}
|
|
42430
|
+
for (const node of comp.body) {
|
|
42431
|
+
if (node instanceof TrackDecl)
|
|
42432
|
+
continue;
|
|
42267
42433
|
const v = emitNode2(ctx2, node, tracked2, null);
|
|
42268
42434
|
if (v) {
|
|
42269
42435
|
if (ctx2.hydrate) {
|
|
42270
|
-
ctx2.push(indent3(`if (${v}.parentNode !== $root) { if (!$root || ${v}.parentNode == null || !$
|
|
42436
|
+
ctx2.push(indent3(`if (${v}.parentNode !== $root) { if (!$root || ${v}.parentNode == null || !${v}.parentNode.contains(${v})) $root.appendChild(${v}); }`));
|
|
42271
42437
|
} else {
|
|
42272
42438
|
ctx2.push(indent3(`$root.appendChild(${v});`));
|
|
42273
42439
|
}
|
|
@@ -42298,7 +42464,15 @@ function buildComponentMap3(irRoot, hydrate = false) {
|
|
|
42298
42464
|
mapLines.push(`const __components = {};`);
|
|
42299
42465
|
const asyncComps = computeAsyncComponents2(irRoot.components);
|
|
42300
42466
|
const linkNames = /* @__PURE__ */ new Set();
|
|
42467
|
+
const selfClaimNames = /* @__PURE__ */ new Set();
|
|
42468
|
+
const SELF_CLAIM_RUNTIME = /* @__PURE__ */ new Set(["Link", "NavLink", "Md", "Form", "Field", "LoadingIndicator"]);
|
|
42301
42469
|
for (const imp of irRoot.imports) {
|
|
42470
|
+
if (importModuleTarget(imp) !== "@vesk/runtime")
|
|
42471
|
+
continue;
|
|
42472
|
+
for (const pair of importBindingPairs(imp)) {
|
|
42473
|
+
if (SELF_CLAIM_RUNTIME.has(pair.imported))
|
|
42474
|
+
selfClaimNames.add(pair.local);
|
|
42475
|
+
}
|
|
42302
42476
|
for (const pair of importBindingPairs(imp)) {
|
|
42303
42477
|
if (pair.imported === "Link" || pair.imported === "NavLink")
|
|
42304
42478
|
linkNames.add(pair.local);
|
|
@@ -42309,11 +42483,11 @@ function buildComponentMap3(irRoot, hydrate = false) {
|
|
|
42309
42483
|
const directNames = /* @__PURE__ */ new Set([...extractRuntimeNames(irRoot.imports), ...localValueImportNames(irRoot.imports), ...topValueNames]);
|
|
42310
42484
|
for (const comp of irRoot.components) {
|
|
42311
42485
|
if (hydrate && isStaticComponent2(comp)) {
|
|
42312
|
-
const stub = `(props, __registry, __hydrate) => { return __hydrate.
|
|
42486
|
+
const stub = `(props, __registry, __hydrate) => { return __hydrate.claimOnly(); }`;
|
|
42313
42487
|
mapLines.push(`__components[${JSON.stringify(comp.name)}] = ${stub};`);
|
|
42314
42488
|
continue;
|
|
42315
42489
|
}
|
|
42316
|
-
const code = generateComponent2(comp, directNames, hydrate, asyncComps, linkNames);
|
|
42490
|
+
const code = generateComponent2(comp, directNames, hydrate, asyncComps, linkNames, selfClaimNames);
|
|
42317
42491
|
mapLines.push(`__components[${JSON.stringify(comp.name)}] = ${code};`);
|
|
42318
42492
|
}
|
|
42319
42493
|
mapLines.push(`function __cleanup(start, end) {`);
|
|
@@ -42342,6 +42516,38 @@ function buildComponentMap3(irRoot, hydrate = false) {
|
|
|
42342
42516
|
mapLines.push(`}`);
|
|
42343
42517
|
return mapLines.join("\n\n");
|
|
42344
42518
|
}
|
|
42519
|
+
function ssrResidueEstimate2(node) {
|
|
42520
|
+
if (Array.isArray(node)) {
|
|
42521
|
+
let total = 0;
|
|
42522
|
+
for (const n of node)
|
|
42523
|
+
total += ssrResidueEstimate2(n);
|
|
42524
|
+
return total;
|
|
42525
|
+
}
|
|
42526
|
+
if (node instanceof StaticNode)
|
|
42527
|
+
return 1;
|
|
42528
|
+
if (node instanceof ComponentCall)
|
|
42529
|
+
return 1;
|
|
42530
|
+
if (node instanceof OpaqueDynamicRegion) {
|
|
42531
|
+
return Math.max(ssrResidueEstimate2(node.consequentNodes), ssrResidueEstimate2(node.alternateNodes));
|
|
42532
|
+
}
|
|
42533
|
+
if (node instanceof MapRegion) {
|
|
42534
|
+
return Math.max(ssrResidueEstimate2(node.bodyTemplate), ssrResidueEstimate2(node.alternateNodes));
|
|
42535
|
+
}
|
|
42536
|
+
if (node instanceof ForLoop)
|
|
42537
|
+
return ssrResidueEstimate2(node.bodyTemplate);
|
|
42538
|
+
if (node instanceof WhileLoop)
|
|
42539
|
+
return ssrResidueEstimate2(node.bodyTemplate);
|
|
42540
|
+
if (node instanceof SwitchBlock) {
|
|
42541
|
+
let max = 0;
|
|
42542
|
+
for (const c of node.cases)
|
|
42543
|
+
max = Math.max(max, ssrResidueEstimate2(c.body));
|
|
42544
|
+
return max;
|
|
42545
|
+
}
|
|
42546
|
+
if (node instanceof TryCatch) {
|
|
42547
|
+
return Math.max(ssrResidueEstimate2(node.bodyTemplate), ssrResidueEstimate2(node.catchBody));
|
|
42548
|
+
}
|
|
42549
|
+
return 0;
|
|
42550
|
+
}
|
|
42345
42551
|
function isStaticIR2(body) {
|
|
42346
42552
|
for (const node of body) {
|
|
42347
42553
|
if (node instanceof StaticNode) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/vesk-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.26",
|
|
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.26",
|
|
12
|
+
"@vesk/compiler": "^0.2.26",
|
|
13
|
+
"@vesk/plugin-tailwind": "^0.2.26",
|
|
14
|
+
"@vesk/runtime": "^0.2.26",
|
|
15
15
|
"esrap": "^2.3.0",
|
|
16
16
|
"typescript": "^5.8.0",
|
|
17
17
|
"ws": "^8.18.0",
|