@vesk/compiler 0.2.24 → 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/client-codegen.d.ts.map +1 -1
- package/dist/client-codegen.js +117 -16
- package/dist/server-jsgen.d.ts.map +1 -1
- package/dist/server-jsgen.js +9 -11
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-codegen.d.ts","sourceRoot":"","sources":["../src/client-codegen.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAGL,cAAc,EAQd,gBAAgB,EAOjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"client-codegen.d.ts","sourceRoot":"","sources":["../src/client-codegen.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAGL,cAAc,EAQd,gBAAgB,EAOjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAyCxD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1D;AAiDD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,gBAAgB,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CAwGlI;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAU5E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CAY5F;AAk8CD,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAe3C;AA2HD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO9C;AAqED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CAAO,GAAG,MAAM,CAOnN;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAqBxJ;AAED,OAAO,EAAE,aAAa,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
package/dist/client-codegen.js
CHANGED
|
@@ -9,6 +9,7 @@ import { transformTopLevelForActions } from '@vesk/compiler/src/actions';
|
|
|
9
9
|
import { extractRuntimeNames, extractTopLevelNames } from '@vesk/compiler/src/server-utils';
|
|
10
10
|
import { importBindingPairs, localValueImportNames } from '@vesk/compiler/src/module-imports';
|
|
11
11
|
import { stripTrackGeneric } from '@vesk/compiler/src/scan';
|
|
12
|
+
import { importModuleTarget } from '@vesk/compiler/src/tokens';
|
|
12
13
|
import { inlineMdImportsFrom } from '@vesk/compiler/src/md-inline';
|
|
13
14
|
import { stripTsTypes, hasTsSyntax } from '@vesk/compiler/src/strip-ts';
|
|
14
15
|
function memberExpr(object, property) {
|
|
@@ -253,6 +254,11 @@ class Ctx {
|
|
|
253
254
|
c = 0;
|
|
254
255
|
importedNames = new Set();
|
|
255
256
|
linkNames = new Set();
|
|
257
|
+
// Runtime component imports that claim their own SSR root via `nextElement`
|
|
258
|
+
// (Link/NavLink/Md/Form/Field/LoadingIndicator) and return a DocumentFragment
|
|
259
|
+
// when claimed. They need no call-site adoption guard — the guard targets
|
|
260
|
+
// genuinely-plain components that never touch the walker.
|
|
261
|
+
selfClaimNames = new Set();
|
|
256
262
|
delegatedEvents = new Set();
|
|
257
263
|
directEvents = new Set();
|
|
258
264
|
hydrate = false;
|
|
@@ -412,16 +418,33 @@ function emitStatic(ctx, node, tracked, effectsVar) {
|
|
|
412
418
|
ctx.push(`${el}.setAttribute(${JSON.stringify(attr.name)}, ${JSON.stringify(escapeHtml(attr.value))});`);
|
|
413
419
|
}
|
|
414
420
|
}
|
|
421
|
+
let residueBefore = 0;
|
|
415
422
|
for (const child of children) {
|
|
416
423
|
const childVar = emitNode(ctx, child, tracked, effectsVar, el);
|
|
417
424
|
if (childVar) {
|
|
418
425
|
if (ctx.hydrate) {
|
|
419
|
-
|
|
426
|
+
// Fresh text nodes (static or dynamic) cannot be appended at the end of
|
|
427
|
+
// a claimed element: its SSR element children (component-boundary
|
|
428
|
+
// wrappers, skipped static markup) are still in the DOM at their SSR
|
|
429
|
+
// slots, so appending would move the text AFTER them, reordering
|
|
430
|
+
// mixed text + component children (the hero "compiler-first framework ·
|
|
431
|
+
// <VersionBadge />" label). Insert the fresh node at the SSR position
|
|
432
|
+
// of the text instead: the k-th source text child precedes the residue
|
|
433
|
+
// elements rendered before it, so it slots in before
|
|
434
|
+
// `el.__vsk_ssrEls[k]` (the residue list captured by the runtime at
|
|
435
|
+
// claim time).
|
|
436
|
+
if (child instanceof TextNode || child instanceof DynamicBinding) {
|
|
437
|
+
ctx.push(`if (${childVar}.parentNode !== ${el}) { const __ssr = ${el}.__vsk_ssrEls || []; if (${residueBefore} < __ssr.length) ${el}.insertBefore(${childVar}, __ssr[${residueBefore}]); else ${el}.appendChild(${childVar}); }`);
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
ctx.push(`if (${childVar}.parentNode !== ${el}) { if (!${el} || ${childVar}.parentNode == null || !${el}.contains(${childVar})) ${el}.appendChild(${childVar}); }`);
|
|
441
|
+
}
|
|
420
442
|
}
|
|
421
443
|
else {
|
|
422
444
|
ctx.push(`${el}.appendChild(${childVar});`);
|
|
423
445
|
}
|
|
424
446
|
}
|
|
447
|
+
residueBefore += ssrResidueEstimate(child);
|
|
425
448
|
}
|
|
426
449
|
for (const attr of dynAttrs) {
|
|
427
450
|
const target = attr.target || '';
|
|
@@ -640,7 +663,11 @@ function emitComponentCall(ctx, node, tracked, effectsVar, parentVar, compPrefix
|
|
|
640
663
|
}
|
|
641
664
|
const propsObj = `{ ${propsEntries.join(', ')} }`;
|
|
642
665
|
const v = ctx.n();
|
|
643
|
-
|
|
666
|
+
// Await children whenever the calling scope is async. Async-ness is
|
|
667
|
+
// parent-driven (mirroring the server side) so that imported async
|
|
668
|
+
// components from other files — whose names are not in the local
|
|
669
|
+
// asyncComps set — still resolve to nodes before append/insert.
|
|
670
|
+
const awaitKw = ctx.isAsyncScope ? 'await ' : '';
|
|
644
671
|
// Member-expression tags (`<it.icon>`) carry the raw component-valued
|
|
645
672
|
// expression — invoke it directly; it is never a registry name.
|
|
646
673
|
const calleeExpr = node.calleeExpr ? `(${node.calleeExpr})` : null;
|
|
@@ -649,15 +676,30 @@ function emitComponentCall(ctx, node, tracked, effectsVar, parentVar, compPrefix
|
|
|
649
676
|
?? (ctx.importedNames.has(node.componentName)
|
|
650
677
|
? node.componentName
|
|
651
678
|
: `__components[${JSON.stringify(node.componentName)}]`);
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
679
|
+
// SSR for component calls is marker-ONLY (`<!--vsk-->` + the component's
|
|
680
|
+
// own root; no display:contents wrapper). Compiled `.vsk` components claim
|
|
681
|
+
// their own root on the SHARED walker. Call targets that are not known
|
|
682
|
+
// compiled components (imported values, member-expression tags) cannot
|
|
683
|
+
// claim, so after the call we adopt their SSR root ourselves and replace it
|
|
684
|
+
// with the fresh node they returned — never a duplicate, never a box.
|
|
685
|
+
const plainTarget = !!(calleeExpr || ctx.importedNames.has(node.componentName)) && !ctx.selfClaimNames.has(node.componentName);
|
|
686
|
+
const walkerArg = ctx.walker;
|
|
687
|
+
const maybeReplace = (v) => {
|
|
688
|
+
if (!plainTarget)
|
|
689
|
+
return;
|
|
690
|
+
// nodeType 11 = DocumentFragment: self-claiming imports (Link/Md/Form)
|
|
691
|
+
// return a fragment when they adopted their SSR root, so there is nothing
|
|
692
|
+
// to replace — claiming here would steal the NEXT sibling's root.
|
|
693
|
+
ctx.push(`if (${v} && ${v}.parentNode == null && ${v}.nodeType !== 11) { const __sr = ${walkerArg}.claimOnly(); if (__sr && __sr.parentNode) __sr.parentNode.replaceChild(${v}, __sr); }`);
|
|
694
|
+
};
|
|
695
|
+
const maybeRetire = () => {
|
|
696
|
+
if (ctx.selfClaimNames.has(node.componentName)) {
|
|
697
|
+
ctx.push(`${walkerArg}.retireDetached();`);
|
|
698
|
+
}
|
|
699
|
+
};
|
|
655
700
|
if (node.children.length > 0) {
|
|
656
|
-
const walkerVar = ctx.n();
|
|
657
|
-
ctx.push(`const ${walkerVar} = ${subScope()};`);
|
|
658
701
|
const frag = ctx.n();
|
|
659
702
|
ctx.push(`const ${frag} = (() => { const $f = document.createDocumentFragment();`);
|
|
660
|
-
const savedWalker = ctx.walker;
|
|
661
703
|
const savedEffects = ctx.effects;
|
|
662
704
|
// Link/NavLink hydrate branches WIPE their SSR anchor (a.replaceChildren())
|
|
663
705
|
// and remount the children fragment. Suppressed fully-static children would
|
|
@@ -666,7 +708,6 @@ function emitComponentCall(ctx, node, tracked, effectsVar, parentVar, compPrefix
|
|
|
666
708
|
const savedHydrate = ctx.hydrate;
|
|
667
709
|
if (wipeMount)
|
|
668
710
|
ctx.hydrate = false;
|
|
669
|
-
ctx.walker = walkerVar;
|
|
670
711
|
ctx.effects = [];
|
|
671
712
|
for (const child of node.children) {
|
|
672
713
|
const childVar = emitNode(ctx, child, tracked, effectsVar, '$f');
|
|
@@ -676,14 +717,17 @@ function emitComponentCall(ctx, node, tracked, effectsVar, parentVar, compPrefix
|
|
|
676
717
|
for (const eff of ctx.effects)
|
|
677
718
|
ctx.push(effectsVar ? `${effectsVar}.push(${effectBlockToHandlerExpr(eff)});` : eff);
|
|
678
719
|
ctx.effects = savedEffects;
|
|
679
|
-
ctx.walker = savedWalker;
|
|
680
720
|
ctx.hydrate = savedHydrate;
|
|
681
721
|
ctx.push(`return $f; })();`);
|
|
682
722
|
propsEntries.push(`children: ${frag}`);
|
|
683
|
-
ctx.push(`const ${v} = ${awaitKw}${access}({ ${propsEntries.join(', ')} }, __registry, ${
|
|
723
|
+
ctx.push(`const ${v} = ${awaitKw}${access}({ ${propsEntries.join(', ')} }, __registry, ${walkerArg});`);
|
|
724
|
+
maybeReplace(v);
|
|
725
|
+
maybeRetire();
|
|
684
726
|
return v;
|
|
685
727
|
}
|
|
686
|
-
ctx.push(`const ${v} = ${awaitKw}${access}(${propsObj}, __registry, ${
|
|
728
|
+
ctx.push(`const ${v} = ${awaitKw}${access}(${propsObj}, __registry, ${walkerArg});`);
|
|
729
|
+
maybeReplace(v);
|
|
730
|
+
maybeRetire();
|
|
687
731
|
return v;
|
|
688
732
|
}
|
|
689
733
|
else {
|
|
@@ -1567,11 +1611,12 @@ ${renderAllItems(' ', null)}
|
|
|
1567
1611
|
function computeAsyncComponents(comps) {
|
|
1568
1612
|
return new Set(comps.filter((c) => c.isAsync).map((c) => c.name));
|
|
1569
1613
|
}
|
|
1570
|
-
function generateComponent(comp, importedNames = new Set(), hydrate = false, asyncComps = new Set(), linkNames = new Set()) {
|
|
1614
|
+
function generateComponent(comp, importedNames = new Set(), hydrate = false, asyncComps = new Set(), linkNames = new Set(), selfClaimNames = new Set()) {
|
|
1571
1615
|
const tracked = collectTrackedNames(comp.body);
|
|
1572
1616
|
const ctx = new Ctx();
|
|
1573
1617
|
ctx.importedNames = importedNames;
|
|
1574
1618
|
ctx.linkNames = linkNames;
|
|
1619
|
+
ctx.selfClaimNames = selfClaimNames;
|
|
1575
1620
|
ctx.hydrate = hydrate;
|
|
1576
1621
|
ctx.asyncComps = asyncComps;
|
|
1577
1622
|
ctx.isAsyncScope = comp.isAsync || asyncComps.has(comp.name);
|
|
@@ -1596,11 +1641,19 @@ function generateComponent(comp, importedNames = new Set(), hydrate = false, asy
|
|
|
1596
1641
|
const paramInit = buildParamInit(comp.paramNames);
|
|
1597
1642
|
if (paramInit)
|
|
1598
1643
|
ctx.push(indent(paramInit));
|
|
1644
|
+
// Hoist TrackDecls to top to avoid TDZ when Head/effects reference them before declaration
|
|
1645
|
+
for (const node of comp.body) {
|
|
1646
|
+
if (node instanceof TrackDecl) {
|
|
1647
|
+
emitNode(ctx, node, tracked, null);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1599
1650
|
for (const node of comp.body) {
|
|
1651
|
+
if (node instanceof TrackDecl)
|
|
1652
|
+
continue;
|
|
1600
1653
|
const v = emitNode(ctx, node, tracked, null);
|
|
1601
1654
|
if (v) {
|
|
1602
1655
|
if (ctx.hydrate) {
|
|
1603
|
-
ctx.push(indent(`if (${v}.parentNode !== $root) { if (!$root || ${v}.parentNode == null || !$
|
|
1656
|
+
ctx.push(indent(`if (${v}.parentNode !== $root) { if (!$root || ${v}.parentNode == null || !${v}.parentNode.contains(${v})) $root.appendChild(${v}); }`));
|
|
1604
1657
|
}
|
|
1605
1658
|
else {
|
|
1606
1659
|
ctx.push(indent(`$root.appendChild(${v});`));
|
|
@@ -1635,7 +1688,19 @@ function buildComponentMap(irRoot, hydrate = false) {
|
|
|
1635
1688
|
// hydration, so their children fragments must be rebuilt in full. Track the
|
|
1636
1689
|
// file-local binding names regardless of aliasing (`const Nav = NavLink`).
|
|
1637
1690
|
const linkNames = new Set();
|
|
1691
|
+
// Runtime components that self-claim during hydration (adopt their own SSR
|
|
1692
|
+
// root via nextElement and return a fragment when claimed). Excluded from the
|
|
1693
|
+
// call-site adoption guard; the walker cursor passes them but never a
|
|
1694
|
+
// claimOnly() on their behalf.
|
|
1695
|
+
const selfClaimNames = new Set();
|
|
1696
|
+
const SELF_CLAIM_RUNTIME = new Set(['Link', 'NavLink', 'Md', 'Form', 'Field', 'LoadingIndicator']);
|
|
1638
1697
|
for (const imp of irRoot.imports) {
|
|
1698
|
+
if (importModuleTarget(imp) !== '@vesk/runtime')
|
|
1699
|
+
continue;
|
|
1700
|
+
for (const pair of importBindingPairs(imp)) {
|
|
1701
|
+
if (SELF_CLAIM_RUNTIME.has(pair.imported))
|
|
1702
|
+
selfClaimNames.add(pair.local);
|
|
1703
|
+
}
|
|
1639
1704
|
for (const pair of importBindingPairs(imp)) {
|
|
1640
1705
|
if (pair.imported === 'Link' || pair.imported === 'NavLink')
|
|
1641
1706
|
linkNames.add(pair.local);
|
|
@@ -1650,11 +1715,13 @@ function buildComponentMap(irRoot, hydrate = false) {
|
|
|
1650
1715
|
const directNames = new Set([...extractRuntimeNames(irRoot.imports), ...localValueImportNames(irRoot.imports), ...topValueNames]);
|
|
1651
1716
|
for (const comp of irRoot.components) {
|
|
1652
1717
|
if (hydrate && isStaticComponent(comp)) {
|
|
1653
|
-
|
|
1718
|
+
// Static components keep their SSR content untouched: claim the root
|
|
1719
|
+
// WITHOUT stripping its direct text (nothing will re-create it).
|
|
1720
|
+
const stub = `(props, __registry, __hydrate) => { return __hydrate.claimOnly(); }`;
|
|
1654
1721
|
mapLines.push(`__components[${JSON.stringify(comp.name)}] = ${stub};`);
|
|
1655
1722
|
continue;
|
|
1656
1723
|
}
|
|
1657
|
-
const code = generateComponent(comp, directNames, hydrate, asyncComps, linkNames);
|
|
1724
|
+
const code = generateComponent(comp, directNames, hydrate, asyncComps, linkNames, selfClaimNames);
|
|
1658
1725
|
mapLines.push(`__components[${JSON.stringify(comp.name)}] = ${code};`);
|
|
1659
1726
|
}
|
|
1660
1727
|
mapLines.push(`function __cleanup(start, end) {`);
|
|
@@ -1683,6 +1750,40 @@ function buildComponentMap(irRoot, hydrate = false) {
|
|
|
1683
1750
|
mapLines.push(`}`);
|
|
1684
1751
|
return mapLines.join('\n\n');
|
|
1685
1752
|
}
|
|
1753
|
+
function ssrResidueEstimate(node) {
|
|
1754
|
+
if (Array.isArray(node)) {
|
|
1755
|
+
let total = 0;
|
|
1756
|
+
for (const n of node)
|
|
1757
|
+
total += ssrResidueEstimate(n);
|
|
1758
|
+
return total;
|
|
1759
|
+
}
|
|
1760
|
+
if (node instanceof StaticNode)
|
|
1761
|
+
return 1;
|
|
1762
|
+
if (node instanceof ComponentCall)
|
|
1763
|
+
return 1;
|
|
1764
|
+
if (node instanceof OpaqueDynamicRegion) {
|
|
1765
|
+
return Math.max(ssrResidueEstimate(node.consequentNodes), ssrResidueEstimate(node.alternateNodes));
|
|
1766
|
+
}
|
|
1767
|
+
if (node instanceof MapRegion) {
|
|
1768
|
+
return Math.max(ssrResidueEstimate(node.bodyTemplate), ssrResidueEstimate(node.alternateNodes));
|
|
1769
|
+
}
|
|
1770
|
+
if (node instanceof ForLoop)
|
|
1771
|
+
return ssrResidueEstimate(node.bodyTemplate);
|
|
1772
|
+
if (node instanceof WhileLoop)
|
|
1773
|
+
return ssrResidueEstimate(node.bodyTemplate);
|
|
1774
|
+
if (node instanceof SwitchBlock) {
|
|
1775
|
+
let max = 0;
|
|
1776
|
+
for (const c of node.cases)
|
|
1777
|
+
max = Math.max(max, ssrResidueEstimate(c.body));
|
|
1778
|
+
return max;
|
|
1779
|
+
}
|
|
1780
|
+
if (node instanceof TryCatch) {
|
|
1781
|
+
return Math.max(ssrResidueEstimate(node.bodyTemplate), ssrResidueEstimate(node.catchBody));
|
|
1782
|
+
}
|
|
1783
|
+
// TextNode, DynamicBinding, TrackDecl, RuntimeStatement, SlotNode,
|
|
1784
|
+
// ServerBlock, ClientBlock, HeadBlock emit no SSR element residue.
|
|
1785
|
+
return 0;
|
|
1786
|
+
}
|
|
1686
1787
|
function isStaticIR(body) {
|
|
1687
1788
|
for (const node of body) {
|
|
1688
1789
|
if (node instanceof StaticNode) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-jsgen.d.ts","sourceRoot":"","sources":["../src/server-jsgen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAOzE,OAAO,EAAkG,KAAK,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAoCrK,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,OAAO,GAAE,OAAe,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CAmDjJ;
|
|
1
|
+
{"version":3,"file":"server-jsgen.d.ts","sourceRoot":"","sources":["../src/server-jsgen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAOzE,OAAO,EAAkG,KAAK,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAoCrK,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,OAAO,GAAE,OAAe,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CAmDjJ;AAoWD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAmD1F;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CA4BzE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAYhG"}
|
package/dist/server-jsgen.js
CHANGED
|
@@ -19,14 +19,14 @@ import { localValueImportNames } from '@vesk/compiler/src/module-imports';
|
|
|
19
19
|
// the client's for every property, not just sticky.
|
|
20
20
|
//
|
|
21
21
|
// The wrapper tag must be `<span>`, not `<div>`. The HTML parser implicitly
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
const HYDRATE_COMPONENT_WRAPPER = '<!--vsk
|
|
22
|
+
// Marker-ONLY component boundary. The client's shared walker claims a
|
|
23
|
+
// component call-site by reading the component's own root element off this
|
|
24
|
+
// marker — the SSR output of a component call is exactly `<!--vsk-->` followed
|
|
25
|
+
// by the callee's content. A `<span style="display:contents">` box here would
|
|
26
|
+
// sit between the marker and that root, so a `nextElement(tag)` claim (e.g.
|
|
27
|
+
// LoadingIndicator claiming `div`) hits a tag mismatch, never advances the
|
|
28
|
+
// walker cursor, and every later claim miss wipes the SSR content.
|
|
29
|
+
const HYDRATE_COMPONENT_WRAPPER = '<!--vsk-->';
|
|
30
30
|
export function irNodeToJS(node, importedNames, isAsync = false, tracked) {
|
|
31
31
|
importedNames = importedNames || __vskImportedNames;
|
|
32
32
|
if (node instanceof StaticNode)
|
|
@@ -448,9 +448,7 @@ function componentCallToJS(node, importedNames, isAsync = false, tracked) {
|
|
|
448
448
|
lines.push(`const ${calleeVar} = ${callee};`);
|
|
449
449
|
const callExpr = `${awaitKw}${calleeVar}(${propsObj}, __registry, (${calleeVar}.__veskScope || __vesk))`;
|
|
450
450
|
if (__vskHydrate) {
|
|
451
|
-
|
|
452
|
-
// become a layout box (see the constant's comment for why).
|
|
453
|
-
lines.push(`__out.push(${JSON.stringify(HYDRATE_COMPONENT_WRAPPER)} + (${callExpr} || '') + '</span>');`);
|
|
451
|
+
lines.push(`__out.push(${JSON.stringify(HYDRATE_COMPONENT_WRAPPER)} + (${callExpr} || ''));`);
|
|
454
452
|
}
|
|
455
453
|
else {
|
|
456
454
|
lines.push(`__out.push(${callExpr} || '');`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.26",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vesk compiler — lexer, parser, semantic analysis, IR, codegen",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@sveltejs/acorn-typescript": "^1.0.0",
|
|
23
|
-
"@vesk/types": "^0.2.
|
|
23
|
+
"@vesk/types": "^0.2.26",
|
|
24
24
|
"acorn": "^8.15.0",
|
|
25
25
|
"esrap": "^2.3.0",
|
|
26
26
|
"is-reference": "^3.0.0",
|