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
+3 -1
View File
@@ -46,7 +46,9 @@ function jsResponse(code: string): Response {
return new Response(code, {
headers: {
"content-type": "text/javascript; charset=utf-8",
"cache-control": "no-cache",
"cache-control": "no-store, max-age=0",
pragma: "no-cache",
expires: "0",
},
});
}
+58
View File
@@ -607,6 +607,7 @@ export const HMR_CLIENT_JS = `
var from = document.getElementById("app");
var to = doc.getElementById("app");
syncWrnStyles(doc);
if (from && to) {
morph(from, to);
}
@@ -638,6 +639,62 @@ export const HMR_CLIENT_JS = `
);
}
function currentDocumentNonce() {
var node = document.querySelector("script[nonce],style[nonce]");
if (!node) return "";
return node.nonce || node.getAttribute("nonce") || "";
}
function syncWrnStyles(nextDocument) {
var current = Array.prototype.slice.call(
document.querySelectorAll("style[data-wrnexus-style-id]"),
);
var next = Array.prototype.slice.call(
nextDocument.querySelectorAll("style[data-wrnexus-style-id]"),
);
var currentById = Object.create(null);
var nextIds = Object.create(null);
var nonce = currentDocumentNonce();
current.forEach(function (style) {
var id = style.getAttribute("data-wrnexus-style-id");
if (id) currentById[id] = style;
});
next.forEach(function (nextStyle) {
var id = nextStyle.getAttribute("data-wrnexus-style-id");
if (!id) return;
nextIds[id] = true;
var currentStyle = currentById[id];
if (!currentStyle) {
currentStyle = document.createElement("style");
currentStyle.setAttribute("data-wrnexus-style-id", id);
}
["data-wrnexus-style-owner", "data-wrnexus-style-kind"].forEach(function (name) {
var value = nextStyle.getAttribute(name);
if (value == null) currentStyle.removeAttribute(name);
else currentStyle.setAttribute(name, value);
});
if (nonce) currentStyle.setAttribute("nonce", nonce);
if (currentStyle.textContent !== nextStyle.textContent) {
currentStyle.textContent = nextStyle.textContent;
}
// Appending an existing node moves it. This keeps every local style after
// global stylesheets and in the exact layout -> page -> component order
// produced by the incoming SSR document.
document.head.appendChild(currentStyle);
});
current.forEach(function (style) {
var id = style.getAttribute("data-wrnexus-style-id");
if (id && !nextIds[id]) style.remove();
});
}
// Minimal index-based DOM morph: preserve matching nodes (keeps state/focus),
// patch text and attributes, clone genuinely new nodes, drop removed ones.
// Preserve a hydrated subtree only while its server hydration signature and
@@ -1401,6 +1458,7 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
.join("\n") || undefined,
htmlAttrs,
documentTemplate,
styleNonce: (ctx.locals.cspNonce as string | undefined) ?? undefined,
});
// Conditional GET: hash the page CONTENT (`body`), not the assembled shell —
// the shell carries a per-request CSP nonce in dev, which would otherwise make
@@ -26,3 +26,11 @@ test("HMR preserves the active browser theme and accent", () => {
expect(HMR_CLIENT_JS).toContain('new CustomEvent("wrnexus:hmr-updated"');
});
test("HMR synchronizes local WRN styles with the current document nonce", () => {
expect(HMR_CLIENT_JS).toContain("style[data-wrnexus-style-id]");
expect(HMR_CLIENT_JS).toContain("function currentDocumentNonce()");
expect(HMR_CLIENT_JS).toContain('currentStyle.setAttribute("nonce", nonce)');
expect(HMR_CLIENT_JS).toContain("document.head.appendChild(currentStyle)");
expect(HMR_CLIENT_JS).toContain("syncWrnStyles(doc)");
});