@vesk/compiler 0.2.10 → 0.2.12
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 +1 -1
- package/dist/client-codegen.d.ts.map +1 -1
- package/dist/client-codegen.js +78 -23
- package/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +35 -2
- package/dist/ir-generator.d.ts +1 -1
- package/dist/ir-generator.d.ts.map +1 -1
- package/dist/ir-generator.js +109 -20
- package/dist/ir.d.ts +8 -1
- package/dist/ir.d.ts.map +1 -1
- package/dist/ir.js +9 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +46 -10
- package/dist/server-jsgen.d.ts.map +1 -1
- package/dist/server-jsgen.js +24 -5
- package/dist/server-render.d.ts +1 -0
- package/dist/server-render.d.ts.map +1 -1
- package/dist/server-render.js +34 -12
- package/package.json +2 -2
package/dist/client-codegen.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare function compileClient(source: string, _componentName: string | n
|
|
|
25
25
|
* `resolveComponentName`, so callers don't need a second full parse just
|
|
26
26
|
* to learn the name.
|
|
27
27
|
*/
|
|
28
|
-
export declare function compileClientBoth(source: string, _componentName: string | null): {
|
|
28
|
+
export declare function compileClientBoth(source: string, _componentName: string | null, sourcePath?: string): {
|
|
29
29
|
comp: string;
|
|
30
30
|
hyd: string;
|
|
31
31
|
name: string | null;
|
|
@@ -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;AAwCxD,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;
|
|
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;AAwCxD,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;AA8kCD,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAe3C;AA2HD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO9C;AAoED,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
|
@@ -6,8 +6,8 @@ import { StaticNode, TextNode, DynamicBinding, OpaqueDynamicRegion, MapRegion, W
|
|
|
6
6
|
import { parse } from '@vesk/compiler/src/parser';
|
|
7
7
|
import { generateIR } from '@vesk/compiler/src/ir-generator';
|
|
8
8
|
import { transformTopLevelForActions } from '@vesk/compiler/src/actions';
|
|
9
|
-
import { extractRuntimeNames } from '@vesk/compiler/src/server-utils';
|
|
10
|
-
import { importBindingPairs } from '@vesk/compiler/src/module-imports';
|
|
9
|
+
import { extractRuntimeNames, extractTopLevelNames } from '@vesk/compiler/src/server-utils';
|
|
10
|
+
import { importBindingPairs, localValueImportNames } from '@vesk/compiler/src/module-imports';
|
|
11
11
|
import { stripTrackGeneric } from '@vesk/compiler/src/scan';
|
|
12
12
|
import { inlineMdImportsFrom } from '@vesk/compiler/src/md-inline';
|
|
13
13
|
import { stripTsTypes, hasTsSyntax } from '@vesk/compiler/src/strip-ts';
|
|
@@ -69,6 +69,36 @@ function containsJsx(node, depth = 0) {
|
|
|
69
69
|
function printAst(ast) {
|
|
70
70
|
return print(ast, containsJsx(ast) ? tsx() : ts()).code;
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Converts a bare effect block (`{ <setup>; effect(fn); }`, the shape every
|
|
74
|
+
* `ctx.effects.push` template produces) into an expression that runs the
|
|
75
|
+
* block immediately and evaluates to the effect handle:
|
|
76
|
+
* `(() => { <setup>; return effect(fn); })()`.
|
|
77
|
+
*
|
|
78
|
+
* Required when an effect is collected into a per-item effects array
|
|
79
|
+
* (`__e.push(<block>)`): a raw block in expression position parses as an
|
|
80
|
+
* object literal, so `let` declarations inside it are a SyntaxError that
|
|
81
|
+
* kills the entire client chunk — and with it hydration for the whole page.
|
|
82
|
+
* Falls back to a value-less IIFE when the block shape is unexpected.
|
|
83
|
+
*/
|
|
84
|
+
function effectBlockToHandlerExpr(eff) {
|
|
85
|
+
try {
|
|
86
|
+
const ast = parse(eff);
|
|
87
|
+
const block = ast.body?.[0];
|
|
88
|
+
const stmts = block?.type === 'BlockStatement' ? block.body ?? [] : [];
|
|
89
|
+
const last = stmts[stmts.length - 1];
|
|
90
|
+
if (last?.type === 'ExpressionStatement' && last.expression) {
|
|
91
|
+
const returning = { ...block, body: [...stmts.slice(0, -1), { type: 'ReturnStatement', argument: last.expression }] };
|
|
92
|
+
const code = printAst(returning);
|
|
93
|
+
if (code)
|
|
94
|
+
return `(() => ${code})()`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// fall through to the value-less IIFE below
|
|
99
|
+
}
|
|
100
|
+
return `(() => ${eff})()`;
|
|
101
|
+
}
|
|
72
102
|
export function transformTracked(irNode, tracked) {
|
|
73
103
|
const ast = irNode.ast;
|
|
74
104
|
if (!ast)
|
|
@@ -260,7 +290,7 @@ function emitNode(ctx, node, tracked, effectsVar, parentVar, compPrefix = '__com
|
|
|
260
290
|
if (node instanceof ComponentCall)
|
|
261
291
|
return emitComponentCall(ctx, node, tracked, effectsVar, parentVar, compPrefix);
|
|
262
292
|
if (node instanceof OpaqueDynamicRegion)
|
|
263
|
-
return emitOpaque(ctx, node, tracked, parentVar);
|
|
293
|
+
return emitOpaque(ctx, node, tracked, effectsVar, parentVar);
|
|
264
294
|
if (node instanceof MapRegion)
|
|
265
295
|
return emitMap(ctx, node, tracked, parentVar);
|
|
266
296
|
if (node instanceof ServerBlock)
|
|
@@ -573,10 +603,14 @@ function emitComponentCall(ctx, node, tracked, effectsVar, parentVar, compPrefix
|
|
|
573
603
|
const propsObj = `{ ${propsEntries.join(', ')} }`;
|
|
574
604
|
const v = ctx.n();
|
|
575
605
|
const awaitKw = ctx.asyncComps.has(node.componentName) ? 'await ' : '';
|
|
606
|
+
// Member-expression tags (`<it.icon>`) carry the raw component-valued
|
|
607
|
+
// expression — invoke it directly; it is never a registry name.
|
|
608
|
+
const calleeExpr = node.calleeExpr ? `(${node.calleeExpr})` : null;
|
|
576
609
|
if (ctx.hydrate) {
|
|
577
|
-
const access =
|
|
578
|
-
|
|
579
|
-
|
|
610
|
+
const access = calleeExpr
|
|
611
|
+
?? (ctx.importedNames.has(node.componentName)
|
|
612
|
+
? node.componentName
|
|
613
|
+
: `__components[${JSON.stringify(node.componentName)}]`);
|
|
580
614
|
const subScope = () => ctx.inTryBody
|
|
581
615
|
? `${ctx.walker}.subWalker(${parentVar})`
|
|
582
616
|
: `${ctx.walker}.subWalker(${ctx.walker}.nextElement())`;
|
|
@@ -595,7 +629,7 @@ function emitComponentCall(ctx, node, tracked, effectsVar, parentVar, compPrefix
|
|
|
595
629
|
ctx.push(`$f.appendChild(${childVar});`);
|
|
596
630
|
}
|
|
597
631
|
for (const eff of ctx.effects)
|
|
598
|
-
ctx.push(effectsVar ? `${effectsVar}.push(${eff});` : eff);
|
|
632
|
+
ctx.push(effectsVar ? `${effectsVar}.push(${effectBlockToHandlerExpr(eff)});` : eff);
|
|
599
633
|
ctx.effects = savedEffects;
|
|
600
634
|
ctx.walker = savedWalker;
|
|
601
635
|
ctx.push(`return $f; })();`);
|
|
@@ -618,12 +652,15 @@ function emitComponentCall(ctx, node, tracked, effectsVar, parentVar, compPrefix
|
|
|
618
652
|
ctx.push(`$f.appendChild(${childVar});`);
|
|
619
653
|
}
|
|
620
654
|
for (const eff of ctx.effects)
|
|
621
|
-
ctx.push(effectsVar ? `${effectsVar}.push(${eff});` : eff);
|
|
655
|
+
ctx.push(effectsVar ? `${effectsVar}.push(${effectBlockToHandlerExpr(eff)});` : eff);
|
|
622
656
|
ctx.effects = savedEffects;
|
|
623
657
|
ctx.push(`return $f; })();`);
|
|
624
658
|
propsEntries.push(`children: ${frag}`);
|
|
625
659
|
}
|
|
626
|
-
if (
|
|
660
|
+
if (calleeExpr) {
|
|
661
|
+
ctx.push(`const ${v} = ${calleeExpr}({ ${propsEntries.join(', ')} });`);
|
|
662
|
+
}
|
|
663
|
+
else if (ctx.importedNames.has(node.componentName)) {
|
|
627
664
|
ctx.push(`const ${v} = ${awaitKw}${node.componentName}({ ${propsEntries.join(', ')} });`);
|
|
628
665
|
}
|
|
629
666
|
else {
|
|
@@ -711,7 +748,7 @@ function emitTryCatch(ctx, node, tracked, effectsVar, parentVar) {
|
|
|
711
748
|
}`);
|
|
712
749
|
return null;
|
|
713
750
|
}
|
|
714
|
-
function emitOpaque(ctx, node, tracked, parentVar) {
|
|
751
|
+
function emitOpaque(ctx, node, tracked, effTarget, parentVar) {
|
|
715
752
|
const condExpr = transformTracked(node.condition, tracked);
|
|
716
753
|
const hasElse = node.alternateNodes.length > 0;
|
|
717
754
|
const anchor = ctx.n();
|
|
@@ -778,21 +815,32 @@ function emitOpaque(ctx, node, tracked, parentVar) {
|
|
|
778
815
|
if (!hyd)
|
|
779
816
|
ctx.push(`${parent}.appendChild(${endAnchor});`);
|
|
780
817
|
ctx.push(`if (${condExpr}) { ${asyncKw}${conRenderName}(); }` + (hasElse ? ` else { ${asyncKw}${altRenderName}(); }` : ''));
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
let __first = true;
|
|
784
|
-
effect(${ctx.isAsyncScope ? 'async () => {' : '() => {'}
|
|
818
|
+
const renderBranch = `if (__nv) { ${asyncKw}${conRenderName}(); }` + (hasElse ? ` else { ${asyncKw}${altRenderName}(); }` : '');
|
|
819
|
+
const effectBody = `effect(${ctx.isAsyncScope ? 'async () => {' : '() => {'}
|
|
785
820
|
if (__first) { __first = false; return; }
|
|
786
821
|
const __nv = ${condExpr};
|
|
787
822
|
if (__nv !== __iv) {
|
|
788
823
|
for (const e of ${effectsVar}) destroy_block(e);
|
|
789
824
|
${effectsVar}.length = 0;
|
|
790
825
|
__cleanup(${anchor}, ${endAnchor});
|
|
791
|
-
|
|
826
|
+
${renderBranch}
|
|
792
827
|
__iv = __nv;
|
|
793
828
|
}
|
|
794
|
-
})
|
|
829
|
+
});`;
|
|
830
|
+
if (effTarget) {
|
|
831
|
+
ctx.push(`${effTarget}.push((() => {
|
|
832
|
+
let __iv = ${condExpr};
|
|
833
|
+
let __first = true;
|
|
834
|
+
return ${effectBody}
|
|
835
|
+
})());`);
|
|
836
|
+
}
|
|
837
|
+
else {
|
|
838
|
+
ctx.effects.push(`{
|
|
839
|
+
let __iv = ${condExpr};
|
|
840
|
+
let __first = true;
|
|
841
|
+
${effectBody}
|
|
795
842
|
}`);
|
|
843
|
+
}
|
|
796
844
|
return null;
|
|
797
845
|
}
|
|
798
846
|
function emitWhileLoop(ctx, node, tracked, parentVar) {
|
|
@@ -1258,13 +1306,20 @@ function buildComponentMap(irRoot, hydrate = false) {
|
|
|
1258
1306
|
const mapLines = [];
|
|
1259
1307
|
mapLines.push(`const __components = {};`);
|
|
1260
1308
|
const asyncComps = computeAsyncComponents(irRoot.components);
|
|
1309
|
+
// Top-level value bindings (`const MyIcon = Cpu`) live in module scope
|
|
1310
|
+
// alongside the component map, so a same-named JSX tag must invoke that
|
|
1311
|
+
// in-scope value directly — not a registry lookup. File-defined components
|
|
1312
|
+
// keep registry precedence.
|
|
1313
|
+
const componentNames = new Set(irRoot.components.map((c) => c.name));
|
|
1314
|
+
const topValueNames = extractTopLevelNames(irRoot.topLevelCode).filter((n) => !componentNames.has(n));
|
|
1315
|
+
const directNames = new Set([...extractRuntimeNames(irRoot.imports), ...localValueImportNames(irRoot.imports), ...topValueNames]);
|
|
1261
1316
|
for (const comp of irRoot.components) {
|
|
1262
1317
|
if (hydrate && isStaticComponent(comp)) {
|
|
1263
1318
|
const stub = `(props, __registry, __hydrate) => { return __hydrate.root; }`;
|
|
1264
1319
|
mapLines.push(`__components[${JSON.stringify(comp.name)}] = ${stub};`);
|
|
1265
1320
|
continue;
|
|
1266
1321
|
}
|
|
1267
|
-
const code = generateComponent(comp,
|
|
1322
|
+
const code = generateComponent(comp, directNames, hydrate, asyncComps);
|
|
1268
1323
|
mapLines.push(`__components[${JSON.stringify(comp.name)}] = ${code};`);
|
|
1269
1324
|
}
|
|
1270
1325
|
mapLines.push(`function __cleanup(start, end) {`);
|
|
@@ -1556,8 +1611,8 @@ export function compileClient(source, _componentName, options = {}) {
|
|
|
1556
1611
|
if (options.sourcePath) {
|
|
1557
1612
|
source = inlineMdImportsFrom(source, options.sourcePath, options.mdRoots || []);
|
|
1558
1613
|
}
|
|
1559
|
-
const ast = parse(source);
|
|
1560
|
-
const ir = generateIR(ast, source);
|
|
1614
|
+
const ast = parse(source, options.sourcePath ? { filename: options.sourcePath } : {});
|
|
1615
|
+
const ir = generateIR(ast, source, options.sourcePath);
|
|
1561
1616
|
return emitClientFromIR(ir, options);
|
|
1562
1617
|
}
|
|
1563
1618
|
/**
|
|
@@ -1568,14 +1623,14 @@ export function compileClient(source, _componentName, options = {}) {
|
|
|
1568
1623
|
* `resolveComponentName`, so callers don't need a second full parse just
|
|
1569
1624
|
* to learn the name.
|
|
1570
1625
|
*/
|
|
1571
|
-
export function compileClientBoth(source, _componentName) {
|
|
1572
|
-
const ast = parse(source);
|
|
1626
|
+
export function compileClientBoth(source, _componentName, sourcePath) {
|
|
1627
|
+
const ast = parse(source, sourcePath ? { filename: sourcePath } : {});
|
|
1573
1628
|
// Downstream type-stripping mutates AST nodes in place (stripTsTypes),
|
|
1574
1629
|
// so each emit mode needs its own tree. Cloning is far cheaper than the
|
|
1575
1630
|
// second full acorn+TS parse this replaces.
|
|
1576
1631
|
const hydAst = structuredClone(ast);
|
|
1577
|
-
const ir = generateIR(ast, source);
|
|
1578
|
-
const irHyd = generateIR(hydAst, source);
|
|
1632
|
+
const ir = generateIR(ast, source, sourcePath);
|
|
1633
|
+
const irHyd = generateIR(hydAst, source, sourcePath);
|
|
1579
1634
|
const defaultComp = ir.components.find((c) => c.defaultExport);
|
|
1580
1635
|
let name = null;
|
|
1581
1636
|
if (defaultComp)
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare function levenshtein(a: string, b: string): number;
|
|
2
2
|
export declare function didYouMean(name: string, candidates: string[], maxDistance?: number): string | null;
|
|
3
|
+
export declare function codeFrame(source: string, line: number, column: number, before?: number, after?: number): string;
|
|
3
4
|
export interface VeskErrorOptions {
|
|
4
5
|
file?: string;
|
|
5
6
|
line?: number;
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAoBxD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,WAAW,GAAE,MAAU,GAAG,MAAM,GAAG,IAAI,CAWrG;AAqCD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAgBD,qBAAa,SAAU,SAAQ,KAAK;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEF,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB;IAYxD,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,EAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IA6BnG,MAAM,CAAC,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAmB3D,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAkBvF,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAkBvF,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,EAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAO3G,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,GAAE,MAAM,EAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAWvG,MAAM,CAAC,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAkB/G,QAAQ,IAAI,MAAM;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAoBxD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,WAAW,GAAE,MAAU,GAAG,MAAM,GAAG,IAAI,CAWrG;AAqCD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAI,EAAE,KAAK,SAAI,GAAG,MAAM,CAkBrG;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAgBD,qBAAa,SAAU,SAAQ,KAAK;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEF,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB;IAYxD,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,EAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IA6BnG,MAAM,CAAC,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAmB3D,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAkBvF,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAkBvF,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,EAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAO3G,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,GAAE,MAAM,EAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAWvG,MAAM,CAAC,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS;IAkB/G,QAAQ,IAAI,MAAM;IA0BlB,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAclC"}
|
package/dist/errors.js
CHANGED
|
@@ -66,6 +66,26 @@ function findKeywordNumber(message, keywords) {
|
|
|
66
66
|
}
|
|
67
67
|
return 0;
|
|
68
68
|
}
|
|
69
|
+
export function codeFrame(source, line, column, before = 5, after = 5) {
|
|
70
|
+
if (line <= 0)
|
|
71
|
+
return '';
|
|
72
|
+
const lines = source.split('\n');
|
|
73
|
+
const start = Math.max(1, line - before);
|
|
74
|
+
const end = Math.min(lines.length, line + after);
|
|
75
|
+
const width = String(end).length;
|
|
76
|
+
let out = '';
|
|
77
|
+
for (let i = start; i <= end; i++) {
|
|
78
|
+
const text = lines[i - 1] ?? '';
|
|
79
|
+
const ln = String(i).padStart(width, ' ');
|
|
80
|
+
out += `${ln} | ${text}\n`;
|
|
81
|
+
if (i === line) {
|
|
82
|
+
const pointerCol = Math.max(0, column - 1);
|
|
83
|
+
const prefix = ' '.repeat(width) + ' | ';
|
|
84
|
+
out += prefix + ' '.repeat(pointerCol) + '^\n';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return out.trimEnd();
|
|
88
|
+
}
|
|
69
89
|
const VESK_BUILTINS = [
|
|
70
90
|
'useFetch', 'useRouter', 'useParams', 'usePathname', 'useSearchParams',
|
|
71
91
|
'useNavigate', 'useHead', 'useTitle',
|
|
@@ -204,8 +224,21 @@ export class VeskError extends Error {
|
|
|
204
224
|
}
|
|
205
225
|
toString() {
|
|
206
226
|
let out = `[vesk] ${this.message}`;
|
|
207
|
-
if (this.file)
|
|
208
|
-
out += `\n File: ${this.file}
|
|
227
|
+
if (this.file) {
|
|
228
|
+
out += `\n File: ${this.file}`;
|
|
229
|
+
if (this.line) {
|
|
230
|
+
out += `:${this.line}`;
|
|
231
|
+
if (this.column)
|
|
232
|
+
out += `:${this.column}`;
|
|
233
|
+
}
|
|
234
|
+
if (this.line && this.column)
|
|
235
|
+
out += ` (line ${this.line}, column ${this.column})`;
|
|
236
|
+
else if (this.line)
|
|
237
|
+
out += ` (line ${this.line})`;
|
|
238
|
+
}
|
|
239
|
+
else if (this.line) {
|
|
240
|
+
out += `\n at line ${this.line}${this.column ? `, column ${this.column}` : ''}`;
|
|
241
|
+
}
|
|
209
242
|
if (this.code)
|
|
210
243
|
out += `\n\n${this.code}`;
|
|
211
244
|
if (this.suggestions.length) {
|
package/dist/ir-generator.d.ts
CHANGED
|
@@ -6,5 +6,5 @@ export declare function getPropsType(params: Array<{
|
|
|
6
6
|
typeAnnotation?: any;
|
|
7
7
|
properties?: any[];
|
|
8
8
|
}> | undefined | null, source: string): string | null;
|
|
9
|
-
export declare function generateIR(ast: any, source: string): IRRoot;
|
|
9
|
+
export declare function generateIR(ast: any, source: string, filename?: string): IRRoot;
|
|
10
10
|
//# sourceMappingURL=ir-generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ir-generator.d.ts","sourceRoot":"","sources":["../src/ir-generator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,MAAM,EAoBP,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"ir-generator.d.ts","sourceRoot":"","sources":["../src/ir-generator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,MAAM,EAoBP,MAAM,uBAAuB,CAAC;AA0L/B,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,GAAG,CAAC;IAAC,cAAc,CAAC,EAAE,GAAG,CAAC;IAAC,UAAU,CAAC,EAAE,GAAG,EAAE,CAAA;CAAE,CAAC,GAAG,SAAS,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkCnL;AAg0BD,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAoO9E"}
|
package/dist/ir-generator.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IRRoot, ComponentIR, StaticNode, TextNode, DynamicBinding, OpaqueDynamicRegion, MapRegion, WhileLoop, SwitchBlock, TryCatch, RuntimeStatement, ForLoop, TrackDecl, ComponentRef, ComponentCall, ServerBlock, ClientBlock, HeadBlock, Expression, SlotNode, } from '@vesk/compiler/src/ir';
|
|
2
|
-
import { VeskError } from '@vesk/compiler/src/errors';
|
|
2
|
+
import { VeskError, codeFrame } from '@vesk/compiler/src/errors';
|
|
3
3
|
import { createBaseParser } from '@vesk/compiler/src/parser';
|
|
4
4
|
import { skipWhitespace, findBalancedEnd, splitTopLevel, startsWithIdentifier, stripDeclKeyword, isWhitespaceChar, collapseNewlineWhitespace } from '@vesk/compiler/src/scan';
|
|
5
5
|
import { stripCodeTypes } from '@vesk/compiler/src/strip-ts';
|
|
@@ -83,6 +83,52 @@ function offsetToLineCol(source, offset) {
|
|
|
83
83
|
}
|
|
84
84
|
return { line, column };
|
|
85
85
|
}
|
|
86
|
+
function calleeIsFetch(callee) {
|
|
87
|
+
if (!callee || typeof callee !== 'object')
|
|
88
|
+
return false;
|
|
89
|
+
const c = callee;
|
|
90
|
+
if (c.type === 'Identifier')
|
|
91
|
+
return c.name === 'useFetch';
|
|
92
|
+
if (c.type === 'MemberExpression') {
|
|
93
|
+
const object = c.object;
|
|
94
|
+
if (object && object.type === 'Identifier')
|
|
95
|
+
return object.name === 'useFetch';
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Walks an ESTree subtree looking for a real `useFetch(...)` / `useFetch.stream(...)`
|
|
101
|
+
* call. String and template-literal *content* is not part of the expression tree,
|
|
102
|
+
* so `const md = \`useFetch.stream(...)\`` no longer counts as a fetch usage.
|
|
103
|
+
*/
|
|
104
|
+
function estreeCallsFetch(ast) {
|
|
105
|
+
if (!ast)
|
|
106
|
+
return false;
|
|
107
|
+
const stack = [ast];
|
|
108
|
+
while (stack.length > 0) {
|
|
109
|
+
const candidate = stack.pop();
|
|
110
|
+
if (!candidate || typeof candidate !== 'object')
|
|
111
|
+
continue;
|
|
112
|
+
const node = candidate;
|
|
113
|
+
if ((node.type === 'CallExpression' || node.type === 'NewExpression') &&
|
|
114
|
+
calleeIsFetch(node.callee)) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
for (const key of Object.keys(node)) {
|
|
118
|
+
if (key === 'parent' || key === 'loc' || key === 'start' || key === 'end' || key === 'range')
|
|
119
|
+
continue;
|
|
120
|
+
const value = node[key];
|
|
121
|
+
if (Array.isArray(value)) {
|
|
122
|
+
for (const item of value)
|
|
123
|
+
stack.push(item);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
stack.push(value);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
86
132
|
function componentUsesFetch(nodes) {
|
|
87
133
|
for (const node of nodes) {
|
|
88
134
|
if (node instanceof ServerBlock || node instanceof ClientBlock) {
|
|
@@ -90,11 +136,11 @@ function componentUsesFetch(nodes) {
|
|
|
90
136
|
return true;
|
|
91
137
|
}
|
|
92
138
|
else if (node instanceof RuntimeStatement) {
|
|
93
|
-
if (
|
|
139
|
+
if (estreeCallsFetch(node.ast))
|
|
94
140
|
return true;
|
|
95
141
|
}
|
|
96
142
|
else if (node instanceof DynamicBinding) {
|
|
97
|
-
if (
|
|
143
|
+
if (estreeCallsFetch(node.expression.ast))
|
|
98
144
|
return true;
|
|
99
145
|
}
|
|
100
146
|
else if (node instanceof MapRegion) {
|
|
@@ -574,12 +620,23 @@ function processJSXCallbackBody(source, body) {
|
|
|
574
620
|
return exprToIR(source, body);
|
|
575
621
|
}
|
|
576
622
|
function processJSXElement(source, element) {
|
|
577
|
-
const
|
|
623
|
+
const nameNode = element.openingElement.name;
|
|
624
|
+
const tagName = getJSXTagName(nameNode);
|
|
578
625
|
const selfClosing = element.openingElement.selfClosing;
|
|
579
626
|
if (tagName === 'Head') {
|
|
580
627
|
const children = selfClosing ? [] : processJSXChildren(source, element.children || []);
|
|
581
628
|
return [new HeadBlock(children)];
|
|
582
629
|
}
|
|
630
|
+
// A dotted JSX tag (`<it.icon>`, `<Foo.Bar>`) is a component-valued member
|
|
631
|
+
// expression — never an HTML element (dots are not valid in tag names) and
|
|
632
|
+
// never a registry key. Carry the raw expression so codegen invokes the
|
|
633
|
+
// actual in-scope value instead of `document.createElement("it.icon")` or a
|
|
634
|
+
// registry lookup by dotted string.
|
|
635
|
+
if (nameNode && nameNode.type === 'JSXMemberExpression') {
|
|
636
|
+
const { props, spreadProps } = extractProps(source, element);
|
|
637
|
+
const children = selfClosing ? [] : processJSXChildren(source, element.children || []);
|
|
638
|
+
return [new ComponentCall(tagName, props, children, spreadProps, element.start, getSource(source, nameNode))];
|
|
639
|
+
}
|
|
583
640
|
if (!isHTMLTag(tagName) && selfClosing) {
|
|
584
641
|
const { props, spreadProps } = extractProps(source, element);
|
|
585
642
|
return [new ComponentCall(tagName, props, [], spreadProps, element.start)];
|
|
@@ -830,7 +887,7 @@ function processTryStatement(source, stmt) {
|
|
|
830
887
|
const catchParamName = stmt.handler?.param?.name ?? null;
|
|
831
888
|
return [new TryCatch(bodyTemplate, catchBody, catchParamName)];
|
|
832
889
|
}
|
|
833
|
-
function processStatementModeBody(source, bodyStmts) {
|
|
890
|
+
function processStatementModeBody(source, bodyStmts, filename) {
|
|
834
891
|
const nodes = [];
|
|
835
892
|
for (let i = 0; i < bodyStmts.length; i++) {
|
|
836
893
|
const stmt = bodyStmts[i];
|
|
@@ -859,7 +916,7 @@ function processStatementModeBody(source, bodyStmts) {
|
|
|
859
916
|
else if (stmt.type === 'VeskBlock') {
|
|
860
917
|
if (stmt.tag === 'empty')
|
|
861
918
|
continue;
|
|
862
|
-
const inner = processStatementModeBody(source, stmt.body);
|
|
919
|
+
const inner = processStatementModeBody(source, stmt.body, filename);
|
|
863
920
|
if (stmt.tag === 'server') {
|
|
864
921
|
nodes.push(new ServerBlock(inner));
|
|
865
922
|
}
|
|
@@ -879,6 +936,18 @@ function processStatementModeBody(source, bodyStmts) {
|
|
|
879
936
|
nodes.push(new ComponentRef(refName));
|
|
880
937
|
}
|
|
881
938
|
else if (stmt.type === 'IfStatement') {
|
|
939
|
+
// Guard-clause early return (`if (c) return X` with no else): everything
|
|
940
|
+
// after this statement becomes the alternate branch, mirroring
|
|
941
|
+
// expression-mode `buildGuardChain`. Without this the `return` is
|
|
942
|
+
// silently swallowed and execution falls through into code that
|
|
943
|
+
// assumes the guard held.
|
|
944
|
+
const guardArg = !stmt.alternate ? getReturnArgument(stmt.consequent) : null;
|
|
945
|
+
if (guardArg) {
|
|
946
|
+
const consequent = exprToIR(source, guardArg);
|
|
947
|
+
const alternate = processStatementModeBody(source, bodyStmts.slice(i + 1), filename);
|
|
948
|
+
nodes.push(new OpaqueDynamicRegion(toExpression(source, stmt.test), consequent, alternate));
|
|
949
|
+
break;
|
|
950
|
+
}
|
|
882
951
|
nodes.push(...processIfStatement(source, stmt));
|
|
883
952
|
}
|
|
884
953
|
else if (stmt.type === 'ForOfStatement') {
|
|
@@ -886,7 +955,7 @@ function processStatementModeBody(source, bodyStmts) {
|
|
|
886
955
|
let consumed = 1;
|
|
887
956
|
const next = bodyStmts[i + 1];
|
|
888
957
|
if (next && next.type === 'VeskBlock' && next.tag === 'empty') {
|
|
889
|
-
alternate = processStatementModeBody(source, next.body);
|
|
958
|
+
alternate = processStatementModeBody(source, next.body, filename);
|
|
890
959
|
consumed = 2;
|
|
891
960
|
}
|
|
892
961
|
nodes.push(...processForStatement(source, stmt, alternate));
|
|
@@ -926,7 +995,8 @@ function processStatementModeBody(source, bodyStmts) {
|
|
|
926
995
|
}
|
|
927
996
|
}
|
|
928
997
|
else if (stmt.type === 'ClassDeclaration') {
|
|
929
|
-
|
|
998
|
+
const { line, column } = offsetToLineCol(source, stmt.start ?? 0);
|
|
999
|
+
throw VeskError.classDecl({ file: filename || '', line, column, code: codeFrame(source, line, column) });
|
|
930
1000
|
}
|
|
931
1001
|
else {
|
|
932
1002
|
const raw = getSource(source, stmt);
|
|
@@ -953,20 +1023,36 @@ function extractStyle(body) {
|
|
|
953
1023
|
}
|
|
954
1024
|
return { body: filtered, css: cssParts.join('\n') || null };
|
|
955
1025
|
}
|
|
956
|
-
function validateBlocks(compName, isClient, body) {
|
|
1026
|
+
function validateBlocks(compName, isClient, body, file, source) {
|
|
957
1027
|
for (const node of body) {
|
|
958
1028
|
if (isClient) {
|
|
959
1029
|
if (node instanceof ServerBlock) {
|
|
960
|
-
|
|
1030
|
+
const opts = file ? { file } : {};
|
|
1031
|
+
if (source && node.start !== undefined) {
|
|
1032
|
+
const pos = node.start;
|
|
1033
|
+
const { line, column } = offsetToLineCol(source, pos);
|
|
1034
|
+
opts.line = line;
|
|
1035
|
+
opts.column = column;
|
|
1036
|
+
opts.code = codeFrame(source, line, column);
|
|
1037
|
+
}
|
|
1038
|
+
throw VeskError.serverBlockInClient(compName, opts);
|
|
961
1039
|
}
|
|
962
1040
|
}
|
|
963
1041
|
else {
|
|
964
1042
|
if (node instanceof ClientBlock) {
|
|
965
|
-
|
|
1043
|
+
const opts = file ? { file } : {};
|
|
1044
|
+
if (source && node.start !== undefined) {
|
|
1045
|
+
const pos = node.start;
|
|
1046
|
+
const { line, column } = offsetToLineCol(source, pos);
|
|
1047
|
+
opts.line = line;
|
|
1048
|
+
opts.column = column;
|
|
1049
|
+
opts.code = codeFrame(source, line, column);
|
|
1050
|
+
}
|
|
1051
|
+
throw VeskError.clientBlockInServer(compName, opts);
|
|
966
1052
|
}
|
|
967
1053
|
}
|
|
968
1054
|
if (node instanceof StaticNode || node instanceof ServerBlock || node instanceof ClientBlock) {
|
|
969
|
-
validateBlocks(compName, isClient, node.children || []);
|
|
1055
|
+
validateBlocks(compName, isClient, node.children || [], file, source);
|
|
970
1056
|
}
|
|
971
1057
|
}
|
|
972
1058
|
}
|
|
@@ -1024,8 +1110,9 @@ function idxOfQuote(s, from) {
|
|
|
1024
1110
|
}
|
|
1025
1111
|
return -1;
|
|
1026
1112
|
}
|
|
1027
|
-
export function generateIR(ast, source) {
|
|
1113
|
+
export function generateIR(ast, source, filename) {
|
|
1028
1114
|
__vskAnnotations = ast.__vskAnnotations ?? [];
|
|
1115
|
+
const file = filename || '';
|
|
1029
1116
|
const components = [];
|
|
1030
1117
|
const imports = [];
|
|
1031
1118
|
const importedNames = new Set();
|
|
@@ -1089,7 +1176,8 @@ export function generateIR(ast, source) {
|
|
|
1089
1176
|
// handled below
|
|
1090
1177
|
}
|
|
1091
1178
|
else if (inner.type === 'ClassDeclaration') {
|
|
1092
|
-
|
|
1179
|
+
const { line, column } = offsetToLineCol(source, inner.start ?? 0);
|
|
1180
|
+
throw VeskError.classDecl({ file, line, column, code: codeFrame(source, line, column) });
|
|
1093
1181
|
}
|
|
1094
1182
|
else if (inner.type === 'TSEnumDeclaration') {
|
|
1095
1183
|
const code = processEnum(inner, source, exported);
|
|
@@ -1106,9 +1194,9 @@ export function generateIR(ast, source) {
|
|
|
1106
1194
|
const bodyStmts = inner.body.body;
|
|
1107
1195
|
const isClientComp = !!inner.client;
|
|
1108
1196
|
if (isStatementMode(bodyStmts)) {
|
|
1109
|
-
const raw = processStatementModeBody(source, bodyStmts);
|
|
1197
|
+
const raw = processStatementModeBody(source, bodyStmts, file);
|
|
1110
1198
|
const { body, css } = extractStyle(raw);
|
|
1111
|
-
validateBlocks(name, isClientComp, body);
|
|
1199
|
+
validateBlocks(name, isClientComp, body, file, source);
|
|
1112
1200
|
const comp = new ComponentIR(name, paramNames, body, { mode: 'statement', exported, defaultExport, isClient: inner.client, isAsync: inner.async, ssrAwait: componentUsesFetch(body), propsType });
|
|
1113
1201
|
comp.style = css;
|
|
1114
1202
|
components.push(comp);
|
|
@@ -1119,7 +1207,7 @@ export function generateIR(ast, source) {
|
|
|
1119
1207
|
const preamble = [];
|
|
1120
1208
|
for (const stmt of bodyStmts) {
|
|
1121
1209
|
if (stmt.type === 'VeskBlock') {
|
|
1122
|
-
const innerBody = processStatementModeBody(source, stmt.body);
|
|
1210
|
+
const innerBody = processStatementModeBody(source, stmt.body, file);
|
|
1123
1211
|
if (stmt.tag === 'server') {
|
|
1124
1212
|
preamble.push(new ServerBlock(innerBody));
|
|
1125
1213
|
}
|
|
@@ -1145,7 +1233,8 @@ export function generateIR(ast, source) {
|
|
|
1145
1233
|
guardClauses.push(stmt);
|
|
1146
1234
|
}
|
|
1147
1235
|
else if (stmt.type === 'ClassDeclaration') {
|
|
1148
|
-
|
|
1236
|
+
const { line, column } = offsetToLineCol(source, stmt.start ?? 0);
|
|
1237
|
+
throw VeskError.classDecl({ file, line, column, code: codeFrame(source, line, column) });
|
|
1149
1238
|
}
|
|
1150
1239
|
else {
|
|
1151
1240
|
const raw = getSource(source, stmt);
|
|
@@ -1155,7 +1244,7 @@ export function generateIR(ast, source) {
|
|
|
1155
1244
|
}
|
|
1156
1245
|
const guardBody = buildGuardChain(source, guardClauses, mainReturn);
|
|
1157
1246
|
const { body, css } = extractStyle([...preamble, ...guardBody]);
|
|
1158
|
-
validateBlocks(name, isClientComp, body);
|
|
1247
|
+
validateBlocks(name, isClientComp, body, file, source);
|
|
1159
1248
|
const comp = new ComponentIR(name, paramNames, body, { exported, defaultExport, isClient: inner.client, isAsync: inner.async, ssrAwait: componentUsesFetch(body), propsType });
|
|
1160
1249
|
comp.style = css;
|
|
1161
1250
|
components.push(comp);
|
|
@@ -1171,7 +1260,7 @@ export function generateIR(ast, source) {
|
|
|
1171
1260
|
if (!asyncNames.has(childName))
|
|
1172
1261
|
continue;
|
|
1173
1262
|
const { line, column } = offsetToLineCol(source, start >= 0 ? start : 0);
|
|
1174
|
-
throw VeskError.asyncChildInSyncParent(comp.name, childName, { line, column });
|
|
1263
|
+
throw VeskError.asyncChildInSyncParent(comp.name, childName, { file, line, column, code: codeFrame(source, line, column) });
|
|
1175
1264
|
}
|
|
1176
1265
|
}
|
|
1177
1266
|
const autoImportable = [
|
package/dist/ir.d.ts
CHANGED
|
@@ -89,10 +89,17 @@ export declare class ComponentCall {
|
|
|
89
89
|
spreadProps: Expression[];
|
|
90
90
|
children: IRNode[];
|
|
91
91
|
start: number;
|
|
92
|
+
/**
|
|
93
|
+
* Raw JS expression for the component value when the JSX tag is a member
|
|
94
|
+
* expression (e.g. `<it.icon>` → `it.icon`). Dotted tags can never be HTML
|
|
95
|
+
* elements or registry names, so codegen must invoke this expression
|
|
96
|
+
* directly instead of resolving `componentName` through the registry.
|
|
97
|
+
*/
|
|
98
|
+
calleeExpr: string | null;
|
|
92
99
|
constructor(componentName: string, props: {
|
|
93
100
|
name: string;
|
|
94
101
|
value: Expression;
|
|
95
|
-
}[], children?: IRNode[], spreadProps?: Expression[], start?: number);
|
|
102
|
+
}[], children?: IRNode[], spreadProps?: Expression[], start?: number, calleeExpr?: string | null);
|
|
96
103
|
}
|
|
97
104
|
export declare class SlotNode {
|
|
98
105
|
constructor();
|
package/dist/ir.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"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"}
|
package/dist/ir.js
CHANGED
|
@@ -120,12 +120,20 @@ export class ComponentCall {
|
|
|
120
120
|
spreadProps;
|
|
121
121
|
children;
|
|
122
122
|
start;
|
|
123
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Raw JS expression for the component value when the JSX tag is a member
|
|
125
|
+
* expression (e.g. `<it.icon>` → `it.icon`). Dotted tags can never be HTML
|
|
126
|
+
* elements or registry names, so codegen must invoke this expression
|
|
127
|
+
* directly instead of resolving `componentName` through the registry.
|
|
128
|
+
*/
|
|
129
|
+
calleeExpr;
|
|
130
|
+
constructor(componentName, props, children = [], spreadProps = [], start = -1, calleeExpr = null) {
|
|
124
131
|
this.componentName = componentName;
|
|
125
132
|
this.props = props;
|
|
126
133
|
this.children = children;
|
|
127
134
|
this.spreadProps = spreadProps;
|
|
128
135
|
this.start = start;
|
|
136
|
+
this.calleeExpr = calleeExpr;
|
|
129
137
|
}
|
|
130
138
|
}
|
|
131
139
|
export class SlotNode {
|
package/dist/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAMtC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,cAAc,EAAE,CAAA;CAAE,CA0KpG;AAED,wBAAgB,gBAAgB,IAAI,OAAO,KAAK,CAAC,MAAM,CAEtD;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CA+CzE"}
|
package/dist/parser.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as acorn from 'acorn';
|
|
|
2
2
|
import { tsPlugin } from './acorn-ts-plugin/index.js';
|
|
3
3
|
import { VeskParserPlugin } from '@vesk/compiler/src/vesk-plugin';
|
|
4
4
|
import { containsForOfIn } from '@vesk/compiler/src/scan';
|
|
5
|
+
import { VeskError, codeFrame } from '@vesk/compiler/src/errors';
|
|
5
6
|
function isIdentChar(code) {
|
|
6
7
|
return ((code >= 97 && code <= 122) || (code >= 65 && code <= 90) || (code >= 48 && code <= 57) || code === 95 || code === 36);
|
|
7
8
|
}
|
|
@@ -228,15 +229,50 @@ export function createBaseParser() {
|
|
|
228
229
|
export function parse(source, options = {}) {
|
|
229
230
|
const ParserClass = createBaseParser();
|
|
230
231
|
const { code, annotations } = preprocessForClauses(source);
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
232
|
+
try {
|
|
233
|
+
const ast = ParserClass.parse(code, {
|
|
234
|
+
ecmaVersion: 'latest',
|
|
235
|
+
sourceType: 'module',
|
|
236
|
+
locations: true,
|
|
237
|
+
ranges: true,
|
|
238
|
+
...(options.filename ? { sourceFilename: options.filename } : {}),
|
|
239
|
+
});
|
|
240
|
+
if (annotations.length > 0) {
|
|
241
|
+
ast.__vskAnnotations = annotations;
|
|
242
|
+
}
|
|
243
|
+
return ast;
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
const err = e;
|
|
247
|
+
// Acorn's SyntaxError already contains "(line:column)" in message and loc
|
|
248
|
+
let line = 0;
|
|
249
|
+
let column = 0;
|
|
250
|
+
if (err.loc && typeof err.loc.line === 'number') {
|
|
251
|
+
line = err.loc.line;
|
|
252
|
+
column = (err.loc.column ?? 0) + 1;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
const m = err.message.match(/\((\d+):(\d+)\)/);
|
|
256
|
+
if (m) {
|
|
257
|
+
line = parseInt(m[1], 10);
|
|
258
|
+
column = parseInt(m[2], 10) + 1;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const filename = options.filename || '';
|
|
262
|
+
const cleanMessage = err.message.replace(/\s*\(\d+:\d+\)\s*$/, '');
|
|
263
|
+
const frame = line > 0 ? codeFrame(source, line, column, 5, 5) : '';
|
|
264
|
+
const hint = filename ? ` in ${filename}` : '';
|
|
265
|
+
throw new VeskError(`${cleanMessage}${hint}`, {
|
|
266
|
+
file: filename,
|
|
267
|
+
line,
|
|
268
|
+
column,
|
|
269
|
+
code: frame,
|
|
270
|
+
nextSteps: [
|
|
271
|
+
'Check the line indicated by the ^ marker for missing brackets, quotes, or JSX syntax.',
|
|
272
|
+
'If you wrote literal { or } inside JSX text, escape them as {\'{\'} and {\'}\'} or use { }.',
|
|
273
|
+
'Ensure all JSX tags are properly closed and component names start with an uppercase letter.',
|
|
274
|
+
],
|
|
275
|
+
tip: 'Vesk parses with Acorn + TypeScript + JSX — use the code frame above to locate the error.',
|
|
276
|
+
});
|
|
240
277
|
}
|
|
241
|
-
return ast;
|
|
242
278
|
}
|
|
@@ -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,EAA4E,KAAK,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAW/I,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,CA8CjJ;
|
|
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,EAA4E,KAAK,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAW/I,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,CA8CjJ;AAyTD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAmD1F;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAkChG"}
|
package/dist/server-jsgen.js
CHANGED
|
@@ -358,14 +358,27 @@ function componentCallToJS(node, importedNames, isAsync = false, tracked) {
|
|
|
358
358
|
}
|
|
359
359
|
const propsObj = `{ ${propsEntries.join(', ')} }`;
|
|
360
360
|
const compName = node.componentName;
|
|
361
|
-
|
|
362
|
-
|
|
361
|
+
// Member-expression tags (`<it.icon>`) carry the raw component-valued
|
|
362
|
+
// expression — invoke it directly; it is never a registry name.
|
|
363
|
+
const callee = node.calleeExpr
|
|
364
|
+
? `(${node.calleeExpr})`
|
|
365
|
+
: (() => {
|
|
366
|
+
const isImported = importedNames && importedNames.has(compName);
|
|
367
|
+
return isImported ? compName : `__registry.get(${JSON.stringify(compName)})`;
|
|
368
|
+
})();
|
|
363
369
|
const awaitKw = isAsync ? 'await ' : '';
|
|
370
|
+
// Hoist the callee so its defining-file scope (`__veskScope`, attached in
|
|
371
|
+
// server-render.ts) is preferred over the merged caller scope. Same-named
|
|
372
|
+
// top-level bindings in different `.vsk` files must not leak across
|
|
373
|
+
// components during SSR.
|
|
374
|
+
const calleeVar = `__cc${nextVskId()}`;
|
|
375
|
+
lines.push(`const ${calleeVar} = ${callee};`);
|
|
376
|
+
const callExpr = `${awaitKw}${calleeVar}(${propsObj}, __registry, (${calleeVar}.__veskScope || __vesk))`;
|
|
364
377
|
if (__vskHydrate) {
|
|
365
|
-
lines.push(`__out.push('<!--vsk--><div>' + (${
|
|
378
|
+
lines.push(`__out.push('<!--vsk--><div>' + (${callExpr} || '') + '</div>');`);
|
|
366
379
|
}
|
|
367
380
|
else {
|
|
368
|
-
lines.push(`__out.push(${
|
|
381
|
+
lines.push(`__out.push(${callExpr} || '');`);
|
|
369
382
|
}
|
|
370
383
|
return lines.join('\n');
|
|
371
384
|
}
|
|
@@ -424,8 +437,14 @@ export function buildComponentMap(irRoot, useSharedScope) {
|
|
|
424
437
|
const map = new Map();
|
|
425
438
|
const runtimeNames = extractRuntimeNames(irRoot.imports);
|
|
426
439
|
const localValueNames = localValueImportNames(irRoot.imports);
|
|
427
|
-
const importedNames = new Set([...runtimeNames, ...localValueNames]);
|
|
428
440
|
const topNames = extractTopLevelNames(irRoot.topLevelCode);
|
|
441
|
+
// Top-level value bindings (`const MyIcon = Cpu`) are destructured into
|
|
442
|
+
// every component scope from `__vesk` (see `scopeDecl` below), so a
|
|
443
|
+
// same-named JSX tag must invoke that in-scope value directly — not a
|
|
444
|
+
// registry lookup. File-defined components keep registry precedence.
|
|
445
|
+
const componentNames = new Set(irRoot.components.map((c) => c.name));
|
|
446
|
+
const topValueNames = topNames.filter((n) => !componentNames.has(n));
|
|
447
|
+
const importedNames = new Set([...runtimeNames, ...localValueNames, ...topValueNames]);
|
|
429
448
|
const hasTracked = irRoot.components.some((c) => c.body.some((n) => n instanceof TrackDecl));
|
|
430
449
|
const extraNames = hasTracked ? ['get', 'set', 'track'] : [];
|
|
431
450
|
const allNames = [...new Set([...runtimeNames, ...topNames, ...extraNames, ...localValueNames])];
|
package/dist/server-render.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare function ssg(source: string, componentName?: string, customProps?
|
|
|
8
8
|
registry?: Map<string, Function>;
|
|
9
9
|
cssUrl?: string;
|
|
10
10
|
cssUrls?: string[];
|
|
11
|
+
sourcePath?: string;
|
|
11
12
|
[key: string]: unknown;
|
|
12
13
|
}): Promise<SSGResult>;
|
|
13
14
|
export declare function buildDataScripts(ssrProps: Record<string, unknown> | null | undefined, ssrData: Record<string, unknown>, external?: ExternalDataScript | null): string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-render.d.ts","sourceRoot":"","sources":["../src/server-render.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAqB,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"server-render.d.ts","sourceRoot":"","sources":["../src/server-render.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAqB,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AA6BvJ,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,iBAAiB,CAEhG;AA6CD,wBAAgB,MAAM,CACpB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACpC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC1B;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACpC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiE9C;AAcD,wBAAsB,GAAG,CACvB,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAO,GACnI,OAAO,CAAC,SAAS,CAAC,CA8DpB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACpD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,GACnC,MAAM,EAAE,CAuBV;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAoEjB;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,eAAoB,GAC5B,cAAc,CAAC,MAAM,CAAC,CA2FxB"}
|
package/dist/server-render.js
CHANGED
|
@@ -12,6 +12,15 @@ import { collectVskImportPaths } from '@vesk/compiler/src/vsk-imports';
|
|
|
12
12
|
import { inlineMdImportsFrom, guessProjectRoots } from '@vesk/compiler/src/md-inline';
|
|
13
13
|
import { withSsrStore, ssrSink } from '@vesk/compiler/src/ssr-store';
|
|
14
14
|
import { applyLocalModuleImports } from '@vesk/compiler/src/module-imports';
|
|
15
|
+
// Registry-hoisted sub components are invoked with the caller's `__vesk`,
|
|
16
|
+
// but each component's scope declaration destructures its DEFINING file's
|
|
17
|
+
// top-level bindings. When two `.vsk` files declare the same top-level name
|
|
18
|
+
// (e.g. both define `const stages`), the hoist-first-wins merge below would
|
|
19
|
+
// hand every component the wrong file's value. Attaching the defining scope
|
|
20
|
+
// lets every call site prefer the callee's own bindings.
|
|
21
|
+
function scopedVesk(fn, fallback) {
|
|
22
|
+
return fn.__veskScope || fallback;
|
|
23
|
+
}
|
|
15
24
|
export function compileFile(source, options) {
|
|
16
25
|
return compileFileInternal(source, options?.sourcePath, new Set());
|
|
17
26
|
}
|
|
@@ -20,9 +29,10 @@ function compileFileInternal(source, sourcePath, seenImportFiles) {
|
|
|
20
29
|
const dir = dirname(sourcePath);
|
|
21
30
|
source = inlineMdImportsFrom(source, sourcePath, guessProjectRoots(dir));
|
|
22
31
|
}
|
|
23
|
-
const ast = parse(source);
|
|
24
|
-
const ir = generateIR(ast, source);
|
|
32
|
+
const ast = parse(source, sourcePath ? { filename: sourcePath } : {});
|
|
33
|
+
const ir = generateIR(ast, source, sourcePath);
|
|
25
34
|
const componentMap = buildComponentMap(ir, true);
|
|
35
|
+
const ownComponentNames = ir.components.map((c) => c.name);
|
|
26
36
|
const __vesk = loadRuntimeImports(ir.imports);
|
|
27
37
|
applyLocalModuleImports(__vesk, ir.imports, sourcePath);
|
|
28
38
|
if (sourcePath) {
|
|
@@ -52,6 +62,13 @@ function compileFileInternal(source, sourcePath, seenImportFiles) {
|
|
|
52
62
|
}
|
|
53
63
|
}
|
|
54
64
|
evalTopLevelCode(transformTopLevelForActions(ir.topLevelCode, 'server'), __vesk);
|
|
65
|
+
// Sub-file components arrive pre-scoped from the recursive call below;
|
|
66
|
+
// scope the remaining (own) components to this file's bindings.
|
|
67
|
+
for (const name of ownComponentNames) {
|
|
68
|
+
const fn = componentMap.get(name);
|
|
69
|
+
if (fn && !fn.__veskScope)
|
|
70
|
+
fn.__veskScope = __vesk;
|
|
71
|
+
}
|
|
55
72
|
return { ir, componentMap, __vesk };
|
|
56
73
|
}
|
|
57
74
|
export function render(source, componentName, props = {}, registry = new Map(), options = {}) {
|
|
@@ -72,7 +89,7 @@ export function render(source, componentName, props = {}, registry = new Map(),
|
|
|
72
89
|
return withSsrStore(() => (async () => {
|
|
73
90
|
let bodyHtml;
|
|
74
91
|
try {
|
|
75
|
-
bodyHtml = await renderFn(props, fullRegistry, __vesk);
|
|
92
|
+
bodyHtml = await renderFn(props, fullRegistry, scopedVesk(renderFn, __vesk));
|
|
76
93
|
}
|
|
77
94
|
finally {
|
|
78
95
|
delete globalThis.__vsk_ssr;
|
|
@@ -83,7 +100,7 @@ export function render(source, componentName, props = {}, registry = new Map(),
|
|
|
83
100
|
}
|
|
84
101
|
let bodyHtml;
|
|
85
102
|
try {
|
|
86
|
-
bodyHtml = withSsrStore(() => renderFn(props, fullRegistry, __vesk));
|
|
103
|
+
bodyHtml = withSsrStore(() => renderFn(props, fullRegistry, scopedVesk(renderFn, __vesk)));
|
|
87
104
|
}
|
|
88
105
|
finally {
|
|
89
106
|
delete globalThis.__vsk_ssr;
|
|
@@ -119,7 +136,7 @@ export function renderPage(source, componentName, props = {}, registry = new Map
|
|
|
119
136
|
return withSsrStore(() => (async () => {
|
|
120
137
|
let bodyHtml;
|
|
121
138
|
try {
|
|
122
|
-
bodyHtml = await renderFn(ssrProps, fullRegistry, __vesk);
|
|
139
|
+
bodyHtml = await renderFn(ssrProps, fullRegistry, scopedVesk(renderFn, __vesk));
|
|
123
140
|
}
|
|
124
141
|
finally {
|
|
125
142
|
delete globalThis.__vsk_ssr;
|
|
@@ -134,7 +151,7 @@ export function renderPage(source, componentName, props = {}, registry = new Map
|
|
|
134
151
|
}
|
|
135
152
|
let bodyHtml;
|
|
136
153
|
try {
|
|
137
|
-
bodyHtml = withSsrStore(() => renderFn(ssrProps, fullRegistry, __vesk));
|
|
154
|
+
bodyHtml = withSsrStore(() => renderFn(ssrProps, fullRegistry, scopedVesk(renderFn, __vesk)));
|
|
138
155
|
}
|
|
139
156
|
finally {
|
|
140
157
|
delete globalThis.__vsk_ssr;
|
|
@@ -175,8 +192,8 @@ function clearSsrCells(token) {
|
|
|
175
192
|
}
|
|
176
193
|
}
|
|
177
194
|
export async function ssg(source, componentName, customProps, options = {}) {
|
|
178
|
-
const ast = parse(source);
|
|
179
|
-
const ir = generateIR(ast, source);
|
|
195
|
+
const ast = parse(source, options.sourcePath ? { filename: options.sourcePath } : {});
|
|
196
|
+
const ir = generateIR(ast, source, options.sourcePath);
|
|
180
197
|
if (!componentName) {
|
|
181
198
|
const defaultComp = ir.components.find((c) => c.defaultExport);
|
|
182
199
|
const exportedComp = ir.components.find((c) => c.exported);
|
|
@@ -268,7 +285,7 @@ export async function renderFullPage(source, componentName, props = {}, registry
|
|
|
268
285
|
let ssrProps = { ...props };
|
|
269
286
|
let serializedProps = null;
|
|
270
287
|
const cached = options.cached || undefined;
|
|
271
|
-
const ir = cached ? cached.ir : generateIR(parse(source), source);
|
|
288
|
+
const ir = cached ? cached.ir : generateIR(parse(source, options.sourcePath ? { filename: options.sourcePath } : {}), source, options.sourcePath);
|
|
272
289
|
if (ir.loadFn) {
|
|
273
290
|
const __vesk = options.__vesk || cached?.__vesk || loadRuntimeImports(ir.imports);
|
|
274
291
|
const loadResult = await callLoadFunction(ir.loadFn, ssrProps, __vesk);
|
|
@@ -334,7 +351,7 @@ ${dataScriptBlock}${clientScript}</body>
|
|
|
334
351
|
export function renderPageStream(source, componentName, props = {}, registry = new Map(), options = {}) {
|
|
335
352
|
async function* raw() {
|
|
336
353
|
const cached = options.cached || undefined;
|
|
337
|
-
const ir = cached ? cached.ir : generateIR(parse(source), source);
|
|
354
|
+
const ir = cached ? cached.ir : generateIR(parse(source, options.sourcePath ? { filename: options.sourcePath } : {}), source, options.sourcePath);
|
|
338
355
|
let ssrProps = { ...props };
|
|
339
356
|
let serializedProps = null;
|
|
340
357
|
let __vesk = options.__vesk || cached?.__vesk || null;
|
|
@@ -394,7 +411,7 @@ export function renderPageStream(source, componentName, props = {}, registry = n
|
|
|
394
411
|
const renderToken = globalThis.__vsk_ssr_token;
|
|
395
412
|
let bodyHtml;
|
|
396
413
|
try {
|
|
397
|
-
bodyHtml = await Promise.resolve(renderFn(ssrProps, fullRegistry, __vesk));
|
|
414
|
+
bodyHtml = await Promise.resolve(renderFn(ssrProps, fullRegistry, scopedVesk(renderFn, __vesk)));
|
|
398
415
|
}
|
|
399
416
|
finally {
|
|
400
417
|
delete globalThis.__vsk_ssr;
|
|
@@ -404,7 +421,12 @@ export function renderPageStream(source, componentName, props = {}, registry = n
|
|
|
404
421
|
const ssrData = { ...ssrSink.snapshot() };
|
|
405
422
|
const dataScripts = buildDataScripts(ssrProps, ssrData, options.externalDataScript);
|
|
406
423
|
const dataScriptBlock = dataScripts.length > 0 ? '\n' + dataScripts.join('\n') : '';
|
|
407
|
-
|
|
424
|
+
// Mirror renderFullPage: a full document must carry the client bundle or
|
|
425
|
+
// the page can never hydrate (dev-server streams hit this path).
|
|
426
|
+
const clientScript = options.clientScriptUrl
|
|
427
|
+
? `\t<script type="module" src="${options.clientScriptUrl}"></script>\n`
|
|
428
|
+
: '';
|
|
429
|
+
yield `\n</div>${dataScriptBlock}${clientScript}</body>\n</html>\n`;
|
|
408
430
|
}
|
|
409
431
|
const gen = raw();
|
|
410
432
|
async function* scoped() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
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.12",
|
|
24
24
|
"acorn": "^8.15.0",
|
|
25
25
|
"esrap": "^2.3.0",
|
|
26
26
|
"is-reference": "^3.0.0",
|