deer-flow/frontend/src/components/workspace/code-editor-extensions.ts
DanielWalnut 459dd78707
perf(frontend): bound delivery, bundles, and long-running UI work (#4622)
* docs: design frontend performance remediation

* docs: plan frontend performance remediation

* test(frontend): add route asset performance budgets

* perf(nginx): compress textual responses safely

* perf(frontend): lazy load case study media

* perf(frontend): bound static demo file tracing

* perf(frontend): restore static locale boundaries

* perf(frontend): defer closed workspace panels

* perf(frontend): split editors and deduplicate highlighting

* perf(frontend): index incremental message derivation

* perf(frontend): stabilize paged history cache policy

* perf(frontend): bound streaming markdown renders

* perf(frontend): virtualize message history

* perf(frontend): bound and virtualize chat lists

* perf(frontend): suspend inactive decorative animation

* perf(browser): stream latest frames as binary

* perf(artifacts): stream bounded text previews

* docs: finalize performance runtime boundaries

* style(backend): apply test formatting

* fix(frontend): keep translation functions client-side

* perf(frontend): defer decorative animation bundles

* test(frontend): lock optimized route budgets

* fix: harden frontend performance boundaries

* test(frontend): update i18n provider fixture

* fix(frontend): preserve sidebar pagination position

* style(backend): format artifact range test
2026-08-01 22:19:59 +08:00

102 lines
2.5 KiB
TypeScript

import type { Extension } from "@uiw/react-codemirror";
export type CodeEditorLanguage =
| "css"
| "html"
| "javascript"
| "json"
| "markdown"
| "python"
| "text";
export function normalizeCodeEditorLanguage(
language: string | null | undefined,
): CodeEditorLanguage {
switch (language?.toLowerCase()) {
case "css":
case "scss":
case "sass":
case "less":
return "css";
case "html":
case "xml":
return "html";
case "javascript":
case "typescript":
case "jsx":
case "tsx":
return "javascript";
case "json":
case "jsonc":
case "json5":
return "json";
case "markdown":
case "mdx":
return "markdown";
case "python":
case "py":
return "python";
default:
return "text";
}
}
async function loadLanguageExtension(
language: CodeEditorLanguage,
): Promise<Extension[]> {
switch (language) {
case "css":
return [(await import("@codemirror/lang-css")).css()];
case "html":
return [(await import("@codemirror/lang-html")).html()];
case "javascript":
return [(await import("@codemirror/lang-javascript")).javascript()];
case "json":
return [(await import("@codemirror/lang-json")).json()];
case "markdown": {
const markdownModule = await import("@codemirror/lang-markdown");
return [
markdownModule.markdown({ base: markdownModule.markdownLanguage }),
];
}
case "python":
return [(await import("@codemirror/lang-python")).python()];
case "text":
return [];
}
}
async function loadTheme(theme: "light" | "dark"): Promise<Extension> {
if (theme === "dark") {
const { monokaiInit } = await import("@uiw/codemirror-theme-monokai");
return monokaiInit({
settings: {
background: "transparent",
gutterBackground: "transparent",
gutterForeground: "#555",
gutterActiveForeground: "#fff",
fontSize: "var(--text-sm)",
},
});
}
const { basicLightInit } = await import("@uiw/codemirror-theme-basic");
return basicLightInit({
settings: {
background: "transparent",
fontSize: "var(--text-sm)",
},
});
}
export async function loadCodeEditorExtensions(
language: string | null | undefined,
theme: "light" | "dark",
) {
const normalizedLanguage = normalizeCodeEditorLanguage(language);
const [extensions, loadedTheme] = await Promise.all([
loadLanguageExtension(normalizedLanguage),
loadTheme(theme),
]);
return { extensions, theme: loadedTheme };
}