release: WRNexusJS 0.5.10

This commit is contained in:
2026-07-30 13:36:29 +05:30
parent 8fc6f15402
commit d1b0c55b53
159 changed files with 7509 additions and 604 deletions
+20 -6
View File
@@ -133,6 +133,8 @@ export interface RuntimeDeps {
assetVersion?: string;
/** Package browser runtimes resolved by the plugin system. */
clientRuntimes?: ClientRuntimeDefinition[];
/** Page navigation strategy. `document` disables same-origin link interception. */
navigation?: { mode?: "client" | "document" };
/** Raw HTML appended to every page head (e.g. CDN framework links). */
head?: string;
/** Global SEO defaults. */
@@ -1140,9 +1142,9 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
selfClose === "/" ? { inner: "", end: openEnd } : readElementBody(body, tag!, openEnd);
i = end;
const normalizedName = name.toLowerCase();
const normalizedName = normalizeComponentName(name);
const component = router.components.find(
(candidate) => candidate.name.toLowerCase() === normalizedName,
(candidate) => normalizeComponentName(candidate.name) === normalizedName,
);
if (!component) {
console.warn(`[wrnexus] no component registered for '${name}'`);
@@ -1312,7 +1314,7 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
if (deps.i18n) body = translateHtml(body, ctx.t);
// Point 3: only ship the JS this page actually uses.
const scripts = collectScripts(body, deps.clientRuntimes).map((script) =>
const scripts = collectScripts(body, deps.clientRuntimes, deps.navigation).map((script) =>
versionRenderScript(script, deps.assetVersion),
);
if (pwaServiceWorkerEnabled)
@@ -1669,6 +1671,17 @@ export function resolveTProps(
return props;
}
/**
* Normalize component identifiers for registry lookup.
*
* WRN declarations use PascalCase (`PublicHeader`) while explicit
* `data-component` mounts commonly use kebab-case (`public-header`) or
* snake_case (`public_header`). All three forms identify the same component.
*/
export function normalizeComponentName(name: string): string {
return name.toLowerCase().replace(/[-_]/g, "");
}
/**
* Decide which framework scripts a rendered page needs. Components are already
* server-rendered into the HTML; the only script is the reactive runtime, and
@@ -1677,10 +1690,11 @@ export function resolveTProps(
export function collectScripts(
body: string,
clientRuntimes: readonly ClientRuntimeDefinition[] = [],
navigation: { mode?: "client" | "document" } = {},
): RenderScript[] {
// Client-side navigation is an app-wide progressive enhancement: it must load
// on every page (you navigate *from* any page), and degrades to full loads.
const scripts: RenderScript[] = ["/__wrnexus/nav.js"];
// Client navigation is optional. In document mode, links retain native browser
// behavior and each route receives a fresh server-rendered HTML document.
const scripts: RenderScript[] = navigation.mode === "document" ? [] : ["/__wrnexus/nav.js"];
if (/\bdata-scope=/.test(body) || /\bdata-wrnexus-csr=/.test(body)) {
scripts.push("/__wrnexus/reactive.js");
}