Pre Release New Changes

This commit is contained in:
2026-07-31 16:30:13 +05:30
parent 358a520bc5
commit 3e565e8d03
189 changed files with 36727 additions and 17249 deletions
+120 -6
View File
@@ -41,6 +41,8 @@ export interface RenderOptions {
defaultTitle?: string;
/** Raw HTML injected at the end of `<head>` (trusted, framework-controlled). */
extraHead?: string;
/** CSP nonce applied to framework-promoted `.wrn` style blocks. */
styleNonce?: string;
/** Raw HTML injected at the end of `<body>` (trusted, framework-controlled). */
extraBody?: string;
/** Attributes for the `<html>` element, e.g. ` data-theme="dark"` (trusted). */
@@ -64,6 +66,11 @@ export function renderDocument(opts: RenderOptions): string {
const title = escapeHtml(seo.title);
const scripts = normalizeScripts(opts.scripts ?? []);
const sourceDocument = opts.documentTemplate?.trim();
const extracted = extractWrnexusStyles(sourceDocument ?? opts.body, opts.styleNonce);
const renderedBody = sourceDocument ? opts.body : extracted.html;
const renderedDocument = sourceDocument ? extracted.html : undefined;
const seoTags = renderSeoTags(seo);
const preloadTags = scripts
.filter((script) => (script.type ?? "module") === "module")
@@ -71,15 +78,16 @@ export function renderDocument(opts: RenderOptions): string {
.join("");
const scriptTags = scripts.map((script) => `\n ${renderScriptTag(script)}`).join("");
const extraHead = opts.extraHead ? `\n ${opts.extraHead}` : "";
const globalHead = opts.extraHead ? `\n ${opts.extraHead}` : "";
const localStyles = extracted.styles ? `\n ${extracted.styles}` : "";
const extraBody = opts.extraBody ? `\n ${opts.extraBody}` : "";
const htmlAttrs = /(?:^|\s)lang\s*=/.test(opts.htmlAttrs ?? "")
? (opts.htmlAttrs ?? "")
: `${opts.htmlAttrs ?? ""} lang="en"`;
if (opts.documentTemplate) {
let document = opts.documentTemplate.trim();
if (renderedDocument) {
let document = renderedDocument;
if (!/^<!doctype\s+html>/i.test(document)) document = `<!doctype html>\n${document}`;
document = document.replace(/<html([^>]*)>/i, (_match, existing: string) => {
const language = /(?:^|\s)lang\s*=/.test(`${existing}${opts.htmlAttrs ?? ""}`)
@@ -91,8 +99,9 @@ export function renderDocument(opts: RenderOptions): string {
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
<title>${title}</title>${seoTags}${preloadTags}${extraHead}`;
<title>${title}</title>${seoTags}${preloadTags}${globalHead}`;
document = document.replace(/<head([^>]*)>/i, `<head$1>${headContent}`);
document = appendBeforeClosingTag(document, "head", localStyles);
document = document.replace(/<\/body>/i, `${scriptTags}${extraBody}\n </body>`);
return `${document}\n`;
}
@@ -103,15 +112,120 @@ export function renderDocument(opts: RenderOptions): string {
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
<title>${title}</title>${seoTags}${preloadTags}${extraHead}
<title>${title}</title>${seoTags}${preloadTags}${globalHead}${localStyles}
</head>
<body>
<div id="app">${opts.body}</div>${scriptTags}${extraBody}
<div id="app">${renderedBody}</div>${scriptTags}${extraBody}
</body>
</html>
`;
}
interface ExtractedStyle {
id: string;
owner: string;
kind: "layout" | "page" | "component";
css: string;
order: number;
}
interface ExtractedWrnexusStyles {
html: string;
styles: string;
}
const WRNEXUS_STYLE_RE = /<style\b([^>]*)>([\s\S]*?)<\/style\s*>/gi;
function appendBeforeClosingTag(document: string, tag: string, html: string): string {
if (!html) return document;
const closing = new RegExp(`</${tag}\\s*>`, "i");
return closing.test(document)
? document.replace(closing, `${html}\n </${tag}>`)
: `${document}${html}`;
}
function readHtmlAttribute(attributes: string, name: string): string | undefined {
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const match = attributes.match(
new RegExp(`(?:^|\\s)${escaped}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))`, "i"),
);
return match?.[1] ?? match?.[2] ?? match?.[3];
}
function stableStyleHash(value: string): string {
let hash = 0x811c9dc5;
for (let index = 0; index < value.length; index++) {
hash ^= value.charCodeAt(index);
hash = Math.imul(hash, 0x01000193);
}
return (hash >>> 0).toString(36);
}
function normalizeStyleKind(value: string | undefined): ExtractedStyle["kind"] {
return value === "layout" || value === "page" ? value : "component";
}
function styleKindOrder(kind: ExtractedStyle["kind"]): number {
return kind === "layout" ? 0 : kind === "page" ? 1 : 2;
}
function escapeStyleAttribute(value: string): string {
return escapeHtml(value);
}
/**
* Promote compiler-emitted `.wrn` style blocks out of rendered markup and into
* the document head. They are emitted after global stylesheets, deduplicated by
* stable id, ordered layout -> page -> component, and nonce-tagged for CSP.
*/
export function extractWrnexusStyles(html: string, nonce?: string): ExtractedWrnexusStyles {
const found: ExtractedStyle[] = [];
let sourceOrder = 0;
const cleaned = html.replace(
WRNEXUS_STYLE_RE,
(whole: string, attributes: string, css: string) => {
const legacyOwner = readHtmlAttribute(attributes, "data-wrnexus-style");
const explicitId = readHtmlAttribute(attributes, "data-wrnexus-style-id");
if (!legacyOwner && !explicitId) return whole;
const owner =
readHtmlAttribute(attributes, "data-wrnexus-style-owner") ?? legacyOwner ?? "anonymous";
const kind = normalizeStyleKind(readHtmlAttribute(attributes, "data-wrnexus-style-kind"));
const id = explicitId ?? `wrn-${kind}-${stableStyleHash(`${kind}:${owner}`)}`;
found.push({ id, owner, kind, css: css.trim(), order: sourceOrder++ });
return "";
},
);
const byId = new Map<string, ExtractedStyle>();
for (const style of found) {
const current = byId.get(style.id);
if (!current) {
byId.set(style.id, style);
continue;
}
// Repeated mounts of one component carry identical CSS. Keep the latest
// body only when it differs while preserving the original cascade position.
if (current.css !== style.css) byId.set(style.id, { ...style, order: current.order });
}
const nonceAttribute = nonce ? ` nonce="${escapeStyleAttribute(nonce)}"` : "";
const styles = [...byId.values()]
.sort((left, right) => {
const kind = styleKindOrder(left.kind) - styleKindOrder(right.kind);
return kind || left.order - right.order;
})
.map(
(style) =>
`<style data-wrnexus-style-id="${escapeStyleAttribute(style.id)}" data-wrnexus-style-owner="${escapeStyleAttribute(style.owner)}" data-wrnexus-style-kind="${style.kind}"${nonceAttribute}>\n${style.css.replace(/<\/style/gi, "<\\/style")}\n</style>`,
)
.join("\n ");
return { html: cleaned, styles };
}
function normalizeScripts(scripts: readonly RenderScript[]): ScriptAsset[] {
const bySrc = new Map<string, ScriptAsset>();
for (const script of scripts) {