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) {
+57
View File
@@ -88,3 +88,60 @@ test("renders rich script metadata and deduplicates by source", () => {
expect(html).toContain('data-wrnexus-runtime-src="captcha"');
expect(html).not.toContain('rel="modulepreload" href="/__wrnexus/assets/captcha.abc.js"');
});
test("promotes WRN style blocks into head after global CSS with CSP nonce", () => {
const html = renderDocument({
meta: { title: "Styled" },
extraHead: '<link rel="stylesheet" href="/global.css" />',
styleNonce: "nonce-123",
body:
'<style data-wrnexus-style="Card" data-wrnexus-style-id="card" data-wrnexus-style-kind="component">.shared{color:blue}</style>' +
'<style data-wrnexus-style="Page" data-wrnexus-style-id="page" data-wrnexus-style-kind="page">.shared{color:red}</style>' +
'<style data-wrnexus-style="Layout" data-wrnexus-style-id="layout" data-wrnexus-style-kind="layout">.shared{color:green}</style>' +
'<main class="shared">Styled</main>',
});
expect(html).not.toContain('<div id="app"><style');
expect(html).toContain('<main class="shared">Styled</main>');
expect(html.match(/data-wrnexus-style-id=/g)).toHaveLength(3);
expect(html.match(/nonce="nonce-123"/g)).toHaveLength(3);
const globalIndex = html.indexOf("/global.css");
const layoutIndex = html.indexOf('data-wrnexus-style-id="layout"');
const pageIndex = html.indexOf('data-wrnexus-style-id="page"');
const componentIndex = html.indexOf('data-wrnexus-style-id="card"');
expect(globalIndex).toBeLessThan(layoutIndex);
expect(layoutIndex).toBeLessThan(pageIndex);
expect(pageIndex).toBeLessThan(componentIndex);
});
test("deduplicates repeated component style blocks", () => {
const style =
'<style data-wrnexus-style="Card" data-wrnexus-style-id="card" data-wrnexus-style-kind="component">.card{display:grid}</style>';
const html = renderDocument({
meta: { title: "Repeated" },
body: `${style}<article>One</article>${style}<article>Two</article>`,
});
expect(html.match(/data-wrnexus-style-id="card"/g)).toHaveLength(1);
expect(html).toContain("<article>One</article><article>Two</article>");
});
test("places document-layout WRN styles at the end of head", () => {
const html = renderDocument({
meta: { title: "Document styles" },
styleNonce: "document-nonce",
body: "",
documentTemplate:
'<html><head><link rel="stylesheet" href="/document-global.css" /></head><body>' +
'<style data-wrnexus-style="Document" data-wrnexus-style-id="document-layout" data-wrnexus-style-kind="layout">.shell{display:block}</style>' +
'<div id="app" class="shell">Page</div></body></html>',
});
const globalIndex = html.indexOf("/document-global.css");
const styleIndex = html.indexOf('data-wrnexus-style-id="document-layout"');
const headEnd = html.indexOf("</head>");
expect(globalIndex).toBeLessThan(styleIndex);
expect(styleIndex).toBeLessThan(headEnd);
expect(html).not.toContain("<body><style");
});