mirror of https://github.com/openclaw/openclaw.git
refactor: dedupe pierre theme loader patch
This commit is contained in:
parent
793b9f8405
commit
4a3aab4ff5
|
|
@ -1,33 +1,58 @@
|
|||
import fs from "node:fs/promises";
|
||||
import { createRequire } from "node:module";
|
||||
import type { ThemeRegistrationResolved } from "@pierre/diffs";
|
||||
import { RegisteredCustomThemes, ResolvedThemes, ResolvingThemes } from "@pierre/diffs";
|
||||
|
||||
type RegisteredThemeLoader = NonNullable<ReturnType<typeof RegisteredCustomThemes.get>>;
|
||||
type RegisteredTheme = Awaited<ReturnType<RegisteredThemeLoader>>;
|
||||
const require = createRequire(import.meta.url);
|
||||
type PierreThemeName = "pierre-dark" | "pierre-light";
|
||||
const diffsRequire = createRequire(import.meta.resolve("@pierre/diffs"));
|
||||
const PIERRE_THEME_SPECS = [
|
||||
["pierre-dark", "@pierre/theme/themes/pierre-dark.json"],
|
||||
["pierre-light", "@pierre/theme/themes/pierre-light.json"],
|
||||
] as const satisfies ReadonlyArray<readonly [PierreThemeName, string]>;
|
||||
|
||||
async function loadPierreTheme(
|
||||
function createThemeLoader(
|
||||
themeName: PierreThemeName,
|
||||
themeSpecifier: string,
|
||||
themeName: string,
|
||||
): Promise<RegisteredTheme> {
|
||||
const themePath = require.resolve(themeSpecifier);
|
||||
return {
|
||||
...(JSON.parse(await fs.readFile(themePath, "utf8")) as Record<string, unknown>),
|
||||
name: themeName,
|
||||
): () => Promise<ThemeRegistrationResolved> {
|
||||
let cachedTheme: ThemeRegistrationResolved | undefined;
|
||||
return async () => {
|
||||
if (cachedTheme) {
|
||||
return cachedTheme;
|
||||
}
|
||||
const themePath = diffsRequire.resolve(themeSpecifier);
|
||||
cachedTheme = {
|
||||
...(JSON.parse(await fs.readFile(themePath, "utf8")) as Record<string, unknown>),
|
||||
name: themeName,
|
||||
} as ThemeRegistrationResolved;
|
||||
return cachedTheme;
|
||||
};
|
||||
}
|
||||
|
||||
export async function ensurePierreThemesRegistered(): Promise<void> {
|
||||
// Always overwrite the upstream loaders so the Node-safe path wins even if
|
||||
// @pierre/diffs registered its JSON-import loaders earlier in this process.
|
||||
RegisteredCustomThemes.set("pierre-light", () =>
|
||||
loadPierreTheme("@pierre/theme/themes/pierre-light.json", "pierre-light"),
|
||||
);
|
||||
RegisteredCustomThemes.set("pierre-dark", () =>
|
||||
loadPierreTheme("@pierre/theme/themes/pierre-dark.json", "pierre-dark"),
|
||||
);
|
||||
ResolvedThemes.delete("pierre-light");
|
||||
ResolvedThemes.delete("pierre-dark");
|
||||
ResolvingThemes.delete("pierre-light");
|
||||
ResolvingThemes.delete("pierre-dark");
|
||||
const PIERRE_THEME_LOADERS = new Map(
|
||||
PIERRE_THEME_SPECS.map(([themeName, themeSpecifier]) => [
|
||||
themeName,
|
||||
createThemeLoader(themeName, themeSpecifier),
|
||||
]),
|
||||
);
|
||||
|
||||
export function ensurePierreThemesRegistered(): void {
|
||||
let replacedThemeLoader = false;
|
||||
|
||||
for (const [themeName, loader] of PIERRE_THEME_LOADERS) {
|
||||
if (RegisteredCustomThemes.get(themeName) !== loader) {
|
||||
RegisteredCustomThemes.set(themeName, loader);
|
||||
replacedThemeLoader = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!replacedThemeLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If another path swapped these loaders, clear the resolver caches so the
|
||||
// next render rehydrates the highlighter with the Node-safe theme source.
|
||||
for (const [themeName] of PIERRE_THEME_LOADERS) {
|
||||
ResolvedThemes.delete(themeName);
|
||||
ResolvingThemes.delete(themeName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,5 @@
|
|||
import fs from "node:fs/promises";
|
||||
import { createRequire } from "node:module";
|
||||
import type {
|
||||
FileContents,
|
||||
FileDiffMetadata,
|
||||
SupportedLanguages,
|
||||
ThemeRegistrationResolved,
|
||||
} from "@pierre/diffs";
|
||||
import { RegisteredCustomThemes, parsePatchFiles } from "@pierre/diffs";
|
||||
import type { FileContents, FileDiffMetadata, SupportedLanguages } from "@pierre/diffs";
|
||||
import { parsePatchFiles } from "@pierre/diffs";
|
||||
import { preloadFileDiff, preloadMultiFileDiff } from "@pierre/diffs/ssr";
|
||||
import { ensurePierreThemesRegistered } from "./pierre-themes.js";
|
||||
import type {
|
||||
|
|
@ -21,45 +14,7 @@ import { VIEWER_LOADER_PATH } from "./viewer-assets.js";
|
|||
const DEFAULT_FILE_NAME = "diff.txt";
|
||||
const MAX_PATCH_FILE_COUNT = 128;
|
||||
const MAX_PATCH_TOTAL_LINES = 120_000;
|
||||
const diffsRequire = createRequire(import.meta.resolve("@pierre/diffs"));
|
||||
|
||||
let pierreThemesPatched = false;
|
||||
|
||||
function createThemeLoader(
|
||||
themeName: "pierre-dark" | "pierre-light",
|
||||
themePath: string,
|
||||
): () => Promise<ThemeRegistrationResolved> {
|
||||
let cachedTheme: ThemeRegistrationResolved | undefined;
|
||||
return async () => {
|
||||
if (cachedTheme) {
|
||||
return cachedTheme;
|
||||
}
|
||||
const raw = await fs.readFile(themePath, "utf8");
|
||||
const parsed = JSON.parse(raw) as Record<string, unknown>;
|
||||
cachedTheme = {
|
||||
...parsed,
|
||||
name: themeName,
|
||||
} as ThemeRegistrationResolved;
|
||||
return cachedTheme;
|
||||
};
|
||||
}
|
||||
|
||||
function patchPierreThemeLoadersForNode24(): void {
|
||||
if (pierreThemesPatched) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const darkThemePath = diffsRequire.resolve("@pierre/theme/themes/pierre-dark.json");
|
||||
const lightThemePath = diffsRequire.resolve("@pierre/theme/themes/pierre-light.json");
|
||||
RegisteredCustomThemes.set("pierre-dark", createThemeLoader("pierre-dark", darkThemePath));
|
||||
RegisteredCustomThemes.set("pierre-light", createThemeLoader("pierre-light", lightThemePath));
|
||||
pierreThemesPatched = true;
|
||||
} catch {
|
||||
// Keep upstream loaders if theme files cannot be resolved.
|
||||
}
|
||||
}
|
||||
|
||||
patchPierreThemeLoadersForNode24();
|
||||
ensurePierreThemesRegistered();
|
||||
|
||||
function escapeCssString(value: string): string {
|
||||
return value.replaceAll("\\", "\\\\").replaceAll('"', '\\"');
|
||||
|
|
@ -376,7 +331,7 @@ async function renderBeforeAfterDiff(
|
|||
input: Extract<DiffInput, { kind: "before_after" }>,
|
||||
options: DiffRenderOptions,
|
||||
): Promise<{ viewerBodyHtml: string; imageBodyHtml: string; fileCount: number }> {
|
||||
await ensurePierreThemesRegistered();
|
||||
ensurePierreThemesRegistered();
|
||||
|
||||
const fileName = resolveBeforeAfterFileName(input);
|
||||
const lang = normalizeSupportedLanguage(input.lang);
|
||||
|
|
@ -436,7 +391,7 @@ async function renderPatchDiff(
|
|||
input: Extract<DiffInput, { kind: "patch" }>,
|
||||
options: DiffRenderOptions,
|
||||
): Promise<{ viewerBodyHtml: string; imageBodyHtml: string; fileCount: number }> {
|
||||
await ensurePierreThemesRegistered();
|
||||
ensurePierreThemesRegistered();
|
||||
|
||||
const files = parsePatchFiles(input.patch).flatMap((entry) => entry.files ?? []);
|
||||
if (files.length === 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue