release: WRNexusJS 0.2.75

This commit is contained in:
2026-07-21 12:30:46 +05:30
parent 2ca2d02b22
commit 69b6cd431f
100 changed files with 2313 additions and 116 deletions
+104 -3
View File
@@ -54,6 +54,14 @@ import {
} from "@wrnexus/i18n";
import { runMiddleware } from "./pipeline.ts";
import type { HmrHub } from "./hmr.ts";
import type { DevToolbarConfig } from "@wrnexus/dev-toolbar/types";
import {
createServerIssue,
handleDevToolbarRoute,
issueFromError,
type DevToolbarCollector,
} from "@wrnexus/dev-toolbar/server";
/** HTTP methods we recognize as API handler exports. */
const HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"] as const;
@@ -131,6 +139,32 @@ export interface RuntimeDeps {
* bus (use the Redis pub/sub driver). Enables realtime across multiple apps.
*/
realtimeBus?: RealtimeBus;
devToolbar?: {
config: DevToolbarConfig;
collector: DevToolbarCollector;
root: string;
};
}
const DEV_TOOLBAR_SCRIPT =
'<script type="module" src="/__wrnexus/dev-toolbar.js" data-wrnexus-dev-toolbar></script>';
function shouldEnableDevToolbar(mode: string, deps: RuntimeDeps): boolean {
return (
mode === "development" &&
deps.devToolbar !== undefined &&
deps.devToolbar.config.enabled !== false
);
}
function shouldReportNotFound(pathname: string): boolean {
return !(
pathname.startsWith("/__wrnexus/") ||
pathname.startsWith("/.well-known/") ||
pathname === "/favicon.ico" ||
pathname.endsWith(".map")
);
}
export const PWA_CLIENT = `if ("serviceWorker" in navigator) {
@@ -429,8 +463,12 @@ export const HMR_CLIENT_JS = `
};
ws.onmessage = function (e) {
var msg; try { msg = JSON.parse(e.data); } catch (_) { return; }
if (msg.type === "css") swapCss(msg.version);
else if (msg.type === "reload") requestSync();
if (msg.channel === "toolbar") {
window.dispatchEvent(new CustomEvent("wrnexus:toolbar-message", { detail: msg }));
} else if (msg.type === "css") {
swapCss(msg.version);
window.dispatchEvent(new CustomEvent("wrnexus:hmr", { detail: msg }));
} else if (msg.type === "reload") requestSync();
else if (msg.type === "html") applyHtml(msg.html);
else if (msg.type === "error") console.error("[wrnexus] HMR update failed:", msg.message);
};
@@ -479,6 +517,7 @@ export const HMR_CLIENT_JS = `
// their reactive scopes (and any browser-side API fetches) in place.
if (window.__wrnexusHydrateScopes) window.__wrnexusHydrateScopes(document);
if (window.__wrnexusHydrateCsrFetches) window.__wrnexusHydrateCsrFetches(document);
window.dispatchEvent(new CustomEvent("wrnexus:hmr", { detail: { type: "html" } }));
}
// Minimal index-based DOM morph: preserve matching nodes (keeps state/focus),
@@ -717,6 +756,17 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
return secure(new Response("Payload Too Large", { status: 413 }));
}
if (deps.devToolbar) {
const toolbarResponse = await handleDevToolbarRoute(req, {
mode,
root: deps.devToolbar.root,
collector: deps.devToolbar.collector,
editor: deps.devToolbar.config.editor,
allowOpenEditor: deps.devToolbar.config.openEditor !== false,
});
if (toolbarResponse) return secure(toolbarResponse);
}
// --- HMR socket (dev only): upgrade before anything else. ---
if (hmr && url.pathname === "/__wrnexus/hmr") {
if (!isWebSocketOriginAllowed(req, deps.security)) return secure(forbiddenOrigin());
@@ -795,6 +845,14 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
console.error(
`[wrnexus] unhandled request error (${app}) ${req.method} ${url.pathname}\n${detail}`,
);
deps.devToolbar?.collector.add(
issueFromError(err, {
ruleId: "server/request-error",
category: "server",
title: "Request processing failed",
pathname: url.pathname,
}),
);
const response = secure(renderError(err, mode));
// Gateway-managed production apps bind to loopback. Carry a bounded,
// encoded diagnostic to the parent gateway so centralized log collectors
@@ -1004,6 +1062,14 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
result += await renderComponents(rendered, translate, depth + 1);
} catch (err) {
console.error(`[wrnexus] component '${name}' failed to render`, err);
deps.devToolbar?.collector.add(
issueFromError(err, {
ruleId: "server/component-render-error",
category: "server",
title: `Component '${name}' failed to render`,
source: { file: component.file, component: name },
}),
);
result += body.slice(tagStart, end);
}
}
@@ -1018,6 +1084,20 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
);
const matched = router.matchPage(ctx.url.pathname);
if (!matched) {
if (deps.devToolbar && shouldReportNotFound(ctx.url.pathname)) {
deps.devToolbar.collector.add(
createServerIssue({
ruleId: "routing/not-found",
category: "routing",
severity: "warning",
title: "Route not found",
message: `No page route matched ${ctx.url.pathname}.`,
pathname: ctx.url.pathname,
recommendation:
"Verify the URL, page filename, dynamic route parameters, and route casing.",
}),
);
}
const response = renderNotFound();
if (!isMobileRequest) return response;
const headers = new Headers(response.headers);
@@ -1065,6 +1145,15 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
}
} catch (err) {
console.error(`[wrnexus] layout '${layoutName}' failed to render`, err);
deps.devToolbar?.collector.add(
issueFromError(err, {
ruleId: "server/layout-render-error",
category: "server",
title: `Layout '${layoutName}' failed to render`,
pathname: ctx.url.pathname,
source: { file: layout.file },
}),
);
}
}
@@ -1102,7 +1191,13 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
]
.filter(Boolean)
.join("\n "),
extraBody: hmr ? hmrClientTag((ctx.locals.cspNonce as string) ?? "") : undefined,
extraBody:
[
hmr ? hmrClientTag((ctx.locals.cspNonce as string) ?? "") : "",
shouldEnableDevToolbar(mode, deps) ? DEV_TOOLBAR_SCRIPT : "",
]
.filter(Boolean)
.join("\n") || undefined,
htmlAttrs,
});
// Conditional GET: hash the page CONTENT (`body`), not the assembled shell —
@@ -1121,6 +1216,12 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
"content-type": "text/html; charset=utf-8",
etag: tag,
"cache-control": "private, no-cache",
...(shouldEnableDevToolbar(mode, deps)
? {
"x-wrnexus-dev-toolbar": "enabled",
"x-wrnexus-route": matched.route.raw,
}
: {}),
},
});
}