Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion packages/kumo-docs-astro/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ const buildInfo = getBuildInfo();
// Detect dev mode: `astro dev` sets this in process.argv
const isDev = process.argv.includes("dev");

// Load the built config while Astro's config module runner is still active.
// In dev, defer to the source-loading path so Kumo does not need to be built.
const builtThemeConfig = isDev
? undefined
: await import("@cloudflare/kumo/scripts/theme-generator/config");

// Path to kumo source (used for dev mode CSS aliases)
const kumoSrc = resolve(__dirname, "../kumo/src");

Expand Down Expand Up @@ -107,7 +113,7 @@ export default defineConfig({
// before Tailwind processes them.
...(isDev ? [kumoHmrPlugin()] : []),
tailwindcss(),
kumoColorsPlugin(),
kumoColorsPlugin({ isDev, builtThemeConfig }),
kumoRegistryPlugin(),
],

Expand Down
61 changes: 33 additions & 28 deletions packages/kumo-docs-astro/src/lib/vite-plugin-kumo-colors.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import {
THEME_CONFIG as STATIC_THEME_CONFIG,
AVAILABLE_THEMES as STATIC_AVAILABLE_THEMES,
} from "@cloudflare/kumo/scripts/theme-generator/config";
import type { TokenDefinition } from "@cloudflare/kumo/scripts/theme-generator/types";
import type {
ThemeConfig,
TokenDefinition,
} from "@cloudflare/kumo/scripts/theme-generator/types";

const __dirname = dirname(fileURLToPath(import.meta.url));

Expand All @@ -21,6 +20,11 @@ type ColorToken = {
tokenType: TokenType;
};

type ThemeConfigModule = {
THEME_CONFIG: ThemeConfig;
AVAILABLE_THEMES: readonly string[];
};

// Path to the source config.ts — used for dev-mode loading and HMR watching
const configFile = resolve(
__dirname,
Expand All @@ -32,8 +36,8 @@ const configFile = resolve(
* Derives token data directly from config.ts (single source of truth).
*/
function getColorsFromConfig(
THEME_CONFIG: typeof STATIC_THEME_CONFIG,
AVAILABLE_THEMES: typeof STATIC_AVAILABLE_THEMES,
THEME_CONFIG: ThemeConfig,
AVAILABLE_THEMES: readonly string[],
): ColorToken[] {
const colors: ColorToken[] = [];

Expand Down Expand Up @@ -106,25 +110,22 @@ function getColorsFromConfig(
*
* In dev mode, uses Vite's ssrLoadModule to import the source .ts file
* directly — changes to config.ts are reflected without rebuilding kumo.
* In production builds, uses the static import from the built dist/.
* In production builds, loads the package export from the built dist/.
*
* @returns Astro/Vite compatible plugin
*/
export function kumoColorsPlugin() {
// Reference to the Vite dev server (set during configureServer).
// Only used in actual dev mode — Astro's build also creates a server
// for SSR, but ssrLoadModule can hang during build, so we track the
// real mode via the config hook.
export function kumoColorsPlugin({
isDev,
builtThemeConfig,
}: {
isDev: boolean;
builtThemeConfig?: ThemeConfigModule;
}) {
let server: any = null;
let isDevMode = false;

return {
name: "vite-plugin-kumo-colors",

config(_: unknown, env: { command: string }) {
isDevMode = env.command === "serve";
},

resolveId(id: string) {
if (id === VIRTUAL_MODULE_ID) {
return RESOLVED_VIRTUAL_MODULE_ID;
Expand All @@ -133,23 +134,27 @@ export function kumoColorsPlugin() {

async load(id: string) {
if (id === RESOLVED_VIRTUAL_MODULE_ID) {
let THEME_CONFIG: typeof STATIC_THEME_CONFIG;
let AVAILABLE_THEMES: typeof STATIC_AVAILABLE_THEMES;
let themeConfig: ThemeConfig;
let availableThemes: readonly string[];

if (isDevMode && server) {
if (isDev && server) {
// Dev mode: load source .ts directly via Vite's module runner.
// This always reads the latest file contents — no build needed.
const mod = await server.ssrLoadModule(configFile);
THEME_CONFIG = mod.THEME_CONFIG;
AVAILABLE_THEMES = mod.AVAILABLE_THEMES;
themeConfig = mod.THEME_CONFIG;
availableThemes = mod.AVAILABLE_THEMES;
} else {
// Production build: use the statically imported config from dist/.
// This is resolved at module load time and always available.
THEME_CONFIG = STATIC_THEME_CONFIG;
AVAILABLE_THEMES = STATIC_AVAILABLE_THEMES;
if (!builtThemeConfig) {
throw new Error(
"The built Kumo theme config is required outside dev mode.",
);
}

themeConfig = builtThemeConfig.THEME_CONFIG;
availableThemes = builtThemeConfig.AVAILABLE_THEMES;
}

const colors = getColorsFromConfig(THEME_CONFIG, AVAILABLE_THEMES);
const colors = getColorsFromConfig(themeConfig, availableThemes);

return `
export const kumoColors = ${JSON.stringify(colors, null, 2)};
Expand Down
4 changes: 4 additions & 0 deletions packages/kumo-docs-astro/src/lib/vite-plugin-kumo-hmr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ const aliases: Record<string, string> = {
kumoRoot,
"scripts/theme-generator/types.ts",
),

// Code highlighting has separate client and server entry points.
"@cloudflare/kumo/code": resolve(kumoSrc, "code/index.ts"),
"@cloudflare/kumo/code/server": resolve(kumoSrc, "code/server.tsx"),
};

/**
Expand Down
Loading