@vesk/vesk-cli 0.2.50-canary.4 → 0.2.50-canary.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +269 -20
- package/package.json +5 -5
package/dist/cli.js
CHANGED
|
@@ -399,6 +399,13 @@ var init_ir = __esm({
|
|
|
399
399
|
importedNames;
|
|
400
400
|
staticProps;
|
|
401
401
|
loadFn;
|
|
402
|
+
/**
|
|
403
|
+
* Source of `export const metadata = defineMetadata({...})`, when present.
|
|
404
|
+
* Static by construction: evaluated with only `defineMetadata` in scope, at
|
|
405
|
+
* build time where possible and in a sealed sandbox at request time
|
|
406
|
+
* otherwise, so the head never depends on the component's frame.
|
|
407
|
+
*/
|
|
408
|
+
metadataSource;
|
|
402
409
|
topLevelCode;
|
|
403
410
|
/**
|
|
404
411
|
* Same-file specifier exports (`export { A }`, `export { A as B }`) as
|
|
@@ -1966,8 +1973,16 @@ function writeCache(key, data2) {
|
|
|
1966
1973
|
const entry = getClientCache().get(key);
|
|
1967
1974
|
if (!entry || entry.data !== data2) getClientCache().set(key, { data: data2, fetchedAt: Date.now() });
|
|
1968
1975
|
}
|
|
1969
|
-
function trackSsrPromise(promise) {
|
|
1976
|
+
function trackSsrPromise(promise, defer = false) {
|
|
1970
1977
|
const tk = g().__vsk_ssr_token || "";
|
|
1978
|
+
if (defer) {
|
|
1979
|
+
const deferredKey = tk ? `__vsk_ssr_deferred_${tk}` : "__vsk_ssr_deferred";
|
|
1980
|
+
if (!g()[deferredKey]) g()[deferredKey] = [];
|
|
1981
|
+
g()[deferredKey].push(promise);
|
|
1982
|
+
promise.then(void 0, () => {
|
|
1983
|
+
});
|
|
1984
|
+
return;
|
|
1985
|
+
}
|
|
1971
1986
|
const promisesKey = tk ? `__vsk_ssr_promises_${tk}` : "__vsk_ssr_promises";
|
|
1972
1987
|
if (!g()[promisesKey]) g()[promisesKey] = [];
|
|
1973
1988
|
g()[promisesKey].push(promise);
|
|
@@ -2034,7 +2049,7 @@ function startRequest(handle2, skipCache) {
|
|
|
2034
2049
|
} else {
|
|
2035
2050
|
attachSettle(handle2, prom2);
|
|
2036
2051
|
}
|
|
2037
|
-
trackSsrPromise(prom2);
|
|
2052
|
+
trackSsrPromise(prom2, options.ssr === "defer");
|
|
2038
2053
|
return prom2;
|
|
2039
2054
|
}
|
|
2040
2055
|
if (!skipCache && options.staleTime && options.staleTime > 0) {
|
|
@@ -21292,6 +21307,7 @@ function generateIR(ast, source, filename) {
|
|
|
21292
21307
|
const importedNames = /* @__PURE__ */ new Set();
|
|
21293
21308
|
let staticProps = null;
|
|
21294
21309
|
let loadFn = null;
|
|
21310
|
+
let metadataSource = null;
|
|
21295
21311
|
const topLevelCode = [];
|
|
21296
21312
|
const exportAliases = [];
|
|
21297
21313
|
const reexportSources = [];
|
|
@@ -21327,6 +21343,14 @@ function generateIR(ast, source, filename) {
|
|
|
21327
21343
|
continue;
|
|
21328
21344
|
}
|
|
21329
21345
|
}
|
|
21346
|
+
if (node.type === "ExportNamedDeclaration" && node.declaration && !metadataSource) {
|
|
21347
|
+
const decl = node.declaration;
|
|
21348
|
+
const first = decl.type === "VariableDeclaration" ? decl.declarations[0] : null;
|
|
21349
|
+
if (first?.id?.name === "metadata") {
|
|
21350
|
+
metadataSource = first.init ? stripCodeTypes(getSource(source, first.init)) : null;
|
|
21351
|
+
continue;
|
|
21352
|
+
}
|
|
21353
|
+
}
|
|
21330
21354
|
if (node.type === "ExportNamedDeclaration" && node.declaration && !loadFn) {
|
|
21331
21355
|
const decl = node.declaration;
|
|
21332
21356
|
const fnName = decl.type === "FunctionDeclaration" ? decl.id?.name : decl.type === "VariableDeclaration" ? decl.declarations[0]?.id?.name : null;
|
|
@@ -21543,7 +21567,9 @@ function generateIR(ast, source, filename) {
|
|
|
21543
21567
|
imports.push(`import { ${missing.join(", ")} } from '@vesk/runtime';`);
|
|
21544
21568
|
}
|
|
21545
21569
|
}
|
|
21546
|
-
|
|
21570
|
+
const irRoot = new IRRoot(components, imports, importedNames, staticProps, loadFn, topLevelCode, exportAliases, reexportSources);
|
|
21571
|
+
irRoot.metadataSource = metadataSource;
|
|
21572
|
+
return irRoot;
|
|
21547
21573
|
} finally {
|
|
21548
21574
|
currentVskNamespaceLocals = prevNamespaceLocals;
|
|
21549
21575
|
currentSourceFile = prevSourceFile;
|
|
@@ -22836,18 +22862,20 @@ function webhook(options) {
|
|
|
22836
22862
|
secret,
|
|
22837
22863
|
handler,
|
|
22838
22864
|
headerName = "x-webhook-signature",
|
|
22839
|
-
signaturePrefix = "sha256="
|
|
22865
|
+
signaturePrefix = "sha256=",
|
|
22866
|
+
algorithm = "SHA-256",
|
|
22867
|
+
signedPayload
|
|
22840
22868
|
} = options;
|
|
22841
22869
|
if (!secret) throw new Error("webhook() requires a secret");
|
|
22842
22870
|
if (!handler) throw new Error("webhook() requires a handler function");
|
|
22843
|
-
async function computeSignature(
|
|
22871
|
+
async function computeSignature(payload) {
|
|
22844
22872
|
const key = typeof secret === "string" ? new TextEncoder().encode(secret) : secret;
|
|
22845
|
-
const data2 =
|
|
22873
|
+
const data2 = new TextEncoder().encode(payload);
|
|
22846
22874
|
const crypto2 = globalThis.crypto;
|
|
22847
22875
|
if (!crypto2?.subtle) {
|
|
22848
22876
|
throw new Error("Web Crypto API not available (required for webhook signature verification)");
|
|
22849
22877
|
}
|
|
22850
|
-
return crypto2.subtle.importKey("raw", key, { name: "HMAC", hash:
|
|
22878
|
+
return crypto2.subtle.importKey("raw", key, { name: "HMAC", hash: algorithm }, false, ["sign"]).then((k) => crypto2.subtle.sign("HMAC", k, data2)).then((sig) => {
|
|
22851
22879
|
const hex = Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
22852
22880
|
return hex;
|
|
22853
22881
|
});
|
|
@@ -22867,7 +22895,25 @@ function webhook(options) {
|
|
|
22867
22895
|
});
|
|
22868
22896
|
}
|
|
22869
22897
|
const body = await request.text();
|
|
22870
|
-
|
|
22898
|
+
let parsed;
|
|
22899
|
+
try {
|
|
22900
|
+
parsed = JSON.parse(body);
|
|
22901
|
+
} catch {
|
|
22902
|
+
parsed = body;
|
|
22903
|
+
}
|
|
22904
|
+
const event = parsed;
|
|
22905
|
+
let payload = body;
|
|
22906
|
+
if (signedPayload) {
|
|
22907
|
+
try {
|
|
22908
|
+
payload = signedPayload(event);
|
|
22909
|
+
} catch {
|
|
22910
|
+
return new Response(JSON.stringify({ error: "Invalid signature" }), {
|
|
22911
|
+
status: 401,
|
|
22912
|
+
headers: { "Content-Type": "application/json" }
|
|
22913
|
+
});
|
|
22914
|
+
}
|
|
22915
|
+
}
|
|
22916
|
+
const expectedSig = await computeSignature(payload);
|
|
22871
22917
|
const prefixLen = signaturePrefix.length;
|
|
22872
22918
|
const providedSig = signature.startsWith(signaturePrefix) ? signature.slice(prefixLen) : signature;
|
|
22873
22919
|
if (providedSig.length !== expectedSig.length) {
|
|
@@ -22886,12 +22932,6 @@ function webhook(options) {
|
|
|
22886
22932
|
headers: { "Content-Type": "application/json" }
|
|
22887
22933
|
});
|
|
22888
22934
|
}
|
|
22889
|
-
let event;
|
|
22890
|
-
try {
|
|
22891
|
-
event = JSON.parse(body);
|
|
22892
|
-
} catch {
|
|
22893
|
-
event = body;
|
|
22894
|
-
}
|
|
22895
22935
|
return handler(event, request);
|
|
22896
22936
|
}
|
|
22897
22937
|
return webhookHandler;
|
|
@@ -26614,6 +26654,177 @@ var init_action = __esm({
|
|
|
26614
26654
|
}
|
|
26615
26655
|
});
|
|
26616
26656
|
|
|
26657
|
+
// ../runtime/src/metadata.ts
|
|
26658
|
+
function assertPlainObject(value, where) {
|
|
26659
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
26660
|
+
throw new Error(`defineMetadata: ${where} must be a plain object, got ${Array.isArray(value) ? "an array" : typeof value}`);
|
|
26661
|
+
}
|
|
26662
|
+
return value;
|
|
26663
|
+
}
|
|
26664
|
+
function defineMetadata(input) {
|
|
26665
|
+
const meta = assertPlainObject(input, "the argument");
|
|
26666
|
+
if ("title" in meta && meta.title !== void 0) {
|
|
26667
|
+
if (typeof meta.title !== "string" && typeof meta.title !== "object") {
|
|
26668
|
+
throw new Error("defineMetadata: `title` must be a string or { default, template }");
|
|
26669
|
+
}
|
|
26670
|
+
if (typeof meta.title === "object") {
|
|
26671
|
+
const t = assertPlainObject(meta.title, "`title`");
|
|
26672
|
+
for (const key of Object.keys(t)) {
|
|
26673
|
+
if (key !== "default" && key !== "template" && key !== "absolute") {
|
|
26674
|
+
throw new Error(`defineMetadata: unknown \`title.${key}\` (expected default, template or absolute)`);
|
|
26675
|
+
}
|
|
26676
|
+
}
|
|
26677
|
+
}
|
|
26678
|
+
}
|
|
26679
|
+
if ("description" in meta && meta.description !== void 0 && typeof meta.description !== "string") {
|
|
26680
|
+
throw new Error("defineMetadata: `description` must be a string");
|
|
26681
|
+
}
|
|
26682
|
+
for (const key of ["openGraph", "twitter"]) {
|
|
26683
|
+
if (key in meta && meta[key] !== void 0) assertPlainObject(meta[key], `\`${key}\``);
|
|
26684
|
+
}
|
|
26685
|
+
if ("alternates" in meta && meta.alternates !== void 0) {
|
|
26686
|
+
const alt = assertPlainObject(meta.alternates, "`alternates`");
|
|
26687
|
+
for (const key of Object.keys(alt)) {
|
|
26688
|
+
if (key !== "canonical" && key !== "languages") {
|
|
26689
|
+
throw new Error(`defineMetadata: unknown \`alternates.${key}\` (expected canonical or languages)`);
|
|
26690
|
+
}
|
|
26691
|
+
}
|
|
26692
|
+
}
|
|
26693
|
+
for (const key of Object.keys(meta)) {
|
|
26694
|
+
if (!KNOWN_KEYS.has(key)) {
|
|
26695
|
+
throw new Error(
|
|
26696
|
+
`defineMetadata: unknown key "${key}". Known keys: ${[...KNOWN_KEYS].join(", ")}. (\`openGraph\` carries og:* tags, not top-level \`ogTitle\`.)`
|
|
26697
|
+
);
|
|
26698
|
+
}
|
|
26699
|
+
}
|
|
26700
|
+
return meta;
|
|
26701
|
+
}
|
|
26702
|
+
function resolveTitle(meta, child) {
|
|
26703
|
+
if (!meta || meta.title === void 0 || meta.title === null) return null;
|
|
26704
|
+
if (typeof meta.title === "string") return meta.title;
|
|
26705
|
+
if (meta.title.absolute) return meta.title.absolute;
|
|
26706
|
+
if (meta.title.default) return meta.title.default;
|
|
26707
|
+
if (meta.title.template && child) {
|
|
26708
|
+
const childTitle = resolveTitle(child);
|
|
26709
|
+
return childTitle === null ? null : meta.title.template.replace("%s", childTitle);
|
|
26710
|
+
}
|
|
26711
|
+
return null;
|
|
26712
|
+
}
|
|
26713
|
+
function mergeMetadata(...sources) {
|
|
26714
|
+
const out = {};
|
|
26715
|
+
let template;
|
|
26716
|
+
let sawTemplate = false;
|
|
26717
|
+
for (const source of sources) {
|
|
26718
|
+
if (!source) continue;
|
|
26719
|
+
for (const [key, value] of Object.entries(source)) {
|
|
26720
|
+
if (value === void 0) continue;
|
|
26721
|
+
if (key === "openGraph" || key === "twitter") {
|
|
26722
|
+
out[key] = { ...out[key] || {}, ...value };
|
|
26723
|
+
continue;
|
|
26724
|
+
}
|
|
26725
|
+
if (key === "title") {
|
|
26726
|
+
if (value && typeof value === "object" && value.template) {
|
|
26727
|
+
sawTemplate = true;
|
|
26728
|
+
template = value.template || template;
|
|
26729
|
+
}
|
|
26730
|
+
out.title = value;
|
|
26731
|
+
continue;
|
|
26732
|
+
}
|
|
26733
|
+
out[key] = value;
|
|
26734
|
+
}
|
|
26735
|
+
}
|
|
26736
|
+
if (sawTemplate && out.title !== void 0) {
|
|
26737
|
+
const own = out.title;
|
|
26738
|
+
if (typeof own === "string") out.title = { absolute: own };
|
|
26739
|
+
else if (own && typeof own === "object" && own.template) {
|
|
26740
|
+
out.title = { default: own.default, template: own.template || template };
|
|
26741
|
+
} else if (own && typeof own === "object") {
|
|
26742
|
+
out.title = { ...own, template };
|
|
26743
|
+
}
|
|
26744
|
+
}
|
|
26745
|
+
return out;
|
|
26746
|
+
}
|
|
26747
|
+
function escapeAttr2(value) {
|
|
26748
|
+
return String(value).split("&").join("&").split("<").join("<").split(">").join(">").split('"').join(""");
|
|
26749
|
+
}
|
|
26750
|
+
function escapeText(value) {
|
|
26751
|
+
return String(value).split("&").join("&").split("<").join("<").split(">").join(">");
|
|
26752
|
+
}
|
|
26753
|
+
function metadataToHtml(meta, opts = {}) {
|
|
26754
|
+
if (!meta) return "";
|
|
26755
|
+
const lines = [];
|
|
26756
|
+
const title = resolveTitle(meta, opts.child);
|
|
26757
|
+
if (title !== null) lines.push(`<title data-vesk-head>${escapeText(title)}</title>`);
|
|
26758
|
+
if (typeof meta.description === "string" && meta.description.length > 0) {
|
|
26759
|
+
lines.push(`<meta name="description" content="${escapeAttr2(meta.description)}" data-vesk-head />`);
|
|
26760
|
+
}
|
|
26761
|
+
if (meta.robots) {
|
|
26762
|
+
const content = typeof meta.robots === "string" ? meta.robots : Object.entries(meta.robots).filter(([, on]) => on).map(([k]) => k).join(", ");
|
|
26763
|
+
if (content) lines.push(`<meta name="robots" content="${escapeAttr2(content)}" data-vesk-head />`);
|
|
26764
|
+
}
|
|
26765
|
+
if (meta.themeColor) {
|
|
26766
|
+
lines.push(`<meta name="theme-color" content="${escapeAttr2(meta.themeColor)}" data-vesk-head />`);
|
|
26767
|
+
}
|
|
26768
|
+
const og = meta.openGraph;
|
|
26769
|
+
if (og) {
|
|
26770
|
+
const ogTitle = resolveTitle(og) ?? title;
|
|
26771
|
+
const ogFields = [
|
|
26772
|
+
["og:title", ogTitle],
|
|
26773
|
+
["og:description", og.description ?? meta.description],
|
|
26774
|
+
["og:url", og.url],
|
|
26775
|
+
["og:site_name", og.siteName],
|
|
26776
|
+
["og:image", og.image],
|
|
26777
|
+
["og:type", og.type]
|
|
26778
|
+
];
|
|
26779
|
+
for (const [prop, value] of ogFields) {
|
|
26780
|
+
if (value === void 0 || value === null || value === "") continue;
|
|
26781
|
+
lines.push(`<meta property="${prop}" content="${escapeAttr2(value)}" data-vesk-head />`);
|
|
26782
|
+
}
|
|
26783
|
+
}
|
|
26784
|
+
const tw = meta.twitter;
|
|
26785
|
+
if (tw) {
|
|
26786
|
+
const twFields = [
|
|
26787
|
+
["twitter:card", tw.card],
|
|
26788
|
+
["twitter:site", tw.site],
|
|
26789
|
+
["twitter:title", resolveTitle(tw) ?? title],
|
|
26790
|
+
["twitter:description", tw.description ?? meta.description],
|
|
26791
|
+
["twitter:image", tw.image]
|
|
26792
|
+
];
|
|
26793
|
+
for (const [name, value] of twFields) {
|
|
26794
|
+
if (value === void 0 || value === null || value === "") continue;
|
|
26795
|
+
lines.push(`<meta name="${name}" content="${escapeAttr2(value)}" data-vesk-head />`);
|
|
26796
|
+
}
|
|
26797
|
+
}
|
|
26798
|
+
const alt = meta.alternates;
|
|
26799
|
+
if (alt) {
|
|
26800
|
+
if (typeof alt === "object" && typeof alt.canonical === "string") {
|
|
26801
|
+
lines.push(`<link rel="canonical" href="${escapeAttr2(alt.canonical)}" data-vesk-head />`);
|
|
26802
|
+
}
|
|
26803
|
+
const languages = alt.languages;
|
|
26804
|
+
if (languages && typeof languages === "object") {
|
|
26805
|
+
for (const [lang, href] of Object.entries(languages)) {
|
|
26806
|
+
lines.push(`<link rel="alternate" hreflang="${escapeAttr2(lang)}" href="${escapeAttr2(href)}" data-vesk-head />`);
|
|
26807
|
+
}
|
|
26808
|
+
}
|
|
26809
|
+
}
|
|
26810
|
+
return lines.join("\n");
|
|
26811
|
+
}
|
|
26812
|
+
var KNOWN_KEYS;
|
|
26813
|
+
var init_metadata = __esm({
|
|
26814
|
+
"../runtime/src/metadata.ts"() {
|
|
26815
|
+
"use strict";
|
|
26816
|
+
KNOWN_KEYS = /* @__PURE__ */ new Set([
|
|
26817
|
+
"title",
|
|
26818
|
+
"description",
|
|
26819
|
+
"robots",
|
|
26820
|
+
"openGraph",
|
|
26821
|
+
"twitter",
|
|
26822
|
+
"alternates",
|
|
26823
|
+
"themeColor"
|
|
26824
|
+
]);
|
|
26825
|
+
}
|
|
26826
|
+
});
|
|
26827
|
+
|
|
26617
26828
|
// ../runtime/src/index-server.ts
|
|
26618
26829
|
var index_server_exports = {};
|
|
26619
26830
|
__export(index_server_exports, {
|
|
@@ -26675,6 +26886,7 @@ __export(index_server_exports, {
|
|
|
26675
26886
|
custom: () => custom,
|
|
26676
26887
|
defineAction: () => defineAction,
|
|
26677
26888
|
defineHook: () => defineHook,
|
|
26889
|
+
defineMetadata: () => defineMetadata,
|
|
26678
26890
|
defineRoute: () => defineRoute,
|
|
26679
26891
|
derived: () => derived,
|
|
26680
26892
|
destroy_block: () => destroy_block,
|
|
@@ -26702,6 +26914,8 @@ __export(index_server_exports, {
|
|
|
26702
26914
|
leaf: () => leaf,
|
|
26703
26915
|
locals: () => locals,
|
|
26704
26916
|
maxLength: () => maxLength,
|
|
26917
|
+
mergeMetadata: () => mergeMetadata,
|
|
26918
|
+
metadataToHtml: () => metadataToHtml,
|
|
26705
26919
|
minLength: () => minLength,
|
|
26706
26920
|
mutate: () => mutate,
|
|
26707
26921
|
notFound: () => notFound,
|
|
@@ -26722,6 +26936,7 @@ __export(index_server_exports, {
|
|
|
26722
26936
|
required: () => required,
|
|
26723
26937
|
rerenderNode: () => rerenderNode,
|
|
26724
26938
|
resolveSsrResources: () => resolveSsrResources,
|
|
26939
|
+
resolveTitle: () => resolveTitle,
|
|
26725
26940
|
resume_block: () => resume_block,
|
|
26726
26941
|
revalidateComponent: () => revalidateComponent,
|
|
26727
26942
|
revalidatePath: () => revalidatePath,
|
|
@@ -26786,6 +27001,7 @@ var init_index_server = __esm({
|
|
|
26786
27001
|
init_primitive();
|
|
26787
27002
|
init_loading_indicator();
|
|
26788
27003
|
init_action();
|
|
27004
|
+
init_metadata();
|
|
26789
27005
|
}
|
|
26790
27006
|
});
|
|
26791
27007
|
|
|
@@ -31410,6 +31626,17 @@ function irNodeToHeadHtml(node, ctx2, reconcileable = false) {
|
|
|
31410
31626
|
}
|
|
31411
31627
|
return "";
|
|
31412
31628
|
}
|
|
31629
|
+
function renderStaticMetadataHtml(source) {
|
|
31630
|
+
if (!source) return "";
|
|
31631
|
+
try {
|
|
31632
|
+
const fn = new Function("defineMetadata", "return (" + source + ")");
|
|
31633
|
+
const meta = fn(defineMetadata);
|
|
31634
|
+
return metadataToHtml(meta);
|
|
31635
|
+
} catch (e) {
|
|
31636
|
+
console.error("vesk: static metadata could not be evaluated:", e instanceof Error ? e.message : e);
|
|
31637
|
+
return "";
|
|
31638
|
+
}
|
|
31639
|
+
}
|
|
31413
31640
|
function renderHeadHtml(comp, props = {}, scope2 = {}) {
|
|
31414
31641
|
const tracked2 = collectTrackedNames(comp.body);
|
|
31415
31642
|
const needed = headNeededNames(comp);
|
|
@@ -31577,6 +31804,7 @@ var init_server_head = __esm({
|
|
|
31577
31804
|
init_scan();
|
|
31578
31805
|
init_parser();
|
|
31579
31806
|
init_client_codegen();
|
|
31807
|
+
init_metadata();
|
|
31580
31808
|
headRuntimeShims = () => ({
|
|
31581
31809
|
track: (init) => headCell(init),
|
|
31582
31810
|
derived: (fn) => headCell(typeof fn === "function" ? fn() : fn),
|
|
@@ -32244,6 +32472,7 @@ function compileFile(source, options) {
|
|
|
32244
32472
|
const owners = new VskComponentOwners();
|
|
32245
32473
|
const result = compileFileInternal(source, options?.sourcePath, /* @__PURE__ */ new Set(), owners);
|
|
32246
32474
|
owners.report("SSR");
|
|
32475
|
+
result.metadataSource = result.ir.metadataSource || null;
|
|
32247
32476
|
return result;
|
|
32248
32477
|
}
|
|
32249
32478
|
function compileFileInternal(source, sourcePath2, seenImportFiles, owners) {
|
|
@@ -32346,6 +32575,7 @@ function renderPage(source, componentName, props = {}, registry = /* @__PURE__ *
|
|
|
32346
32575
|
if (!renderFn) throw new Error(`Component "${componentName}" not found in source`);
|
|
32347
32576
|
const fullRegistry = new Map([...registry, ...componentMap]);
|
|
32348
32577
|
const targetComp = ir.components.find((c) => c.name === componentName);
|
|
32578
|
+
const metadataSource = ir.metadataSource || null;
|
|
32349
32579
|
const doRender = (ssrProps) => {
|
|
32350
32580
|
globalThis.__vsk_ssr = true;
|
|
32351
32581
|
if (!globalThis.__vsk_ssr_token) globalThis.__vsk_ssr_token = Math.random().toString(36).slice(2);
|
|
@@ -32364,9 +32594,11 @@ function renderPage(source, componentName, props = {}, registry = /* @__PURE__ *
|
|
|
32364
32594
|
}
|
|
32365
32595
|
return {
|
|
32366
32596
|
body: bodyHtml2,
|
|
32367
|
-
//
|
|
32368
|
-
//
|
|
32369
|
-
|
|
32597
|
+
// A static `export const metadata` wins: it is evaluated in a sealed
|
|
32598
|
+
// sandbox, so it cannot depend on the component's frame resolving
|
|
32599
|
+
// (the failure mode that shipped an empty <title>). Whatever the
|
|
32600
|
+
// page's `<Head>` adds is appended, not lost.
|
|
32601
|
+
head: [renderStaticMetadataHtml(metadataSource), renderHeadHtml(targetComp, ssrProps, scopedVesk(renderFn, __vesk))].filter(Boolean).join("\n"),
|
|
32370
32602
|
props: ssrProps
|
|
32371
32603
|
};
|
|
32372
32604
|
})();
|
|
@@ -32377,7 +32609,10 @@ function renderPage(source, componentName, props = {}, registry = /* @__PURE__ *
|
|
|
32377
32609
|
} finally {
|
|
32378
32610
|
delete globalThis.__vsk_ssr;
|
|
32379
32611
|
}
|
|
32380
|
-
const headHtml =
|
|
32612
|
+
const headHtml = [
|
|
32613
|
+
renderStaticMetadataHtml(metadataSource),
|
|
32614
|
+
targetComp ? renderHeadHtml(targetComp, ssrProps, scopedVesk(renderFn, __vesk)) : ""
|
|
32615
|
+
].filter(Boolean).join("\n");
|
|
32381
32616
|
const pending = globalThis[`__vsk_ssr_promises_${renderToken}`];
|
|
32382
32617
|
if (pending && pending.length > 0) {
|
|
32383
32618
|
return (async () => {
|
|
@@ -32407,6 +32642,7 @@ function renderPage(source, componentName, props = {}, registry = /* @__PURE__ *
|
|
|
32407
32642
|
function clearSsrCells(token) {
|
|
32408
32643
|
if (!token) return;
|
|
32409
32644
|
delete globalThis[`__vsk_ssr_promises_${token}`];
|
|
32645
|
+
delete globalThis[`__vsk_ssr_deferred_${token}`];
|
|
32410
32646
|
delete globalThis[`__vsk_ssr_failures_${token}`];
|
|
32411
32647
|
dropSsrSlot(token);
|
|
32412
32648
|
const cells = globalThis.__vsk_ssr_cells;
|
|
@@ -32679,6 +32915,7 @@ function renderPageStream(source, componentName, props = {}, registry = /* @__PU
|
|
|
32679
32915
|
if (!renderFn) throw new Error(`Component "${componentName}" not found in source`);
|
|
32680
32916
|
resetVskState(!!options.hydrate, options.markerless !== false);
|
|
32681
32917
|
const targetComp = ir.components.find((c) => c.name === componentName);
|
|
32918
|
+
const metadataSource = cached?.metadataSource ?? ir.metadataSource ?? null;
|
|
32682
32919
|
const cssUrls = options.cssUrls || (options.cssUrl ? [options.cssUrl] : []);
|
|
32683
32920
|
const cssLink = cssUrls.map((u) => ` <link rel="stylesheet" href="${u}" />
|
|
32684
32921
|
`).join("");
|
|
@@ -32692,7 +32929,10 @@ function renderPageStream(source, componentName, props = {}, registry = /* @__PU
|
|
|
32692
32929
|
}
|
|
32693
32930
|
let streamHeadHtml = null;
|
|
32694
32931
|
if (targetComp) {
|
|
32695
|
-
let headHtml =
|
|
32932
|
+
let headHtml = [
|
|
32933
|
+
renderStaticMetadataHtml(metadataSource),
|
|
32934
|
+
renderHeadHtml(targetComp, ssrProps, scopedVesk(renderFn, __vesk))
|
|
32935
|
+
].filter(Boolean).join("\n");
|
|
32696
32936
|
if (options.pageHead) {
|
|
32697
32937
|
const merged = mergeHeadHtml(options.pageHead, headHtml);
|
|
32698
32938
|
headHtml = merged.html;
|
|
@@ -46657,6 +46897,7 @@ function precompileFileInternal(source, sourcePath2, seenImportFiles) {
|
|
|
46657
46897
|
setVskHydrate(false);
|
|
46658
46898
|
}
|
|
46659
46899
|
const topLevelCode = transformTopLevelForActions(ir.topLevelCode, "server");
|
|
46900
|
+
const metadataSource = ir.metadataSource || null;
|
|
46660
46901
|
const runtimeImports = ir.imports.slice();
|
|
46661
46902
|
const collector = { keysByAbs: /* @__PURE__ */ new Map(), modules: [] };
|
|
46662
46903
|
const bindings = sourcePath2 !== void 0 ? collectModuleBundle(ir.imports, dirname6(sourcePath2), collector) : [];
|
|
@@ -46684,7 +46925,10 @@ function precompileFileInternal(source, sourcePath2, seenImportFiles) {
|
|
|
46684
46925
|
modules: collector.modules,
|
|
46685
46926
|
bindings,
|
|
46686
46927
|
topLevelCode,
|
|
46687
|
-
subFiles
|
|
46928
|
+
subFiles,
|
|
46929
|
+
// A static `export const metadata` rides along so a serverless function can
|
|
46930
|
+
// serialize the head without the `.vsk` source being present at all.
|
|
46931
|
+
...metadataSource ? { metadataSource } : {}
|
|
46688
46932
|
};
|
|
46689
46933
|
}
|
|
46690
46934
|
|
|
@@ -62534,6 +62778,7 @@ __export(index_server_exports2, {
|
|
|
62534
62778
|
custom: () => custom,
|
|
62535
62779
|
defineAction: () => defineAction,
|
|
62536
62780
|
defineHook: () => defineHook,
|
|
62781
|
+
defineMetadata: () => defineMetadata,
|
|
62537
62782
|
defineRoute: () => defineRoute,
|
|
62538
62783
|
derived: () => derived,
|
|
62539
62784
|
destroy_block: () => destroy_block,
|
|
@@ -62561,6 +62806,8 @@ __export(index_server_exports2, {
|
|
|
62561
62806
|
leaf: () => leaf,
|
|
62562
62807
|
locals: () => locals,
|
|
62563
62808
|
maxLength: () => maxLength,
|
|
62809
|
+
mergeMetadata: () => mergeMetadata,
|
|
62810
|
+
metadataToHtml: () => metadataToHtml,
|
|
62564
62811
|
minLength: () => minLength,
|
|
62565
62812
|
mutate: () => mutate,
|
|
62566
62813
|
notFound: () => notFound,
|
|
@@ -62581,6 +62828,7 @@ __export(index_server_exports2, {
|
|
|
62581
62828
|
required: () => required,
|
|
62582
62829
|
rerenderNode: () => rerenderNode,
|
|
62583
62830
|
resolveSsrResources: () => resolveSsrResources,
|
|
62831
|
+
resolveTitle: () => resolveTitle,
|
|
62584
62832
|
resume_block: () => resume_block,
|
|
62585
62833
|
revalidateComponent: () => revalidateComponent,
|
|
62586
62834
|
revalidatePath: () => revalidatePath,
|
|
@@ -62642,6 +62890,7 @@ init_headless();
|
|
|
62642
62890
|
init_primitive();
|
|
62643
62891
|
init_loading_indicator();
|
|
62644
62892
|
init_action();
|
|
62893
|
+
init_metadata();
|
|
62645
62894
|
|
|
62646
62895
|
// src/index.ts
|
|
62647
62896
|
var __filename2 = fileURLToPath9(import.meta.url);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/vesk-cli",
|
|
3
|
-
"version": "0.2.50-canary.
|
|
3
|
+
"version": "0.2.50-canary.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vesk — compiler-first framework for the post-VDOM web. vesk dev, vesk build.",
|
|
6
6
|
"bin": {
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/cli.js",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@vesk/adapter": "^0.2.50-canary.
|
|
12
|
-
"@vesk/compiler": "^0.2.50-canary.
|
|
13
|
-
"@vesk/plugin-tailwind": "^0.2.50-canary.
|
|
14
|
-
"@vesk/runtime": "^0.2.50-canary.
|
|
11
|
+
"@vesk/adapter": "^0.2.50-canary.6",
|
|
12
|
+
"@vesk/compiler": "^0.2.50-canary.6",
|
|
13
|
+
"@vesk/plugin-tailwind": "^0.2.50-canary.6",
|
|
14
|
+
"@vesk/runtime": "^0.2.50-canary.6",
|
|
15
15
|
"esrap": "^2.3.0",
|
|
16
16
|
"typescript": "^5.8.0",
|
|
17
17
|
"ws": "^8.18.0",
|