finish CSS delivery and generated type remediation
Quality / quality (ubuntu-latest) (push) Failing after 12m54s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-10 00:17:25 +05:30
parent 232d8e6734
commit bca9549f3a
11 changed files with 277 additions and 18 deletions
+11 -8
View File
@@ -566,14 +566,17 @@ export async function runBuild(appRoot: string): Promise<void> {
},
config.styles,
);
const combinedSource = `${frameworkStyles}\n${css}`;
// Theme tokens are request-selected and loaded separately. Keep only the
// shared UI primitives with application CSS so the full theme/accent
// matrix cannot leak back into the blocking stylesheet.
const combinedSource = `${uiStyles}\n${css}`;
const combinedInput = join(distDir, ".wrnexus-combined.css");
writeFileSync(combinedInput, combinedSource, "utf8");
const combinedCss = await bundleCss(combinedInput, "production");
rmSync(combinedInput, { force: true });
assetHash.update(combinedCss);
// One blocking CSS request in production: tokens → UI application CSS.
// The standalone framework.css remains available for apps without global CSS.
// One shared blocking request for UI + application CSS. The small active
// theme stylesheet is selected from the request cookie and loaded first.
writeFileSync(join(distDir, "styles.css"), combinedCss, "utf8");
hasStyles = true;
if (Buffer.byteLength(combinedCss, "utf8") <= INLINE_CSS_LIMIT_BYTES) {
@@ -655,8 +658,8 @@ applyAuthzManifestEarly([${authzSetupEntries}]);
const componentsLit = router.components
.map((c) => {
const v = `c${counter++}`;
imports.push(`import * as ${v} from ${JSON.stringify(importPathFor(c.file))};`);
return `{ name: ${JSON.stringify(c.name)}, mod: ${v} }`;
imports.push(`import { render as ${v} } from ${JSON.stringify(importPathFor(c.file))};`);
return `{ name: ${JSON.stringify(c.name)}, mod: { render: ${v} } }`;
})
.join(", ");
console.log(`✓ Components: ${router.components.length}`);
@@ -665,8 +668,8 @@ applyAuthzManifestEarly([${authzSetupEntries}]);
const layoutsLit = router.layouts
.map((l) => {
const v = `c${counter++}`;
imports.push(`import * as ${v} from ${JSON.stringify(importPathFor(l.file))};`);
return `{ name: ${JSON.stringify(l.name)}, mod: ${v} }`;
imports.push(`import { render as ${v} } from ${JSON.stringify(importPathFor(l.file))};`);
return `{ name: ${JSON.stringify(l.name)}, mod: { render: ${v} } }`;
})
.join(", ");
if (router.layouts.length) console.log(`✓ Layouts: ${router.layouts.length}`);
@@ -748,7 +751,7 @@ await createProductionServer(
realtime: ${config.realtime ? JSON.stringify(config.realtime) : "undefined"},
publicDir: join(import.meta.dir, "public"),
${hasStyles ? `stylesPath: join(import.meta.dir, "styles.css"),` : ""}
${hasStyles ? `stylesIncludeFramework: true,` : ""}
${hasStyles ? `stylesIncludeUi: true,` : ""}
${inlineStyles ? `inlineStyles: ${JSON.stringify(inlineStyles)},` : ""}
assetVersion: ${JSON.stringify(assetVersion)},
clientRuntimes: ${JSON.stringify(emittedPluginAssets.runtimes)},
+1 -2
View File
@@ -75,7 +75,7 @@ function writePluginArtifacts(root: string, contributions?: PluginContributions)
});
writeFileSync(
join(typeDir, "wrnexus.plugins.generated.d.ts"),
`// AUTO-GENERATED plugin type aggregation - do not edit.\n${references.join("\n")}\n`,
`// AUTO-GENERATED plugin type aggregation - do not edit.\n${references.length > 0 ? `${references.join("\n")}\n` : ""}`,
"utf8",
);
const docsDir = join(root, ".wrnexus", "documentation");
@@ -182,7 +182,6 @@ export function generateApplicationTypes(
.map((name) => join(root, name))
.find(existsSync);
const code = `// AUTO-GENERATED by \`wrnexus generate types\` - do not edit.
/* eslint-disable @typescript-eslint/no-empty-object-type */
declare namespace WRNexusGenerated {
type ApiContract<T> = T extends import("@wrnexus/core").DefinedEndpoint<infer I, infer O>
? { input: I; output: O }
@@ -0,0 +1,38 @@
import { afterAll, expect, test } from "bun:test";
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { runBuild } from "../src/build.ts";
const scratchRoot = join(import.meta.dir, ".tmp-css-delivery");
mkdirSync(scratchRoot, { recursive: true });
afterAll(() => rmSync(scratchRoot, { recursive: true, force: true }));
test("production ships active themes separately and retains one component style copy", async () => {
const root = mkdtempSync(join(scratchRoot, "app-"));
mkdirSync(join(root, "app", "pages"), { recursive: true });
mkdirSync(join(root, "app", "components"), { recursive: true });
mkdirSync(join(root, "app", "styles"), { recursive: true });
writeFileSync(join(root, "package.json"), JSON.stringify({ name: "css-delivery-fixture" }));
writeFileSync(
join(root, "wrnexus.config.ts"),
`export default { theme: { default: "dark", palette: "violet" }, styles: { entry: "app/styles/global.css" } };\n`,
);
writeFileSync(join(root, "app", "styles", "global.css"), ".app-shell{display:block}\n");
writeFileSync(
join(root, "app", "components", "Probe.wrn"),
`component Probe { style { .unique-server-style-marker{color:red} } view { <p class="unique-server-style-marker">Probe</p> } }\n`,
);
writeFileSync(
join(root, "app", "pages", "index.wrn"),
`import Probe from "../components/Probe.wrn"\npage Home { view { <main class="app-shell"><Probe /></main> } }\n`,
);
await runBuild(root);
const styles = readFileSync(join(root, "dist", "styles.css"), "utf8");
const activeTheme = readFileSync(join(root, "dist", "theme", "dark", "violet.css"), "utf8");
const server = readFileSync(join(root, "dist", "server.js"), "utf8");
expect(styles).toContain(".app-shell");
expect(styles).not.toContain("[data-theme=");
expect(activeTheme.length).toBeLessThan(10_000);
expect(server.match(/unique-server-style-marker/g)).toHaveLength(2);
});