release: WRNexusJS 0.5.10
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user