@vesk/compiler 0.2.49 → 0.2.50-canary.10
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/ir-generator.d.ts.map +1 -1
- package/dist/ir-generator.js +21 -1
- package/dist/ir.d.ts +7 -0
- package/dist/ir.d.ts.map +1 -1
- package/dist/ir.js +7 -0
- package/dist/module-imports.d.ts +25 -0
- package/dist/module-imports.d.ts.map +1 -1
- package/dist/module-imports.js +172 -4
- package/dist/precompile-runtime.d.ts +8 -0
- package/dist/precompile-runtime.d.ts.map +1 -1
- package/dist/precompile.js +4 -0
- package/dist/scan.d.ts +15 -0
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +64 -0
- package/dist/server-head.d.ts +15 -0
- package/dist/server-head.d.ts.map +1 -1
- package/dist/server-head.js +30 -0
- package/dist/server-jsgen.d.ts.map +1 -1
- package/dist/server-jsgen.js +102 -3
- package/dist/server-render.d.ts.map +1 -1
- package/dist/server-render.js +25 -8
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ir-generator.d.ts","sourceRoot":"","sources":["../src/ir-generator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,MAAM,EAsBP,MAAM,uBAAuB,CAAC;AA2T/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;AA6nCD,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"ir-generator.d.ts","sourceRoot":"","sources":["../src/ir-generator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,MAAM,EAsBP,MAAM,uBAAuB,CAAC;AA2T/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;AA6nCD,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAqT9E"}
|
package/dist/ir-generator.js
CHANGED
|
@@ -1610,6 +1610,13 @@ export function generateIR(ast, source, filename) {
|
|
|
1610
1610
|
const importedNames = new Set();
|
|
1611
1611
|
let staticProps = null;
|
|
1612
1612
|
let loadFn = null;
|
|
1613
|
+
// `export const metadata = defineMetadata({...})` — the SOURCE of the
|
|
1614
|
+
// expression, captured like `load`/`getStaticProps`. It is evaluated in a
|
|
1615
|
+
// sandbox with nothing in scope but `defineMetadata`, so a static head can
|
|
1616
|
+
// never depend on the component's frame evaluating correctly (the class of
|
|
1617
|
+
// bug the `<Head>` interpolation path is prone to) and can never be
|
|
1618
|
+
// non-deterministic.
|
|
1619
|
+
let metadataSource = null;
|
|
1613
1620
|
const topLevelCode = [];
|
|
1614
1621
|
const exportAliases = [];
|
|
1615
1622
|
const reexportSources = [];
|
|
@@ -1660,6 +1667,17 @@ export function generateIR(ast, source, filename) {
|
|
|
1660
1667
|
continue;
|
|
1661
1668
|
}
|
|
1662
1669
|
}
|
|
1670
|
+
if (node.type === 'ExportNamedDeclaration' && node.declaration && !metadataSource) {
|
|
1671
|
+
const decl = node.declaration;
|
|
1672
|
+
const first = decl.type === 'VariableDeclaration' ? decl.declarations[0] : null;
|
|
1673
|
+
if (first?.id?.name === 'metadata') {
|
|
1674
|
+
// The INITIALIZER, not the declaration: the sandbox evaluates this as
|
|
1675
|
+
// an expression (`return ( … )`), so a `const metadata = …` wrapper
|
|
1676
|
+
// would be a syntax error.
|
|
1677
|
+
metadataSource = first.init ? stripCodeTypes(getSource(source, first.init)) : null;
|
|
1678
|
+
continue;
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1663
1681
|
if (node.type === 'ExportNamedDeclaration' && node.declaration && !loadFn) {
|
|
1664
1682
|
const decl = node.declaration;
|
|
1665
1683
|
const fnName = decl.type === 'FunctionDeclaration'
|
|
@@ -1890,7 +1908,9 @@ export function generateIR(ast, source, filename) {
|
|
|
1890
1908
|
imports.push(`import { ${missing.join(', ')} } from '@vesk/runtime';`);
|
|
1891
1909
|
}
|
|
1892
1910
|
}
|
|
1893
|
-
|
|
1911
|
+
const irRoot = new IRRoot(components, imports, importedNames, staticProps, loadFn, topLevelCode, exportAliases, reexportSources);
|
|
1912
|
+
irRoot.metadataSource = metadataSource;
|
|
1913
|
+
return irRoot;
|
|
1894
1914
|
}
|
|
1895
1915
|
finally {
|
|
1896
1916
|
currentVskNamespaceLocals = prevNamespaceLocals;
|
package/dist/ir.d.ts
CHANGED
|
@@ -12,6 +12,13 @@ export declare class IRRoot {
|
|
|
12
12
|
importedNames: Set<string>;
|
|
13
13
|
staticProps: string | null;
|
|
14
14
|
loadFn: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Source of `export const metadata = defineMetadata({...})`, when present.
|
|
17
|
+
* Static by construction: evaluated with only `defineMetadata` in scope, at
|
|
18
|
+
* build time where possible and in a sealed sandbox at request time
|
|
19
|
+
* otherwise, so the head never depends on the component's frame.
|
|
20
|
+
*/
|
|
21
|
+
metadataSource?: string | null;
|
|
15
22
|
topLevelCode: string[];
|
|
16
23
|
/**
|
|
17
24
|
* Same-file specifier exports (`export { A }`, `export { A as B }`) as
|
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
|
@@ -16,6 +16,13 @@ export class IRRoot {
|
|
|
16
16
|
importedNames;
|
|
17
17
|
staticProps;
|
|
18
18
|
loadFn;
|
|
19
|
+
/**
|
|
20
|
+
* Source of `export const metadata = defineMetadata({...})`, when present.
|
|
21
|
+
* Static by construction: evaluated with only `defineMetadata` in scope, at
|
|
22
|
+
* build time where possible and in a sealed sandbox at request time
|
|
23
|
+
* otherwise, so the head never depends on the component's frame.
|
|
24
|
+
*/
|
|
25
|
+
metadataSource;
|
|
19
26
|
topLevelCode;
|
|
20
27
|
/**
|
|
21
28
|
* Same-file specifier exports (`export { A }`, `export { A as B }`) as
|
package/dist/module-imports.d.ts
CHANGED
|
@@ -74,6 +74,31 @@ export declare function resolveImportPath(spec: string, fromDir: string): string
|
|
|
74
74
|
* `node_modules`) share one cache entry and one module instance.
|
|
75
75
|
*/
|
|
76
76
|
export declare function resolveSsrModule(specifier: string, fromDir: string): string | null;
|
|
77
|
+
/**
|
|
78
|
+
* Resolve a subpath through a package's `exports` map.
|
|
79
|
+
*
|
|
80
|
+
* This is what makes a Vesk app work inside an existing pnpm/npm/yarn
|
|
81
|
+
* workspace. A modern workspace package declares `exports` and often NO `main`
|
|
82
|
+
* (or points `main` at a CJS build while the app imports ESM), and subpath
|
|
83
|
+
* imports (`@acme/ui/button`) resolve through the map rather than through the
|
|
84
|
+
* directory layout. Without this, such a package simply does not resolve, and
|
|
85
|
+
* the app has to vendor it.
|
|
86
|
+
*
|
|
87
|
+
* Conditions are tried in import order: `import`, `module`, `node`, `default`.
|
|
88
|
+
* A pattern (`./dist/*.js`) is matched with the single `*` capture.
|
|
89
|
+
*/
|
|
90
|
+
export declare function resolveExports(exportsField: unknown, subpath: string): string | null;
|
|
91
|
+
/**
|
|
92
|
+
* Resolve a bare specifier through a package's `module` field (the ESM entry
|
|
93
|
+
* in a package that also has a CJS `main`).
|
|
94
|
+
*/
|
|
95
|
+
export declare function resolveViaPackageModuleField(specifier: string, fromDir: string): string | null;
|
|
96
|
+
/**
|
|
97
|
+
* Resolve a bare specifier through its package's `exports` map, walking
|
|
98
|
+
* node_modules upwards. Returns null when the package has no map, does not
|
|
99
|
+
* export the subpath, or cannot be read.
|
|
100
|
+
*/
|
|
101
|
+
export declare function resolveViaPackageExports(specifier: string, fromDir: string): string | null;
|
|
77
102
|
/** Rewrites an ESM program body (imports/exports removed) into CJS statements. */
|
|
78
103
|
export declare function esmToCjs(body: Array<{
|
|
79
104
|
type: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-imports.d.ts","sourceRoot":"","sources":["../src/module-imports.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AA2ElD,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM7D;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOzD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgC1F;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQpE;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAIvD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,IAAI,CAuBN;AAiBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAiE7E;AAmFD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAgB3G;AAwXD,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU/D;AAgDD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiB/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAevE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"module-imports.d.ts","sourceRoot":"","sources":["../src/module-imports.ts"],"names":[],"mappings":"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"}
|
package/dist/module-imports.js
CHANGED
|
@@ -900,6 +900,21 @@ export function resolveSsrModule(specifier, fromDir) {
|
|
|
900
900
|
const aliased = resolveAliasModule(specifier, fromDir);
|
|
901
901
|
if (aliased)
|
|
902
902
|
return toRealPath(aliased);
|
|
903
|
+
// Bare specifier. A package's `exports` map is consulted BEFORE Node's own
|
|
904
|
+
// resolver: `createRequire.resolve` applies the CJS conditions, so it picks
|
|
905
|
+
// a `.cjs` build for a package that also ships ESM — and fails outright on
|
|
906
|
+
// an `import`-only package. Vesk emits ESM, so the `import` condition is
|
|
907
|
+
// the correct one. Node's resolver stays as the fallback (builtins, exotic
|
|
908
|
+
// conditions), and the node_modules walk after that.
|
|
909
|
+
const viaExports = resolveViaPackageExports(specifier, fromDir);
|
|
910
|
+
if (viaExports)
|
|
911
|
+
return viaExports;
|
|
912
|
+
// Same reasoning for the legacy fields: a package declaring both `module`
|
|
913
|
+
// and `main` wants the ESM build (Vesk emits ESM), while `createRequire`
|
|
914
|
+
// would take `main` and hand us the CJS one.
|
|
915
|
+
const viaModuleField = resolveViaPackageModuleField(specifier, fromDir);
|
|
916
|
+
if (viaModuleField)
|
|
917
|
+
return viaModuleField;
|
|
903
918
|
// Bare specifier — prefer the native resolver (exports map, conditions,
|
|
904
919
|
// builtins, symlinks), then fall back to a node_modules walk-up.
|
|
905
920
|
const native = nativeResolve(specifier, fromDir);
|
|
@@ -983,6 +998,145 @@ function statOrNull(p) {
|
|
|
983
998
|
return null;
|
|
984
999
|
}
|
|
985
1000
|
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Resolve a subpath through a package's `exports` map.
|
|
1003
|
+
*
|
|
1004
|
+
* This is what makes a Vesk app work inside an existing pnpm/npm/yarn
|
|
1005
|
+
* workspace. A modern workspace package declares `exports` and often NO `main`
|
|
1006
|
+
* (or points `main` at a CJS build while the app imports ESM), and subpath
|
|
1007
|
+
* imports (`@acme/ui/button`) resolve through the map rather than through the
|
|
1008
|
+
* directory layout. Without this, such a package simply does not resolve, and
|
|
1009
|
+
* the app has to vendor it.
|
|
1010
|
+
*
|
|
1011
|
+
* Conditions are tried in import order: `import`, `module`, `node`, `default`.
|
|
1012
|
+
* A pattern (`./dist/*.js`) is matched with the single `*` capture.
|
|
1013
|
+
*/
|
|
1014
|
+
export function resolveExports(exportsField, subpath) {
|
|
1015
|
+
const conditions = ['import', 'module', 'node', 'default'];
|
|
1016
|
+
const target = (value) => {
|
|
1017
|
+
if (typeof value === 'string')
|
|
1018
|
+
return value;
|
|
1019
|
+
if (!value || typeof value !== 'object')
|
|
1020
|
+
return null;
|
|
1021
|
+
for (const cond of conditions) {
|
|
1022
|
+
if (cond in value) {
|
|
1023
|
+
const got = target(value[cond]);
|
|
1024
|
+
if (got)
|
|
1025
|
+
return got;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
return null;
|
|
1029
|
+
};
|
|
1030
|
+
if (typeof exportsField === 'string')
|
|
1031
|
+
return subpath === '.' ? exportsField : null;
|
|
1032
|
+
if (!exportsField || typeof exportsField !== 'object')
|
|
1033
|
+
return null;
|
|
1034
|
+
const map = exportsField;
|
|
1035
|
+
if (subpath in map) {
|
|
1036
|
+
const direct = target(map[subpath]);
|
|
1037
|
+
if (direct)
|
|
1038
|
+
return direct;
|
|
1039
|
+
return null;
|
|
1040
|
+
}
|
|
1041
|
+
// Longest-prefix match for `./*` patterns, as Node does.
|
|
1042
|
+
let best = null;
|
|
1043
|
+
for (const key of Object.keys(map)) {
|
|
1044
|
+
const star = key.indexOf('*');
|
|
1045
|
+
if (star === -1)
|
|
1046
|
+
continue;
|
|
1047
|
+
const prefix = key.slice(0, star);
|
|
1048
|
+
const suffix = key.slice(star + 1);
|
|
1049
|
+
if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix))
|
|
1050
|
+
continue;
|
|
1051
|
+
if (subpath.length < prefix.length + suffix.length)
|
|
1052
|
+
continue;
|
|
1053
|
+
if (best === null || prefix.length > best.key.length) {
|
|
1054
|
+
best = { key: prefix, star: subpath.slice(prefix.length, subpath.length - suffix.length) };
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
if (!best)
|
|
1058
|
+
return null;
|
|
1059
|
+
const pattern = target(map[Object.keys(map).find((k) => k.startsWith(best.key + '*') && k.endsWith(best.key.slice(0, -1)) + '*')] ?? map[`${best.key}*`]);
|
|
1060
|
+
if (pattern === null)
|
|
1061
|
+
return null;
|
|
1062
|
+
return pattern.split('*').join(best.star);
|
|
1063
|
+
}
|
|
1064
|
+
/**
|
|
1065
|
+
* Resolve a bare specifier through a package's `module` field (the ESM entry
|
|
1066
|
+
* in a package that also has a CJS `main`).
|
|
1067
|
+
*/
|
|
1068
|
+
export function resolveViaPackageModuleField(specifier, fromDir) {
|
|
1069
|
+
const firstSlash = specifier.indexOf('/');
|
|
1070
|
+
const splitAt = specifier.startsWith('@') ? specifier.indexOf('/', firstSlash + 1) : firstSlash;
|
|
1071
|
+
const pkgName = splitAt > 0 ? specifier.slice(0, splitAt) : specifier;
|
|
1072
|
+
if (splitAt > 0)
|
|
1073
|
+
return null; // a subpath import needs the exports map
|
|
1074
|
+
let dir = fromDir;
|
|
1075
|
+
for (let depth = 0; depth < 64; depth++) {
|
|
1076
|
+
const pkgPath = join(dir, 'node_modules', pkgName, 'package.json');
|
|
1077
|
+
if (statOrNull(pkgPath) !== null) {
|
|
1078
|
+
try {
|
|
1079
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
1080
|
+
if (typeof pkg.module === 'string' && pkg.module.length > 0) {
|
|
1081
|
+
const found = probeFile(resolve(join(dir, 'node_modules', pkgName), pkg.module));
|
|
1082
|
+
if (found)
|
|
1083
|
+
return toRealPath(found);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
catch {
|
|
1087
|
+
// malformed package.json — fall through
|
|
1088
|
+
}
|
|
1089
|
+
return null;
|
|
1090
|
+
}
|
|
1091
|
+
const parent = dirname(dir);
|
|
1092
|
+
if (parent === dir)
|
|
1093
|
+
break;
|
|
1094
|
+
dir = parent;
|
|
1095
|
+
}
|
|
1096
|
+
return null;
|
|
1097
|
+
}
|
|
1098
|
+
/**
|
|
1099
|
+
* Resolve a bare specifier through its package's `exports` map, walking
|
|
1100
|
+
* node_modules upwards. Returns null when the package has no map, does not
|
|
1101
|
+
* export the subpath, or cannot be read.
|
|
1102
|
+
*/
|
|
1103
|
+
export function resolveViaPackageExports(specifier, fromDir) {
|
|
1104
|
+
// A scoped name (`@acme/ui`) has its slash INSIDE the package name — taking
|
|
1105
|
+
// the first slash as the subpath separator turns it into package `@acme` +
|
|
1106
|
+
// subpath `./ui`, which no `exports` map matches, and the lookup silently
|
|
1107
|
+
// falls through to Node's resolver.
|
|
1108
|
+
const firstSlash = specifier.indexOf('/');
|
|
1109
|
+
const splitAt = specifier.startsWith('@') ? specifier.indexOf('/', firstSlash + 1) : firstSlash;
|
|
1110
|
+
const pkgName = splitAt > 0 ? specifier.slice(0, splitAt) : specifier;
|
|
1111
|
+
const subpath = splitAt > 0 ? '.' + specifier.slice(splitAt) : '.';
|
|
1112
|
+
let dir = fromDir;
|
|
1113
|
+
for (let depth = 0; depth < 64; depth++) {
|
|
1114
|
+
const pkgDir = join(dir, 'node_modules', pkgName);
|
|
1115
|
+
const pkgPath = join(pkgDir, 'package.json');
|
|
1116
|
+
if (statOrNull(pkgPath) !== null) {
|
|
1117
|
+
try {
|
|
1118
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
1119
|
+
if (pkg.exports !== undefined) {
|
|
1120
|
+
const target = resolveExports(pkg.exports, subpath);
|
|
1121
|
+
if (target) {
|
|
1122
|
+
const found = probeFile(resolve(pkgDir, target));
|
|
1123
|
+
if (found)
|
|
1124
|
+
return toRealPath(found);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
catch {
|
|
1129
|
+
// malformed package.json — fall through to the resolvers below
|
|
1130
|
+
}
|
|
1131
|
+
return null;
|
|
1132
|
+
}
|
|
1133
|
+
const parent = dirname(dir);
|
|
1134
|
+
if (parent === dir)
|
|
1135
|
+
break;
|
|
1136
|
+
dir = parent;
|
|
1137
|
+
}
|
|
1138
|
+
return null;
|
|
1139
|
+
}
|
|
986
1140
|
function probeFile(base) {
|
|
987
1141
|
const st = statOrNull(base);
|
|
988
1142
|
if (st && st.isFile())
|
|
@@ -993,10 +1147,24 @@ function probeFile(base) {
|
|
|
993
1147
|
if (pkgSt && pkgSt.isFile()) {
|
|
994
1148
|
try {
|
|
995
1149
|
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1150
|
+
// `exports` first: it is what the package author intends and what a
|
|
1151
|
+
// workspace package usually ships. `main`/`module` are the legacy
|
|
1152
|
+
// fallbacks.
|
|
1153
|
+
if (pkg.exports !== undefined) {
|
|
1154
|
+
const viaExports = resolveExports(pkg.exports, '.');
|
|
1155
|
+
if (viaExports) {
|
|
1156
|
+
const found = probeFile(resolve(base, viaExports));
|
|
1157
|
+
if (found)
|
|
1158
|
+
return found;
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
for (const field of ['module', 'main']) {
|
|
1162
|
+
const value = pkg[field];
|
|
1163
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
1164
|
+
const found = probeFile(resolve(base, value));
|
|
1165
|
+
if (found)
|
|
1166
|
+
return found;
|
|
1167
|
+
}
|
|
1000
1168
|
}
|
|
1001
1169
|
}
|
|
1002
1170
|
catch {
|
|
@@ -27,6 +27,14 @@ export interface PrecompileFilePlan {
|
|
|
27
27
|
topLevelCode: string[];
|
|
28
28
|
/** The file's `.vsk` imports, precompiled recursively. */
|
|
29
29
|
subFiles: PrecompileSubFilePlan[];
|
|
30
|
+
/**
|
|
31
|
+
* Source of a static `export const metadata = defineMetadata({...})`.
|
|
32
|
+
*
|
|
33
|
+
* Carried as SOURCE, not as a value, so the plan stays pure JSON (it is
|
|
34
|
+
* embedded in a generated function and can be cached to disk). Evaluation
|
|
35
|
+
* happens in a sealed sandbox with only `defineMetadata` in scope.
|
|
36
|
+
*/
|
|
37
|
+
metadataSource?: string;
|
|
30
38
|
}
|
|
31
39
|
/**
|
|
32
40
|
* Recursively JSON-serializes an IR root. IR class instances are tagged with
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"precompile-runtime.d.ts","sourceRoot":"","sources":["../src/precompile-runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AA0BlE,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAe9F,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAExD,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAElD,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,EAAE,EAAE,OAAO,GAAG,IAAI,CAAC;IACnB,8DAA8D;IAC9D,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,2CAA2C;IAC3C,UAAU,EAAE,yBAAyB,EAAE,CAAC;IACxC,iEAAiE;IACjE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IACnC,2CAA2C;IAC3C,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,6EAA6E;IAC7E,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,EAAE,qBAAqB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"precompile-runtime.d.ts","sourceRoot":"","sources":["../src/precompile-runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AA0BlE,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAe9F,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAExD,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAElD,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,EAAE,EAAE,OAAO,GAAG,IAAI,CAAC;IACnB,8DAA8D;IAC9D,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,2CAA2C;IAC3C,UAAU,EAAE,yBAAyB,EAAE,CAAC;IACxC,iEAAiE;IACjE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IACnC,2CAA2C;IAC3C,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,6EAA6E;IAC7E,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAqCD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAiBhD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA0BlD;AAgHD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,iBAAiB,CAE7E"}
|
package/dist/precompile.js
CHANGED
|
@@ -74,6 +74,7 @@ function precompileFileInternal(source, sourcePath, seenImportFiles) {
|
|
|
74
74
|
setVskHydrate(false);
|
|
75
75
|
}
|
|
76
76
|
const topLevelCode = transformTopLevelForActions(ir.topLevelCode, 'server');
|
|
77
|
+
const metadataSource = ir.metadataSource || null;
|
|
77
78
|
const runtimeImports = ir.imports.slice();
|
|
78
79
|
const collector = { keysByAbs: new Map(), modules: [] };
|
|
79
80
|
const bindings = sourcePath !== undefined ? collectModuleBundle(ir.imports, dirname(sourcePath), collector) : [];
|
|
@@ -105,5 +106,8 @@ function precompileFileInternal(source, sourcePath, seenImportFiles) {
|
|
|
105
106
|
bindings,
|
|
106
107
|
topLevelCode,
|
|
107
108
|
subFiles,
|
|
109
|
+
// A static `export const metadata` rides along so a serverless function can
|
|
110
|
+
// serialize the head without the `.vsk` source being present at all.
|
|
111
|
+
...(metadataSource ? { metadataSource } : {}),
|
|
108
112
|
};
|
|
109
113
|
}
|
package/dist/scan.d.ts
CHANGED
|
@@ -93,6 +93,21 @@ export declare function hasTopLevelComma(text: string): boolean;
|
|
|
93
93
|
* and `for (... in ...)` headers apart from classic `for` loops.
|
|
94
94
|
*/
|
|
95
95
|
export declare function containsForOfIn(text: string): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Reports whether `ident` appears in `text` as a CALLED identifier — i.e.
|
|
98
|
+
* followed by an optional TS generic clause and then `(`.
|
|
99
|
+
*
|
|
100
|
+
* This is a character-loop tokenizer, not a text match: it steps over
|
|
101
|
+
* whitespace, `//` and block comments, and quoted / template strings, so
|
|
102
|
+
* `track(` appearing inside a string, a comment or a property access
|
|
103
|
+
* (`obj.track(...)`) never counts. Template literals are skipped whole —
|
|
104
|
+
* including their `${...}` holes — because a `track(` in an interpolation is
|
|
105
|
+
* not a reliable enough signal to inject a runtime binding for.
|
|
106
|
+
*
|
|
107
|
+
* Used to decide which runtime helpers a raw statement needs without
|
|
108
|
+
* requiring the caller to have been lowered into a TrackDecl first.
|
|
109
|
+
*/
|
|
110
|
+
export declare function callsIdentifier(text: string, ident: string): boolean;
|
|
96
111
|
/**
|
|
97
112
|
* Extracts the argument text of a `track<...>(...)` call from an init
|
|
98
113
|
* expression. Handles nested generics (`track<Map<string, number>>(...)`)
|
package/dist/scan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAItD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAOzE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWrD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAc9D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAsB1D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAY3D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmDlD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAkBvE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CA2BjE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgBtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAkBrD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYpD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOtD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAcnE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAqB9D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAY3D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAexD"}
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAItD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAOzE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWrD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAc9D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAsB1D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAY3D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmDlD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAkBvE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CA2BjE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgBtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAkBrD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAwDpE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYpD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOtD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAcnE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAqB9D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAY3D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAexD"}
|
package/dist/scan.js
CHANGED
|
@@ -408,6 +408,70 @@ export function containsForOfIn(text) {
|
|
|
408
408
|
}
|
|
409
409
|
return false;
|
|
410
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* Reports whether `ident` appears in `text` as a CALLED identifier — i.e.
|
|
413
|
+
* followed by an optional TS generic clause and then `(`.
|
|
414
|
+
*
|
|
415
|
+
* This is a character-loop tokenizer, not a text match: it steps over
|
|
416
|
+
* whitespace, `//` and block comments, and quoted / template strings, so
|
|
417
|
+
* `track(` appearing inside a string, a comment or a property access
|
|
418
|
+
* (`obj.track(...)`) never counts. Template literals are skipped whole —
|
|
419
|
+
* including their `${...}` holes — because a `track(` in an interpolation is
|
|
420
|
+
* not a reliable enough signal to inject a runtime binding for.
|
|
421
|
+
*
|
|
422
|
+
* Used to decide which runtime helpers a raw statement needs without
|
|
423
|
+
* requiring the caller to have been lowered into a TrackDecl first.
|
|
424
|
+
*/
|
|
425
|
+
export function callsIdentifier(text, ident) {
|
|
426
|
+
let i = 0;
|
|
427
|
+
const len = text.length;
|
|
428
|
+
// True when the previous significant character means the next identifier
|
|
429
|
+
// is a member access (`obj.track`) rather than a free call.
|
|
430
|
+
let afterDot = false;
|
|
431
|
+
while (i < len) {
|
|
432
|
+
const ch = text[i];
|
|
433
|
+
if (isWhitespaceChar(ch)) {
|
|
434
|
+
i++;
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
const commentEnd = skipComment(text, i);
|
|
438
|
+
if (commentEnd !== i) {
|
|
439
|
+
i = commentEnd;
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
if (ch === '"' || ch === "'" || ch === '`') {
|
|
443
|
+
i = skipString(text, i);
|
|
444
|
+
afterDot = false;
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
if (ch === '.' || (ch === '?' && text[i + 1] === '.')) {
|
|
448
|
+
afterDot = true;
|
|
449
|
+
i += ch === '.' ? 1 : 2;
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
if (isIdentStartCode(ch.charCodeAt(0))) {
|
|
453
|
+
let j = i + 1;
|
|
454
|
+
while (j < len && isIdentCharCode(text.charCodeAt(j)))
|
|
455
|
+
j++;
|
|
456
|
+
const name = text.slice(i, j);
|
|
457
|
+
let k = skipWhitespace(text, j);
|
|
458
|
+
// A `name<T,>(...)` generic call — skip the balanced `<...>`.
|
|
459
|
+
if (text[k] === '<') {
|
|
460
|
+
k = skipTrackGeneric(text, k);
|
|
461
|
+
k = skipWhitespace(text, k);
|
|
462
|
+
}
|
|
463
|
+
if (name === ident && text[k] === '(' && !afterDot) {
|
|
464
|
+
return true;
|
|
465
|
+
}
|
|
466
|
+
afterDot = false;
|
|
467
|
+
i = j;
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
afterDot = false;
|
|
471
|
+
i++;
|
|
472
|
+
}
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
411
475
|
/**
|
|
412
476
|
* Extracts the argument text of a `track<...>(...)` call from an init
|
|
413
477
|
* expression. Handles nested generics (`track<Map<string, number>>(...)`)
|
package/dist/server-head.d.ts
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
import type { ComponentIR } from '@vesk/compiler/src/ir';
|
|
2
|
+
/**
|
|
3
|
+
* Evaluate a static `export const metadata = …` in a SEALED sandbox.
|
|
4
|
+
*
|
|
5
|
+
* The sandbox has exactly one binding — `defineMetadata` — and no access to
|
|
6
|
+
* globals, the request, or the component. That is the whole point: a static
|
|
7
|
+
* head must not be able to depend on the component's frame evaluating
|
|
8
|
+
* correctly (which is how `<title>{doc.title}</title>` came out empty), and it
|
|
9
|
+
* must not be able to be non-deterministic. Anything that needs state belongs
|
|
10
|
+
* in `<Head>`, which is reactive.
|
|
11
|
+
*
|
|
12
|
+
* Returns null — never throws — for a source that will not evaluate, so a
|
|
13
|
+
* broken metadata declaration degrades to "no static head" rather than taking
|
|
14
|
+
* the page down.
|
|
15
|
+
*/
|
|
16
|
+
export declare function renderStaticMetadataHtml(source: string | null | undefined): string;
|
|
2
17
|
/**
|
|
3
18
|
* Serialize one component's `<Head>` block.
|
|
4
19
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-head.d.ts","sourceRoot":"","sources":["../src/server-head.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"server-head.d.ts","sourceRoot":"","sources":["../src/server-head.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAiVzD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAYlF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,EACjB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAClC,MAAM,CAkBR;AAoFD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAkExI"}
|
package/dist/server-head.js
CHANGED
|
@@ -3,6 +3,7 @@ import { tryEvalExpr, escapeHtml } from '@vesk/compiler/src/server-utils';
|
|
|
3
3
|
import { isWhitespaceChar } from '@vesk/compiler/src/scan';
|
|
4
4
|
import { parse } from '@vesk/compiler/src/parser';
|
|
5
5
|
import { collectTrackedNames, transformTracked, transformTrackedInit } from '@vesk/compiler/src/client-codegen';
|
|
6
|
+
import { defineMetadata as metadataShim, metadataToHtml } from '@vesk/runtime/src/metadata';
|
|
6
7
|
import { walk } from 'zimmerframe';
|
|
7
8
|
function isHtmlNameChar(ch) {
|
|
8
9
|
const code = ch.charCodeAt(0);
|
|
@@ -310,6 +311,35 @@ function irNodeToHeadHtml(node, ctx, reconcileable = false) {
|
|
|
310
311
|
}
|
|
311
312
|
return '';
|
|
312
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* Evaluate a static `export const metadata = …` in a SEALED sandbox.
|
|
316
|
+
*
|
|
317
|
+
* The sandbox has exactly one binding — `defineMetadata` — and no access to
|
|
318
|
+
* globals, the request, or the component. That is the whole point: a static
|
|
319
|
+
* head must not be able to depend on the component's frame evaluating
|
|
320
|
+
* correctly (which is how `<title>{doc.title}</title>` came out empty), and it
|
|
321
|
+
* must not be able to be non-deterministic. Anything that needs state belongs
|
|
322
|
+
* in `<Head>`, which is reactive.
|
|
323
|
+
*
|
|
324
|
+
* Returns null — never throws — for a source that will not evaluate, so a
|
|
325
|
+
* broken metadata declaration degrades to "no static head" rather than taking
|
|
326
|
+
* the page down.
|
|
327
|
+
*/
|
|
328
|
+
export function renderStaticMetadataHtml(source) {
|
|
329
|
+
if (!source)
|
|
330
|
+
return '';
|
|
331
|
+
try {
|
|
332
|
+
// Imported lazily and by module path so this stays a server-side concern
|
|
333
|
+
// and does not pull the runtime into a client bundle.
|
|
334
|
+
const fn = new Function('defineMetadata', 'return (' + source + ')');
|
|
335
|
+
const meta = fn(metadataShim);
|
|
336
|
+
return metadataToHtml(meta);
|
|
337
|
+
}
|
|
338
|
+
catch (e) {
|
|
339
|
+
console.error('vesk: static metadata could not be evaluated:', e instanceof Error ? e.message : e);
|
|
340
|
+
return '';
|
|
341
|
+
}
|
|
342
|
+
}
|
|
313
343
|
/**
|
|
314
344
|
* Serialize one component's `<Head>` block.
|
|
315
345
|
*
|
|
@@ -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;AAoDrK,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,CAgEjJ;AA4XD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAqD1F;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;
|
|
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;AAoDrK,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,CAgEjJ;AA4XD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAqD1F;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAuFD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAkCzE;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
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { StaticNode, TextNode, DynamicBinding, OpaqueDynamicRegion, MapRegion, WhileLoop, SwitchBlock, TryCatch, ForLoop, TrackDecl, RuntimeStatement, ComponentRef, ComponentCall, ServerBlock, ClientBlock, HeadBlock, SlotNode, PropSlot, PropSlotRender, } from '@vesk/compiler/src/ir';
|
|
1
|
+
import { Expression, StaticNode, TextNode, DynamicBinding, OpaqueDynamicRegion, MapRegion, WhileLoop, SwitchBlock, TryCatch, ForLoop, TrackDecl, RuntimeStatement, ComponentRef, ComponentCall, ServerBlock, ClientBlock, HeadBlock, SlotNode, PropSlot, PropSlotRender, } from '@vesk/compiler/src/ir';
|
|
2
2
|
import { isStaticIR, collectTrackedNames, transformTracked, transformTrackedInit, semicolonizeStatement } from '@vesk/compiler/src/client-codegen';
|
|
3
|
-
import { unwrapTrackCall, stripTrackGeneric, hasTopLevelComma, skipWhitespace, findBalancedEnd, startsWithIdentifier } from '@vesk/compiler/src/scan';
|
|
3
|
+
import { unwrapTrackCall, stripTrackGeneric, hasTopLevelComma, skipWhitespace, findBalancedEnd, startsWithIdentifier, callsIdentifier } from '@vesk/compiler/src/scan';
|
|
4
4
|
import { escapeHtml, indent, exprJS, extractTopLevelNames, extractRuntimeNames, buildParamInit, __vskHydrate, __vskMarkerless, __vskImportedNames, setVskImportedNames, setVskForceClaim, takeVskForceClaim, nextVskId, } from '@vesk/compiler/src/server-utils';
|
|
5
5
|
import { localValueImportNames } from '@vesk/compiler/src/module-imports';
|
|
6
6
|
import { vskImportValueNames } from '@vesk/compiler/src/vsk-imports';
|
|
@@ -563,6 +563,105 @@ export function generateFunctionBody(comp, importedNames) {
|
|
|
563
563
|
__currentCompName = '';
|
|
564
564
|
return lines.join('\n');
|
|
565
565
|
}
|
|
566
|
+
/**
|
|
567
|
+
* Whether a component body needs `track` / `get` / `set` destructured into its
|
|
568
|
+
* `__vesk` scope.
|
|
569
|
+
*
|
|
570
|
+
* A `TrackDecl` (`const &[n] = track(0)`) always needs them. A PLAIN
|
|
571
|
+
* `const n = track(0)` does not lower to a TrackDecl — it stays a raw
|
|
572
|
+
* `RuntimeStatement` whose source still calls `track` — and used to reach the
|
|
573
|
+
* server renderer unbound, taking the whole page down with
|
|
574
|
+
* "track is not defined". The client codegen imports these names
|
|
575
|
+
* unconditionally, so the server has to recognise the plain form too or the
|
|
576
|
+
* two halves of a file disagree about what is in scope.
|
|
577
|
+
*/
|
|
578
|
+
function bodyNeedsRuntimeCells(nodes) {
|
|
579
|
+
for (const node of nodes) {
|
|
580
|
+
if (node instanceof TrackDecl)
|
|
581
|
+
return true;
|
|
582
|
+
// Raw statement / expression text: the only place a plain `track(...)`
|
|
583
|
+
// call can appear outside a lowered node.
|
|
584
|
+
if (node instanceof RuntimeStatement && callsIdentifier(node.raw, 'track'))
|
|
585
|
+
return true;
|
|
586
|
+
if (node instanceof Expression && callsIdentifier(node.raw, 'track'))
|
|
587
|
+
return true;
|
|
588
|
+
if (node instanceof ForLoop) {
|
|
589
|
+
if (callsIdentifier(node.init, 'track'))
|
|
590
|
+
return true;
|
|
591
|
+
if (callsIdentifier(node.update, 'track'))
|
|
592
|
+
return true;
|
|
593
|
+
if (callsIdentifier(node.condition.raw, 'track'))
|
|
594
|
+
return true;
|
|
595
|
+
if (bodyNeedsRuntimeCells(node.bodyTemplate))
|
|
596
|
+
return true;
|
|
597
|
+
}
|
|
598
|
+
if (node instanceof StaticNode) {
|
|
599
|
+
for (const attr of node.attributes) {
|
|
600
|
+
if (callsIdentifier(attr.value, 'track'))
|
|
601
|
+
return true;
|
|
602
|
+
}
|
|
603
|
+
if (bodyNeedsRuntimeCells(node.children))
|
|
604
|
+
return true;
|
|
605
|
+
}
|
|
606
|
+
if (node instanceof ComponentCall) {
|
|
607
|
+
for (const prop of node.props) {
|
|
608
|
+
if (callsIdentifier(prop.value.raw, 'track'))
|
|
609
|
+
return true;
|
|
610
|
+
}
|
|
611
|
+
for (const spread of node.spreadProps) {
|
|
612
|
+
if (callsIdentifier(spread.raw, 'track'))
|
|
613
|
+
return true;
|
|
614
|
+
}
|
|
615
|
+
if (bodyNeedsRuntimeCells(node.children))
|
|
616
|
+
return true;
|
|
617
|
+
}
|
|
618
|
+
if (node instanceof ServerBlock || node instanceof ClientBlock || node instanceof HeadBlock) {
|
|
619
|
+
if (bodyNeedsRuntimeCells(node.children))
|
|
620
|
+
return true;
|
|
621
|
+
}
|
|
622
|
+
if (node instanceof PropSlot && bodyNeedsRuntimeCells(node.body))
|
|
623
|
+
return true;
|
|
624
|
+
if (node instanceof MapRegion) {
|
|
625
|
+
if (callsIdentifier(node.expression.raw, 'track'))
|
|
626
|
+
return true;
|
|
627
|
+
if (bodyNeedsRuntimeCells(node.bodyTemplate))
|
|
628
|
+
return true;
|
|
629
|
+
if (bodyNeedsRuntimeCells(node.alternateNodes))
|
|
630
|
+
return true;
|
|
631
|
+
}
|
|
632
|
+
if (node instanceof OpaqueDynamicRegion) {
|
|
633
|
+
if (callsIdentifier(node.condition.raw, 'track'))
|
|
634
|
+
return true;
|
|
635
|
+
if (bodyNeedsRuntimeCells(node.consequentNodes))
|
|
636
|
+
return true;
|
|
637
|
+
if (bodyNeedsRuntimeCells(node.alternateNodes))
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
if (node instanceof WhileLoop) {
|
|
641
|
+
if (callsIdentifier(node.condition.raw, 'track'))
|
|
642
|
+
return true;
|
|
643
|
+
if (bodyNeedsRuntimeCells(node.bodyTemplate))
|
|
644
|
+
return true;
|
|
645
|
+
}
|
|
646
|
+
if (node instanceof SwitchBlock) {
|
|
647
|
+
if (callsIdentifier(node.discriminant.raw, 'track'))
|
|
648
|
+
return true;
|
|
649
|
+
for (const c of node.cases) {
|
|
650
|
+
if (c.test && callsIdentifier(c.test.raw, 'track'))
|
|
651
|
+
return true;
|
|
652
|
+
if (bodyNeedsRuntimeCells(c.body))
|
|
653
|
+
return true;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
if (node instanceof TryCatch) {
|
|
657
|
+
if (bodyNeedsRuntimeCells(node.bodyTemplate))
|
|
658
|
+
return true;
|
|
659
|
+
if (bodyNeedsRuntimeCells(node.catchBody))
|
|
660
|
+
return true;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return false;
|
|
664
|
+
}
|
|
566
665
|
/**
|
|
567
666
|
* Builds the compiled body source for every component in an IR root. Used by
|
|
568
667
|
* both `buildComponentMap` (live functions) and `precompile.ts` (AOT SSR plans
|
|
@@ -579,7 +678,7 @@ export function buildComponentEntries(irRoot) {
|
|
|
579
678
|
const componentNames = new Set(irRoot.components.map((c) => c.name));
|
|
580
679
|
const topValueNames = topNames.filter((n) => !componentNames.has(n));
|
|
581
680
|
const importedNames = new Set([...runtimeNames, ...localValueNames, ...topValueNames]);
|
|
582
|
-
const hasTracked = irRoot.components.some((c) => c.body
|
|
681
|
+
const hasTracked = irRoot.components.some((c) => bodyNeedsRuntimeCells(c.body));
|
|
583
682
|
const extraNames = hasTracked ? ['get', 'set', 'track'] : [];
|
|
584
683
|
// Values exported by a `.vsk` module (`export const MAX = 10`) are hoisted
|
|
585
684
|
// into this file's `__vesk` and must be destructured into component scope.
|
|
@@ -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;AAuCvJ,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"server-render.d.ts","sourceRoot":"","sources":["../src/server-render.ts"],"names":[],"mappings":"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"}
|
package/dist/server-render.js
CHANGED
|
@@ -5,7 +5,7 @@ import { parse } from '@vesk/compiler/src/parser';
|
|
|
5
5
|
import { generateIR } from '@vesk/compiler/src/ir-generator';
|
|
6
6
|
import { compileClient, isStaticIR } from '@vesk/compiler/src/client-codegen';
|
|
7
7
|
import { isStatic, prettifyHtml, resetVskState, loadRuntimeImports, evalTopLevelCode, callStaticProps, callLoadFunction, safeJsonForScript, quoteAttr, } from '@vesk/compiler/src/server-utils';
|
|
8
|
-
import { renderHeadHtml, mergeHeadHtml } from '@vesk/compiler/src/server-head';
|
|
8
|
+
import { renderHeadHtml, renderStaticMetadataHtml, mergeHeadHtml } from '@vesk/compiler/src/server-head';
|
|
9
9
|
import { buildComponentMap } from '@vesk/compiler/src/server-jsgen';
|
|
10
10
|
import { transformTopLevelForActions } from '@vesk/compiler/src/actions';
|
|
11
11
|
import { collectVskImportPaths, collectVskReexportPaths, vskRegistryAliases, applyVskRegistryAliases } from '@vesk/compiler/src/vsk-imports';
|
|
@@ -26,6 +26,7 @@ export function compileFile(source, options) {
|
|
|
26
26
|
const owners = new VskComponentOwners();
|
|
27
27
|
const result = compileFileInternal(source, options?.sourcePath, new Set(), owners);
|
|
28
28
|
owners.report('SSR');
|
|
29
|
+
result.metadataSource = result.ir.metadataSource || null;
|
|
29
30
|
return result;
|
|
30
31
|
}
|
|
31
32
|
function compileFileInternal(source, sourcePath, seenImportFiles, owners) {
|
|
@@ -159,6 +160,8 @@ export function renderPage(source, componentName, props = {}, registry = new Map
|
|
|
159
160
|
throw new Error(`Component "${componentName}" not found in source`);
|
|
160
161
|
const fullRegistry = new Map([...registry, ...componentMap]);
|
|
161
162
|
const targetComp = ir.components.find((c) => c.name === componentName);
|
|
163
|
+
// A static `export const metadata` on this .vsk file, if any.
|
|
164
|
+
const metadataSource = (ir.metadataSource || null);
|
|
162
165
|
const doRender = (ssrProps) => {
|
|
163
166
|
globalThis.__vsk_ssr = true;
|
|
164
167
|
// Reuse an in-flight render token: the generated adapter handler renders
|
|
@@ -187,9 +190,12 @@ export function renderPage(source, componentName, props = {}, registry = new Map
|
|
|
187
190
|
}
|
|
188
191
|
return {
|
|
189
192
|
body: bodyHtml,
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
+
// A static `export const metadata` wins: it is evaluated in a sealed
|
|
194
|
+
// sandbox, so it cannot depend on the component's frame resolving
|
|
195
|
+
// (the failure mode that shipped an empty <title>). Whatever the
|
|
196
|
+
// page's `<Head>` adds is appended, not lost.
|
|
197
|
+
head: [renderStaticMetadataHtml(metadataSource), renderHeadHtml(targetComp, ssrProps, scopedVesk(renderFn, __vesk))]
|
|
198
|
+
.filter(Boolean).join('\n'),
|
|
193
199
|
props: ssrProps
|
|
194
200
|
};
|
|
195
201
|
})();
|
|
@@ -201,7 +207,10 @@ export function renderPage(source, componentName, props = {}, registry = new Map
|
|
|
201
207
|
finally {
|
|
202
208
|
delete globalThis.__vsk_ssr;
|
|
203
209
|
}
|
|
204
|
-
const headHtml =
|
|
210
|
+
const headHtml = [
|
|
211
|
+
renderStaticMetadataHtml(metadataSource),
|
|
212
|
+
targetComp ? renderHeadHtml(targetComp, ssrProps, scopedVesk(renderFn, __vesk)) : '',
|
|
213
|
+
].filter(Boolean).join('\n');
|
|
205
214
|
const pending = globalThis[`__vsk_ssr_promises_${renderToken}`];
|
|
206
215
|
if (pending && pending.length > 0) {
|
|
207
216
|
// A sync component still started server resources (useFetch): settle them
|
|
@@ -236,6 +245,7 @@ function clearSsrCells(token) {
|
|
|
236
245
|
if (!token)
|
|
237
246
|
return;
|
|
238
247
|
delete globalThis[`__vsk_ssr_promises_${token}`];
|
|
248
|
+
delete globalThis[`__vsk_ssr_deferred_${token}`];
|
|
239
249
|
delete globalThis[`__vsk_ssr_failures_${token}`];
|
|
240
250
|
// This render is done with the token: release the slot so the reaper below
|
|
241
251
|
// can collect paths that never run renderFullPage (a bare renderPage/render
|
|
@@ -516,8 +526,11 @@ export async function renderFullPage(source, componentName, props = {}, registry
|
|
|
516
526
|
const bodyHtml = prettifyHtml(rendered.body);
|
|
517
527
|
const cssUrls = options.cssUrls || (options.cssUrl ? [options.cssUrl] : []);
|
|
518
528
|
const cssLink = cssUrls.map(u => `\t<link rel="stylesheet" href="${u}" />\n`).join('');
|
|
529
|
+
// `crossorigin` is required for SRI to be enforced on a module script; a
|
|
530
|
+
// same-origin module is fetched in CORS mode, so the attribute is harmless
|
|
531
|
+
// and makes the digest meaningful.
|
|
519
532
|
const clientScript = options.clientScriptUrl
|
|
520
|
-
? `\t<script type="module" src="${options.clientScriptUrl}"></script>\n`
|
|
533
|
+
? `\t<script type="module" src="${options.clientScriptUrl}"${options.clientScriptIntegrity ? ` integrity="${options.clientScriptIntegrity}" crossorigin="anonymous"` : ''}></script>\n`
|
|
521
534
|
: '';
|
|
522
535
|
const dataScripts = buildDataScripts(ssrProps, ssrData, options.externalDataScript);
|
|
523
536
|
const dataScriptBlock = dataScripts.length > 0 ? '\n' + dataScripts.join('\n') + '\n' : '';
|
|
@@ -602,6 +615,7 @@ export function renderPageStream(source, componentName, props = {}, registry = n
|
|
|
602
615
|
throw new Error(`Component "${componentName}" not found in source`);
|
|
603
616
|
resetVskState(!!options.hydrate, options.markerless !== false);
|
|
604
617
|
const targetComp = ir.components.find((c) => c.name === componentName);
|
|
618
|
+
const metadataSource = (cached?.metadataSource ?? ir.metadataSource ?? null);
|
|
605
619
|
const cssUrls = options.cssUrls || (options.cssUrl ? [options.cssUrl] : []);
|
|
606
620
|
const cssLink = cssUrls.map(u => `\t<link rel="stylesheet" href="${u}" />\n`).join('');
|
|
607
621
|
const headParts = [];
|
|
@@ -618,7 +632,10 @@ export function renderPageStream(source, componentName, props = {}, registry = n
|
|
|
618
632
|
}
|
|
619
633
|
let streamHeadHtml = null;
|
|
620
634
|
if (targetComp) {
|
|
621
|
-
let headHtml =
|
|
635
|
+
let headHtml = [
|
|
636
|
+
renderStaticMetadataHtml(metadataSource),
|
|
637
|
+
renderHeadHtml(targetComp, ssrProps, scopedVesk(renderFn, __vesk)),
|
|
638
|
+
].filter(Boolean).join('\n');
|
|
622
639
|
if (options.pageHead) {
|
|
623
640
|
const merged = mergeHeadHtml(options.pageHead, headHtml);
|
|
624
641
|
headHtml = merged.html;
|
|
@@ -675,7 +692,7 @@ export function renderPageStream(source, componentName, props = {}, registry = n
|
|
|
675
692
|
// Mirror renderFullPage: a full document must carry the client bundle or
|
|
676
693
|
// the page can never hydrate (dev-server streams hit this path).
|
|
677
694
|
const clientScript = options.clientScriptUrl
|
|
678
|
-
? `\t<script type="module" src="${options.clientScriptUrl}"></script>\n`
|
|
695
|
+
? `\t<script type="module" src="${options.clientScriptUrl}"${options.clientScriptIntegrity ? ` integrity="${options.clientScriptIntegrity}" crossorigin="anonymous"` : ''}></script>\n`
|
|
679
696
|
: '';
|
|
680
697
|
yield `\n</div>${dataScriptBlock}${clientScript}</body>\n</html>\n`;
|
|
681
698
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,11 +4,23 @@ export interface CompileFileResult {
|
|
|
4
4
|
ir: IRRoot;
|
|
5
5
|
componentMap: Map<string, Function>;
|
|
6
6
|
__vesk: Record<string, unknown>;
|
|
7
|
+
/**
|
|
8
|
+
* Source of a static `export const metadata`, hoisted from the IR so a
|
|
9
|
+
* precompiled (source-less) render can still serialize the head.
|
|
10
|
+
*/
|
|
11
|
+
metadataSource?: string | null;
|
|
7
12
|
}
|
|
8
13
|
export interface FullPageOptions {
|
|
9
14
|
cssUrl?: string;
|
|
10
15
|
cssUrls?: string[];
|
|
11
16
|
clientScriptUrl?: string;
|
|
17
|
+
/**
|
|
18
|
+
* SRI digest for `clientScriptUrl` (`sha384-<base64>`). A production build
|
|
19
|
+
* passes the digest of the exact bundle it emitted, so the tag cannot execute
|
|
20
|
+
* anything but the built bytes. Omitted in dev, where the URL is rewritten on
|
|
21
|
+
* every edit and a digest would block it.
|
|
22
|
+
*/
|
|
23
|
+
clientScriptIntegrity?: string;
|
|
12
24
|
pageHead?: string;
|
|
13
25
|
security?: import('@vesk/types').VeskSecurity;
|
|
14
26
|
__vesk?: Record<string, unknown>;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAIpD,YAAY,EACV,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,QAAQ,EACR,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,UAAU,EACV,OAAO,EACP,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,SAAS,EACT,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,OAAO,EACP,QAAQ,EACR,eAAe,EACf,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAIpD,YAAY,EACV,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,QAAQ,EACR,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,UAAU,EACV,OAAO,EACP,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,SAAS,EACT,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,OAAO,EACP,QAAQ,EACR,eAAe,EACf,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,aAAa,EAAE,YAAY,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,OAAO,aAAa,EAAE,kBAAkB,CAAC;IAC9D,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,aAAa,EAAE,UAAU,EAAE,CAAC;IAC7C;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,shBAahB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.50-canary.10",
|
|
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.50-canary.10",
|
|
24
24
|
"acorn": "^8.15.0",
|
|
25
25
|
"esrap": "^2.3.0",
|
|
26
26
|
"is-reference": "^3.0.0",
|