diff --git a/electron.vite.config.ts b/electron.vite.config.ts index ae5de1887c..9176f2574c 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -5,7 +5,6 @@ import tailwindcss from "@tailwindcss/vite"; import react from "@vitejs/plugin-react-swc"; import { defineConfig } from "electron-vite"; import { ViteImageOptimizer } from "vite-plugin-image-optimizer"; -import { viteStaticCopy } from "vite-plugin-static-copy"; import svgr from "vite-plugin-svgr"; import tsconfigPaths from "vite-tsconfig-paths"; @@ -134,8 +133,7 @@ export default defineConfig({ manualChunks(id) { const p = id.replace(/\\/g, "/"); if (p.includes("node_modules/monaco") || p.includes("node_modules/@monaco")) return "monaco"; - if (p.includes("node_modules/mermaid") || p.includes("node_modules/@mermaid")) - return "mermaid"; + if (p.includes("node_modules/mermaid") || p.includes("node_modules/@mermaid")) return "mermaid"; if (p.includes("node_modules/katex") || p.includes("node_modules/@katex")) return "katex"; if (p.includes("node_modules/shiki") || p.includes("node_modules/@shiki")) { return "shiki"; @@ -153,7 +151,17 @@ export default defineConfig({ server: { open: false, watch: { - ignored: ["dist/**", "**/*.go", "**/go.mod", "**/go.sum", "**/*.md", "**/*.json", "emain/**"], + ignored: [ + "dist/**", + "**/*.go", + "**/go.mod", + "**/go.sum", + "**/*.md", + "**/*.json", + "emain/**", + "**/*.txt", + "**/*.log", + ], }, }, css: { @@ -172,9 +180,6 @@ export default defineConfig({ }), react({}), tailwindcss(), - viteStaticCopy({ - targets: [{ src: "node_modules/monaco-editor/min/vs/*", dest: "monaco" }], - }), ], }, }); diff --git a/frontend/app/monaco/monaco-env.ts b/frontend/app/monaco/monaco-env.ts new file mode 100644 index 0000000000..a11c44b60a --- /dev/null +++ b/frontend/app/monaco/monaco-env.ts @@ -0,0 +1,82 @@ +// Copyright 2025, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +import * as monaco from "monaco-editor"; +import "monaco-editor/esm/vs/language/css/monaco.contribution"; +import "monaco-editor/esm/vs/language/html/monaco.contribution"; +import "monaco-editor/esm/vs/language/json/monaco.contribution"; +import "monaco-editor/esm/vs/language/typescript/monaco.contribution"; +import { configureMonacoYaml } from "monaco-yaml"; + +import { MonacoSchemas } from "@/app/monaco/schemaendpoints"; +import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker"; +import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker"; +import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker"; +import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker"; +import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker"; +import ymlWorker from "./yamlworker?worker"; + +let monacoConfigured = false; + +window.MonacoEnvironment = { + getWorker(_, label) { + if (label === "json") { + return new jsonWorker(); + } + if (label === "css" || label === "scss" || label === "less") { + return new cssWorker(); + } + if (label === "yaml" || label === "yml") { + return new ymlWorker(); + } + if (label === "html" || label === "handlebars" || label === "razor") { + return new htmlWorker(); + } + if (label === "typescript" || label === "javascript") { + return new tsWorker(); + } + return new editorWorker(); + }, +}; + +export function loadMonaco() { + if (monacoConfigured) { + return; + } + monacoConfigured = true; + monaco.editor.defineTheme("wave-theme-dark", { + base: "vs-dark", + inherit: true, + rules: [], + colors: { + "editor.background": "#00000000", + "editorStickyScroll.background": "#00000055", + "minimap.background": "#00000077", + focusBorder: "#00000000", + }, + }); + monaco.editor.defineTheme("wave-theme-light", { + base: "vs", + inherit: true, + rules: [], + colors: { + "editor.background": "#fefefe", + focusBorder: "#00000000", + }, + }); + configureMonacoYaml(monaco, { + validate: true, + schemas: [], + }); + monaco.editor.setTheme("wave-theme-dark"); + // Disable default validation errors for typescript and javascript + monaco.typescript.typescriptDefaults.setDiagnosticsOptions({ + noSemanticValidation: true, + }); + monaco.json.jsonDefaults.setDiagnosticsOptions({ + validate: true, + allowComments: false, + enableSchemaRequest: true, + schemas: MonacoSchemas, + }); +} diff --git a/frontend/app/monaco/monaco-react.tsx b/frontend/app/monaco/monaco-react.tsx new file mode 100644 index 0000000000..aee722e314 --- /dev/null +++ b/frontend/app/monaco/monaco-react.tsx @@ -0,0 +1,171 @@ +// Copyright 2025, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +import { loadMonaco } from "@/app/monaco/monaco-env"; +import type * as MonacoTypes from "monaco-editor"; +import * as monaco from "monaco-editor"; +import { useEffect, useRef } from "react"; + +function createModel(value: string, path: string, language?: string) { + const uri = monaco.Uri.parse(`wave://editor/${encodeURIComponent(path)}`); + return monaco.editor.createModel(value, language, uri); +} + +type CodeEditorProps = { + text: string; + readonly: boolean; + language?: string; + onChange?: (text: string) => void; + onMount?: (editor: MonacoTypes.editor.IStandaloneCodeEditor, monacoApi: typeof monaco) => () => void; + path: string; + options: MonacoTypes.editor.IEditorOptions; +}; + +export function MonacoCodeEditor({ + text, + readonly, + language, + onChange, + onMount, + path, + options, +}: CodeEditorProps) { + const divRef = useRef(null); + const editorRef = useRef(null); + const onUnmountRef = useRef<(() => void) | null>(null); + const applyingFromProps = useRef(false); + + useEffect(() => { + loadMonaco(); + + const el = divRef.current; + if (!el) return; + + const model = createModel(text, path, language); + console.log("[monaco] CREATE MODEL", path, model); + + const editor = monaco.editor.create(el, { + ...options, + readOnly: readonly, + model, + }); + editorRef.current = editor; + + const sub = model.onDidChangeContent(() => { + if (applyingFromProps.current) return; + onChange?.(model.getValue()); + }); + + if (onMount) { + onUnmountRef.current = onMount(editor, monaco); + } + + return () => { + sub.dispose(); + if (onUnmountRef.current) onUnmountRef.current(); + editor.dispose(); + model.dispose(); + console.log("[monaco] dispose model"); + editorRef.current = null; + }; + // mount/unmount only + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // Keep model value in sync with props + useEffect(() => { + const editor = editorRef.current; + if (!editor) return; + const model = editor.getModel(); + if (!model) return; + + const current = model.getValue(); + if (current === text) return; + + applyingFromProps.current = true; + model.pushEditOperations([], [{ range: model.getFullModelRange(), text }], () => null); + applyingFromProps.current = false; + }, [text]); + + // Keep options in sync + useEffect(() => { + const editor = editorRef.current; + if (!editor) return; + editor.updateOptions({ ...options, readOnly: readonly }); + }, [options, readonly]); + + // Keep language in sync + useEffect(() => { + const editor = editorRef.current; + if (!editor) return; + const model = editor.getModel(); + if (!model || !language) return; + monaco.editor.setModelLanguage(model, language); + }, [language]); + + return
; +} + +type DiffViewerProps = { + original: string; + modified: string; + language?: string; + path: string; + options: MonacoTypes.editor.IDiffEditorOptions; +}; + +export function MonacoDiffViewer({ original, modified, language, path, options }: DiffViewerProps) { + const divRef = useRef(null); + const diffRef = useRef(null); + + // Create once + useEffect(() => { + loadMonaco(); + + const el = divRef.current; + if (!el) return; + + const origUri = monaco.Uri.parse(`wave://diff/${encodeURIComponent(path)}.orig`); + const modUri = monaco.Uri.parse(`wave://diff/${encodeURIComponent(path)}.mod`); + + const originalModel = monaco.editor.createModel(original, language, origUri); + const modifiedModel = monaco.editor.createModel(modified, language, modUri); + + const diff = monaco.editor.createDiffEditor(el, options); + diffRef.current = diff; + + diff.setModel({ original: originalModel, modified: modifiedModel }); + + return () => { + diff.dispose(); + originalModel.dispose(); + modifiedModel.dispose(); + diffRef.current = null; + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // Update models on prop change + useEffect(() => { + const diff = diffRef.current; + if (!diff) return; + const model = diff.getModel(); + if (!model) return; + + if (model.original.getValue() !== original) model.original.setValue(original); + if (model.modified.getValue() !== modified) model.modified.setValue(modified); + + if (language) { + monaco.editor.setModelLanguage(model.original, language); + monaco.editor.setModelLanguage(model.modified, language); + } + }, [original, modified, language]); + + useEffect(() => { + const diff = diffRef.current; + if (!diff) return; + diff.updateOptions(options); + }, [options]); + + return
; +} diff --git a/frontend/app/monaco/schemaendpoints.ts b/frontend/app/monaco/schemaendpoints.ts new file mode 100644 index 0000000000..2b3134e215 --- /dev/null +++ b/frontend/app/monaco/schemaendpoints.ts @@ -0,0 +1,50 @@ +// Copyright 2025, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +import settingsSchema from "../../../schema/settings.json"; +import connectionsSchema from "../../../schema/connections.json"; +import aipresetsSchema from "../../../schema/aipresets.json"; +import bgpresetsSchema from "../../../schema/bgpresets.json"; +import waveaiSchema from "../../../schema/waveai.json"; +import widgetsSchema from "../../../schema/widgets.json"; + +type SchemaInfo = { + uri: string; + fileMatch: Array; + schema: object; +}; + +const MonacoSchemas: SchemaInfo[] = [ + { + uri: "wave://schema/settings.json", + fileMatch: ["*/WAVECONFIGPATH/settings.json"], + schema: settingsSchema, + }, + { + uri: "wave://schema/connections.json", + fileMatch: ["*/WAVECONFIGPATH/connections.json"], + schema: connectionsSchema, + }, + { + uri: "wave://schema/aipresets.json", + fileMatch: ["*/WAVECONFIGPATH/presets/ai.json"], + schema: aipresetsSchema, + }, + { + uri: "wave://schema/bgpresets.json", + fileMatch: ["*/WAVECONFIGPATH/presets/bg.json"], + schema: bgpresetsSchema, + }, + { + uri: "wave://schema/waveai.json", + fileMatch: ["*/WAVECONFIGPATH/waveai.json"], + schema: waveaiSchema, + }, + { + uri: "wave://schema/widgets.json", + fileMatch: ["*/WAVECONFIGPATH/widgets.json"], + schema: widgetsSchema, + }, +]; + +export { MonacoSchemas }; diff --git a/frontend/app/view/codeeditor/yamlworker.js b/frontend/app/monaco/yamlworker.js similarity index 100% rename from frontend/app/view/codeeditor/yamlworker.js rename to frontend/app/monaco/yamlworker.js diff --git a/frontend/app/view/codeeditor/codeeditor.tsx b/frontend/app/view/codeeditor/codeeditor.tsx index c77c4d9b7c..2f93264cbf 100644 --- a/frontend/app/view/codeeditor/codeeditor.tsx +++ b/frontend/app/view/codeeditor/codeeditor.tsx @@ -1,86 +1,12 @@ // Copyright 2025, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 +import { MonacoCodeEditor } from "@/app/monaco/monaco-react"; import { useOverrideConfigAtom } from "@/app/store/global"; -import loader from "@monaco-editor/loader"; -import { Editor, Monaco } from "@monaco-editor/react"; -import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api"; -import { configureMonacoYaml } from "monaco-yaml"; -import React, { useMemo, useRef } from "react"; - import { boundNumber } from "@/util/util"; -import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker"; -import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker"; -import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker"; -import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker"; -import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker"; -import { SchemaEndpoints, getSchemaEndpointInfo } from "./schemaendpoints"; -import ymlWorker from "./yamlworker?worker"; - -// there is a global monaco variable (TODO get the correct TS type) -declare var monaco: Monaco; - -window.MonacoEnvironment = { - getWorker(_, label) { - if (label === "json") { - return new jsonWorker(); - } - if (label === "css" || label === "scss" || label === "less") { - return new cssWorker(); - } - if (label === "yaml" || label === "yml") { - return new ymlWorker(); - } - if (label === "html" || label === "handlebars" || label === "razor") { - return new htmlWorker(); - } - if (label === "typescript" || label === "javascript") { - return new tsWorker(); - } - return new editorWorker(); - }, -}; - -export async function loadMonaco() { - loader.config({ paths: { vs: "monaco" } }); - await loader.init(); - - monaco.editor.defineTheme("wave-theme-dark", { - base: "vs-dark", - inherit: true, - rules: [], - colors: { - "editor.background": "#00000000", - "editorStickyScroll.background": "#00000055", - "minimap.background": "#00000077", - focusBorder: "#00000000", - }, - }); - monaco.editor.defineTheme("wave-theme-light", { - base: "vs", - inherit: true, - rules: [], - colors: { - "editor.background": "#fefefe", - focusBorder: "#00000000", - }, - }); - configureMonacoYaml(monaco, { - validate: true, - schemas: [], - }); - // Disable default validation errors for typescript and javascript - monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({ - noSemanticValidation: true, - }); - const schemas = await Promise.all(SchemaEndpoints.map((endpoint) => getSchemaEndpointInfo(endpoint))); - monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ - validate: true, - allowComments: false, // Set to true if you want to allow comments in JSON - enableSchemaRequest: true, - schemas, - }); -} +import type * as MonacoTypes from "monaco-editor"; +import * as MonacoModule from "monaco-editor"; +import React, { useMemo, useRef } from "react"; function defaultEditorOptions(): MonacoTypes.editor.IEditorOptions { const opts: MonacoTypes.editor.IEditorOptions = { @@ -110,7 +36,7 @@ interface CodeEditorProps { language?: string; fileName?: string; onChange?: (text: string) => void; - onMount?: (monacoPtr: MonacoTypes.editor.IStandaloneCodeEditor, monaco: Monaco) => () => void; + onMount?: (monacoPtr: MonacoTypes.editor.IStandaloneCodeEditor, monaco: typeof MonacoModule) => () => void; } export function CodeEditor({ blockId, text, language, fileName, readonly, onChange, onMount }: CodeEditorProps) { @@ -120,7 +46,6 @@ export function CodeEditor({ blockId, text, language, fileName, readonly, onChan const stickyScrollEnabled = useOverrideConfigAtom(blockId, "editor:stickyscrollenabled") ?? false; const wordWrap = useOverrideConfigAtom(blockId, "editor:wordwrap") ?? false; const fontSize = boundNumber(useOverrideConfigAtom(blockId, "editor:fontsize"), 6, 64); - const theme = "wave-theme-dark"; const uuidRef = useRef(crypto.randomUUID()).current; let editorPath: string; if (fileName) { @@ -139,21 +64,24 @@ export function CodeEditor({ blockId, text, language, fileName, readonly, onChan }; }, []); - function handleEditorChange(text: string, ev: MonacoTypes.editor.IModelContentChangedEvent) { + function handleEditorChange(text: string) { if (onChange) { onChange(text); } } - function handleEditorOnMount(editor: MonacoTypes.editor.IStandaloneCodeEditor, monaco: Monaco) { + function handleEditorOnMount( + editor: MonacoTypes.editor.IStandaloneCodeEditor, + monaco: typeof MonacoModule + ): () => void { if (onMount) { unmountRef.current = onMount(editor, monaco); } + return null; } const editorOpts = useMemo(() => { const opts = defaultEditorOptions(); - opts.readOnly = readonly; opts.minimap.enabled = minimapEnabled; opts.stickyScroll.enabled = stickyScrollEnabled; opts.wordWrap = wordWrap ? "on" : "off"; @@ -165,9 +93,9 @@ export function CodeEditor({ blockId, text, language, fileName, readonly, onChan return (
- { const opts = defaultDiffEditorOptions(); @@ -56,8 +62,8 @@ export function DiffViewer({ blockId, original, modified, language, fileName }: return (
- ; - schema: object; -}; - -const allFilepaths: Map> = new Map(); -allFilepaths.set(`${getWebServerEndpoint()}/schema/settings.json`, ["*/WAVECONFIGPATH/settings.json"]); -allFilepaths.set(`${getWebServerEndpoint()}/schema/connections.json`, ["*/WAVECONFIGPATH/connections.json"]); -allFilepaths.set(`${getWebServerEndpoint()}/schema/aipresets.json`, ["*/WAVECONFIGPATH/presets/ai.json"]); -allFilepaths.set(`${getWebServerEndpoint()}/schema/bgpresets.json`, ["*/WAVECONFIGPATH/presets/bg.json"]); -allFilepaths.set(`${getWebServerEndpoint()}/schema/waveai.json`, ["*/WAVECONFIGPATH/waveai.json"]); -allFilepaths.set(`${getWebServerEndpoint()}/schema/widgets.json`, ["*/WAVECONFIGPATH/widgets.json"]); - -async function getSchemaEndpointInfo(endpoint: string): Promise { - let schema: Object; - try { - const data = await fetch(endpoint); - schema = await data.json(); - } catch (e) { - console.log("cannot find schema:", e); - schema = {}; - } - const fileMatch = allFilepaths.get(endpoint) ?? []; - - return { - uri: endpoint, - fileMatch, - schema, - }; -} - -const SchemaEndpoints = Array.from(allFilepaths.keys()); - -export { getSchemaEndpointInfo, SchemaEndpoints }; diff --git a/frontend/app/view/preview/preview-edit.tsx b/frontend/app/view/preview/preview-edit.tsx index dd7d9f56ae..f63e399bba 100644 --- a/frontend/app/view/preview/preview-edit.tsx +++ b/frontend/app/view/preview/preview-edit.tsx @@ -6,9 +6,9 @@ import { CodeEditor } from "@/app/view/codeeditor/codeeditor"; import { globalStore } from "@/store/global"; import { adaptFromReactOrNativeKeyEvent, checkKeyPressed } from "@/util/keyutil"; import { fireAndForget } from "@/util/util"; -import { Monaco } from "@monaco-editor/react"; import { useAtomValue, useSetAtom } from "jotai"; -import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api"; +import * as monaco from "monaco-editor"; +import type * as MonacoTypes from "monaco-editor"; import { useEffect } from "react"; import type { SpecializedViewProps } from "./preview"; @@ -73,7 +73,7 @@ function CodeEditPreview({ model }: SpecializedViewProps) { }; }, []); - function onMount(editor: MonacoTypes.editor.IStandaloneCodeEditor, monaco: Monaco): () => void { + function onMount(editor: MonacoTypes.editor.IStandaloneCodeEditor, monacoApi: typeof monaco): () => void { model.monacoRef.current = editor; const keyDownDisposer = editor.onKeyDown((e: MonacoTypes.IKeyboardEvent) => { diff --git a/frontend/app/view/preview/preview-model.tsx b/frontend/app/view/preview/preview-model.tsx index d1eed4cfbc..3431a9663f 100644 --- a/frontend/app/view/preview/preview-model.tsx +++ b/frontend/app/view/preview/preview-model.tsx @@ -17,7 +17,7 @@ import { formatRemoteUri } from "@/util/waveutil"; import clsx from "clsx"; import { Atom, atom, Getter, PrimitiveAtom, WritableAtom } from "jotai"; import { loadable } from "jotai/utils"; -import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api"; +import type * as MonacoTypes from "monaco-editor"; import { createRef } from "react"; import { PreviewView } from "./preview"; diff --git a/frontend/app/view/waveconfig/waveconfig-model.ts b/frontend/app/view/waveconfig/waveconfig-model.ts index 7c2af88d6d..cd7d4e45e3 100644 --- a/frontend/app/view/waveconfig/waveconfig-model.ts +++ b/frontend/app/view/waveconfig/waveconfig-model.ts @@ -12,7 +12,7 @@ import { WaveConfigView } from "@/app/view/waveconfig/waveconfig"; import { isWindows } from "@/util/platformutil"; import { base64ToString, stringToBase64 } from "@/util/util"; import { atom, type PrimitiveAtom } from "jotai"; -import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api"; +import type * as MonacoTypes from "monaco-editor"; import * as React from "react"; type ValidationResult = { success: true } | { error: string }; diff --git a/frontend/app/view/waveconfig/waveconfig.tsx b/frontend/app/view/waveconfig/waveconfig.tsx index 8eff903b3c..9c5e873bc9 100644 --- a/frontend/app/view/waveconfig/waveconfig.tsx +++ b/frontend/app/view/waveconfig/waveconfig.tsx @@ -9,7 +9,7 @@ import type { ConfigFile, WaveConfigViewModel } from "@/app/view/waveconfig/wave import { adaptFromReactOrNativeKeyEvent, checkKeyPressed, keydownWrapper } from "@/util/keyutil"; import { cn } from "@/util/util"; import { useAtom, useAtomValue } from "jotai"; -import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api"; +import type * as MonacoTypes from "monaco-editor"; import { memo, useCallback, useEffect, useRef } from "react"; import { debounce } from "throttle-debounce"; diff --git a/frontend/wave.ts b/frontend/wave.ts index 7a460dae15..4cb8ee095f 100644 --- a/frontend/wave.ts +++ b/frontend/wave.ts @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { App } from "@/app/app"; +import { loadMonaco } from "@/app/monaco/monaco-env"; import { GlobalModel } from "@/app/store/global-model"; import { globalRefocus, @@ -14,7 +15,6 @@ import { modalsModel } from "@/app/store/modalmodel"; import { RpcApi } from "@/app/store/wshclientapi"; import { makeBuilderRouteId, makeTabRouteId } from "@/app/store/wshrouter"; import { initWshrpc, TabRpcClient } from "@/app/store/wshrpcutil"; -import { loadMonaco } from "@/app/view/codeeditor/codeeditor"; import { BuilderApp } from "@/builder/builder-app"; import { getLayoutModelForStaticTab } from "@/layout/index"; import { diff --git a/package-lock.json b/package-lock.json index e8fbf58f84..bc0bbdb1dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,8 +16,6 @@ "dependencies": { "@ai-sdk/react": "^2.0.104", "@floating-ui/react": "^0.27.16", - "@monaco-editor/loader": "^1.5.0", - "@monaco-editor/react": "^4.7.0", "@observablehq/plot": "^0.6.17", "@react-hook/resize-observer": "^2.0.2", "@table-nav/core": "^0.0.7", @@ -46,7 +44,7 @@ "immer": "^10.1.1", "jotai": "2.9.3", "mermaid": "^11.12.1", - "monaco-editor": "^0.52.0", + "monaco-editor": "^0.55.1", "monaco-yaml": "^5.4.0", "overlayscrollbars": "^2.12.0", "overlayscrollbars-react": "^0.5.6", @@ -128,7 +126,6 @@ "typescript-eslint": "^8.49.0", "vite": "^6.4.1", "vite-plugin-image-optimizer": "^2.0.3", - "vite-plugin-static-copy": "^3.1.4", "vite-plugin-svgr": "^4.5.0", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.0.9" @@ -6608,29 +6605,6 @@ "langium": "3.3.1" } }, - "node_modules/@monaco-editor/loader": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.5.0.tgz", - "integrity": "sha512-hKoGSM+7aAc7eRTRjpqAZucPmoNOC4UUbknb/VNoTkEIkCPhqV8LfbsgM1webRM7S/z21eHEx9Fkwx8Z/C/+Xw==", - "license": "MIT", - "dependencies": { - "state-local": "^1.0.6" - } - }, - "node_modules/@monaco-editor/react": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", - "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", - "license": "MIT", - "dependencies": { - "@monaco-editor/loader": "^1.5.0" - }, - "peerDependencies": { - "monaco-editor": ">= 0.25.0 < 1", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -14883,9 +14857,9 @@ } }, "node_modules/dompurify": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", - "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -22875,10 +22849,26 @@ } }, "node_modules/monaco-editor": { - "version": "0.52.2", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", - "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==", - "license": "MIT" + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", + "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", + "license": "MIT", + "dependencies": { + "dompurify": "3.2.7", + "marked": "14.0.0" + } + }, + "node_modules/monaco-editor/node_modules/marked": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", + "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } }, "node_modules/monaco-languageserver-types": { "version": "0.4.0", @@ -29676,12 +29666,6 @@ "node": ">= 6" } }, - "node_modules/state-local": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", - "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", - "license": "MIT" - }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -32471,102 +32455,6 @@ } } }, - "node_modules/vite-plugin-static-copy": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-3.1.4.tgz", - "integrity": "sha512-iCmr4GSw4eSnaB+G8zc2f4dxSuDjbkjwpuBLLGvQYR9IW7rnDzftnUjOH5p4RYR+d4GsiBqXRvzuFhs5bnzVyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chokidar": "^3.6.0", - "p-map": "^7.0.3", - "picocolors": "^1.1.1", - "tinyglobby": "^0.2.15" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" - } - }, - "node_modules/vite-plugin-static-copy/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/vite-plugin-static-copy/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/vite-plugin-static-copy/node_modules/p-map": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", - "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vite-plugin-static-copy/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/vite-plugin-static-copy/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/vite-plugin-svgr": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.5.0.tgz", diff --git a/package.json b/package.json index 23c2427c0b..2fc677bfac 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,6 @@ "typescript-eslint": "^8.49.0", "vite": "^6.4.1", "vite-plugin-image-optimizer": "^2.0.3", - "vite-plugin-static-copy": "^3.1.4", "vite-plugin-svgr": "^4.5.0", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.0.9" @@ -77,8 +76,6 @@ "dependencies": { "@ai-sdk/react": "^2.0.104", "@floating-ui/react": "^0.27.16", - "@monaco-editor/loader": "^1.5.0", - "@monaco-editor/react": "^4.7.0", "@observablehq/plot": "^0.6.17", "@react-hook/resize-observer": "^2.0.2", "@table-nav/core": "^0.0.7", @@ -107,7 +104,7 @@ "immer": "^10.1.1", "jotai": "2.9.3", "mermaid": "^11.12.1", - "monaco-editor": "^0.52.0", + "monaco-editor": "^0.55.1", "monaco-yaml": "^5.4.0", "overlayscrollbars": "^2.12.0", "overlayscrollbars-react": "^0.5.6", @@ -131,9 +128,9 @@ "rehype-slug": "^6.0.0", "remark-flexible-toc": "^1.2.4", "remark-gfm": "^4.0.1", - "semver": "^7.7.3", "remark-github-blockquote-alert": "^1.3.1", "rxjs": "^7.8.2", + "semver": "^7.7.3", "shell-quote": "^1.8.3", "shiki": "^3.13.0", "sprintf-js": "^1.1.3",