@alauda/react-code-editor 0.1.0-next.20260812.1786527360 → 0.1.0-next.20260817.1786952747

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,9 +13,9 @@ function configureMonacoEnvironment() {
13
13
  if (typeof window === "undefined") return;
14
14
  if (typeof Reflect.get(window, "MonacoEnvironment")?.getWorker === "function") return;
15
15
  window.MonacoEnvironment = { getWorker: (_moduleId, label) => {
16
- if (label === "yaml") return new Worker(new URL("./yaml/yaml.worker.js", import.meta.url));
17
- if (label === "json") return new Worker(new URL("monaco-editor/esm/vs/language/json/json.worker.js", import.meta.url));
18
- return new Worker(new URL("monaco-editor/esm/vs/editor/editor.worker.js", import.meta.url));
16
+ if (label === "yaml") return new Worker(new URL("./yaml/yaml.worker.js", import.meta.url), { type: "module" });
17
+ if (label === "json") return new Worker(new URL("monaco-editor/esm/vs/language/json/json.worker.js", import.meta.url), { type: "module" });
18
+ return new Worker(new URL("monaco-editor/esm/vs/editor/editor.worker.js", import.meta.url), { type: "module" });
19
19
  } };
20
20
  }
21
21
  //#endregion
@@ -383,6 +383,7 @@ const CodeEditor = forwardRef(function CodeEditor({ value, onChange, onBlur, lan
383
383
  insertSpaces: true,
384
384
  lineHeight: 22,
385
385
  minimap: { enabled: false },
386
+ occurrencesHighlight: "off",
386
387
  padding: {
387
388
  top: 12,
388
389
  bottom: 12
@@ -428,4 +429,4 @@ const CodeEditor = forwardRef(function CodeEditor({ value, onChange, onBlur, lan
428
429
  //#endregion
429
430
  export { getSharedRuntimeState as i, acquireModelOwnership as n, loadMonacoRuntime as r, CodeEditor as t };
430
431
 
431
- //# sourceMappingURL=CodeEditor-CEfhCmSA.js.map
432
+ //# sourceMappingURL=CodeEditor-BeDnriRO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeEditor-BeDnriRO.js","names":[],"sources":["../../../src/monacoEnvironment.ts","../../../src/runtime/runtimeState.ts","../../../src/runtime/loadMonaco.ts","../../../src/runtime/modelOwnership.ts","../../../src/CodeEditor.tsx"],"sourcesContent":["declare global {\n interface Window {\n MonacoEnvironment: {\n getWorker: (_moduleId: string, label: string) => Worker;\n };\n }\n}\n\nexport function configureMonacoEnvironment(): void {\n if (typeof window === 'undefined') return;\n const existing = Reflect.get(window, 'MonacoEnvironment') as\n | { readonly getWorker?: unknown }\n | undefined;\n if (typeof existing?.getWorker === 'function') return;\n\n window.MonacoEnvironment = {\n getWorker: (_moduleId, label) => {\n if (label === 'yaml') {\n return new Worker(\n new URL('./yaml/yaml.worker.js', import.meta.url),\n { type: 'module' },\n );\n }\n if (label === 'json') {\n return new Worker(new URL(\n 'monaco-editor/esm/vs/language/json/json.worker.js',\n import.meta.url,\n ), { type: 'module' });\n }\n return new Worker(new URL(\n 'monaco-editor/esm/vs/editor/editor.worker.js',\n import.meta.url,\n ), { type: 'module' });\n },\n };\n}\n","import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nexport interface SharedCodeEditorRuntimeState {\n monaco?: typeof Monaco;\n monacoPromise?: Promise<typeof Monaco>;\n models?: Map<string, unknown>;\n yaml?: unknown;\n}\n\nconst runtimeKey = Symbol.for('alauda.react-code-editor.runtime');\n\nexport function getSharedRuntimeState(): SharedCodeEditorRuntimeState {\n const target = globalThis as typeof globalThis & {\n [runtimeKey]?: SharedCodeEditorRuntimeState;\n };\n target[runtimeKey] ??= {};\n return target[runtimeKey];\n}\n","import { loader } from '@monaco-editor/react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { configureMonacoEnvironment } from '../monacoEnvironment';\nimport { getSharedRuntimeState } from './runtimeState';\n\nexport function loadMonacoRuntime(): Promise<typeof Monaco> {\n const runtime = getSharedRuntimeState();\n if (runtime.monacoPromise) return runtime.monacoPromise;\n const promise = (async () => {\n configureMonacoEnvironment();\n const monaco = await import(\n 'monaco-editor/esm/vs/editor/editor.main.js'\n );\n loader.config({ monaco });\n runtime.monaco = monaco;\n return monaco;\n })();\n runtime.monacoPromise = promise;\n void promise.catch(() => {\n if (runtime.monacoPromise === promise) runtime.monacoPromise = undefined;\n });\n return promise;\n}\n","import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { getSharedRuntimeState } from './runtimeState';\n\ninterface ModelOwnership {\n readonly language: string;\n readonly owners: Set<string>;\n readonly uri: Monaco.Uri;\n readonly ownedByPackage: boolean;\n}\n\nfunction ownershipRegistry(): Map<string, ModelOwnership> {\n const runtime = getSharedRuntimeState();\n runtime.models ??= new Map();\n return runtime.models as Map<string, ModelOwnership>;\n}\n\nexport function acquireModelOwnership(\n monaco: typeof Monaco,\n ownerId: string,\n modelPath: string,\n language: string,\n): () => void {\n const registry = ownershipRegistry();\n const existing = registry.get(modelPath);\n if (existing && existing.language !== language) {\n throw new Error(\n `Conflicting editor languages for ${modelPath}: `\n + `${existing.language} and ${language}`,\n );\n }\n\n const ownership = existing ?? (() => {\n const uri = monaco.Uri.parse(modelPath);\n return {\n language,\n owners: new Set<string>(),\n uri,\n ownedByPackage: !monaco.editor.getModel(uri),\n } satisfies ModelOwnership;\n })();\n ownership.owners.add(ownerId);\n registry.set(modelPath, ownership);\n\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n ownership.owners.delete(ownerId);\n if (ownership.owners.size > 0) return;\n registry.delete(modelPath);\n if (ownership.ownedByPackage) {\n monaco.editor.getModel(ownership.uri)?.dispose();\n }\n };\n}\n","import Editor, { type OnMount } from '@monaco-editor/react';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport { useTheme } from '@mui/material/styles';\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n type FC,\n type ReactNode,\n} from 'react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { loadMonacoRuntime } from './runtime/loadMonaco';\nimport { acquireModelOwnership } from './runtime/modelOwnership';\n\nexport type CodeEditorLanguage =\n | 'json'\n | 'markdown'\n | 'plaintext'\n | 'yaml';\n\nexport type CodeEditorAction =\n | 'copy'\n | 'find'\n | 'format'\n | 'fullscreen'\n | 'redo'\n | 'undo';\n\nexport type CodeEditorDiagnosticSeverity =\n | 'error'\n | 'warning'\n | 'info'\n | 'hint';\n\nexport interface CodeEditorDiagnostic {\n readonly severity: CodeEditorDiagnosticSeverity;\n readonly message: string;\n readonly line: number;\n readonly column: number;\n readonly endLine: number;\n readonly endColumn: number;\n readonly code?: string;\n}\n\nexport interface CodeEditorLabels {\n readonly copy: string;\n readonly copied: string;\n readonly copyFailed: string;\n readonly find: string;\n readonly format: string;\n readonly fullscreen: string;\n readonly exitFullscreen: string;\n readonly undo: string;\n readonly redo: string;\n readonly loading: string;\n readonly valid: string;\n readonly errors: (count: number) => string;\n readonly lineColumn: (line: number, column: number) => string;\n}\n\nexport interface CodeEditorHandle {\n focus(): void;\n find(): Promise<void>;\n format(): Promise<void>;\n undo(): void;\n redo(): void;\n validate(): Promise<readonly CodeEditorDiagnostic[]>;\n}\n\nexport interface CodeEditorProps {\n readonly value: string;\n readonly onChange: (value: string) => void;\n readonly onBlur?: () => void;\n readonly language: CodeEditorLanguage;\n readonly modelPath: string;\n readonly ariaLabel: string;\n readonly readOnly?: boolean;\n readonly disabled?: boolean;\n readonly height?: number | string;\n readonly actions?: readonly CodeEditorAction[];\n readonly labels?: Partial<CodeEditorLabels>;\n readonly error?: string | null;\n readonly onDiagnostics?: (\n diagnostics: readonly CodeEditorDiagnostic[],\n ) => void;\n readonly toolbarStart?: ReactNode;\n readonly toolbarEnd?: ReactNode;\n}\n\nconst defaultLabels: CodeEditorLabels = {\n copy: 'Copy',\n copied: 'Copied',\n copyFailed: 'Copy failed',\n find: 'Search',\n format: 'Format',\n fullscreen: 'Enter fullscreen',\n exitFullscreen: 'Exit fullscreen',\n undo: 'Undo',\n redo: 'Redo',\n loading: 'Loading editor',\n valid: 'Validation passed',\n errors: count => `${count} validation error${count === 1 ? '' : 's'}`,\n lineColumn: (line, column) => `Ln ${line}, Col ${column}`,\n};\n\nconst defaultActions: readonly CodeEditorAction[] = [\n 'find',\n 'copy',\n 'format',\n 'undo',\n 'redo',\n 'fullscreen',\n];\n\nconst paths = {\n copy: 'M16 1H4a2 2 0 0 0-2 2v14h2V3h12zm3 4H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m0 16H8V7h11z',\n find: 'M9.5 3a6.5 6.5 0 1 0 3.98 11.64L19.85 21 21 19.85l-6.36-6.37A6.5 6.5 0 0 0 9.5 3m0 2a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9',\n format: 'M3 5h18v2H3zm0 6h12v2H3zm0 6h18v2H3z',\n fullscreen: 'M4 4h6v2H6v4H4zm10 0h6v6h-2V6h-4zM4 14h2v4h4v2H4zm14 0h2v6h-6v-2h4z',\n redo: 'M15 6V3l5 5-5 5v-3c-4 0-7 1-9 5 1-6 4-9 9-9',\n undo: 'M9 6V3L4 8l5 5v-3c4 0 7 1 9 5-1-6-4-9-9-9',\n} satisfies Record<CodeEditorAction, string>;\n\nconst ToolIcon: FC<{ readonly path: string }> = ({ path }) => (\n <Box\n component=\"svg\"\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n sx={{ width: 20, height: 20, fill: 'currentColor' }}\n >\n <path d={path} />\n </Box>\n);\n\nfunction markerSeverity(\n marker: Monaco.editor.IMarker,\n monaco: typeof Monaco,\n): CodeEditorDiagnosticSeverity {\n if (marker.severity === monaco.MarkerSeverity.Error) return 'error';\n if (marker.severity === monaco.MarkerSeverity.Warning) return 'warning';\n if (marker.severity === monaco.MarkerSeverity.Info) return 'info';\n return 'hint';\n}\n\nfunction mapDiagnostics(\n markers: readonly Monaco.editor.IMarker[],\n monaco: typeof Monaco,\n): readonly CodeEditorDiagnostic[] {\n return markers.map(marker => ({\n severity: markerSeverity(marker, monaco),\n message: marker.message,\n line: marker.startLineNumber,\n column: marker.startColumn,\n endLine: marker.endLineNumber,\n endColumn: marker.endColumn,\n ...(marker.code === undefined ? {} : { code: String(marker.code) }),\n }));\n}\n\nexport const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(\n function CodeEditor({\n value,\n onChange,\n onBlur,\n language,\n modelPath,\n ariaLabel,\n readOnly = false,\n disabled = false,\n height = 400,\n actions = defaultActions,\n labels: labelOverrides,\n error,\n onDiagnostics,\n toolbarStart,\n toolbarEnd,\n }, ref) {\n const theme = useTheme();\n const ownerId = useId();\n const editorRef = useRef<Monaco.editor.IStandaloneCodeEditor | null>(null);\n const disposablesRef = useRef<Monaco.IDisposable[]>([]);\n const diagnosticsRef = useRef<readonly CodeEditorDiagnostic[]>([]);\n const externalValueSyncRef = useRef(false);\n const pendingLocalValuesRef = useRef<string[]>([]);\n const modelPathRef = useRef(modelPath);\n const valueRef = useRef(value);\n const [monaco, setMonaco] = useState<typeof Monaco | null>(null);\n const [runtimeError, setRuntimeError] = useState<string>();\n const [position, setPosition] = useState({ lineNumber: 1, column: 1 });\n const [diagnosticCount, setDiagnosticCount] = useState(0);\n const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>('idle');\n const [fullscreen, setFullscreen] = useState(false);\n const labels = { ...defaultLabels, ...labelOverrides };\n valueRef.current = value;\n\n const synchronizeExternalValue = useCallback((\n editor: Monaco.editor.IStandaloneCodeEditor,\n nextValue: string,\n ): void => {\n const model = editor.getModel();\n if (!model) return;\n\n const pending = pendingLocalValuesRef.current;\n const acknowledgedIndex = pending.lastIndexOf(nextValue);\n if (acknowledgedIndex >= 0) {\n pending.splice(0, acknowledgedIndex + 1);\n return;\n }\n if (model.getValue() === nextValue) return;\n\n pending.length = 0;\n const selections = editor.getSelections();\n const scrollPosition = {\n scrollLeft: editor.getScrollLeft(),\n scrollTop: editor.getScrollTop(),\n };\n externalValueSyncRef.current = true;\n try {\n editor.pushUndoStop();\n const applied = editor.executeEdits(\n 'alauda.react-code-editor.external-value',\n [{\n range: model.getFullModelRange(),\n text: nextValue,\n forceMoveMarkers: true,\n }],\n selections ?? undefined,\n );\n if (!applied) model.setValue(nextValue);\n editor.pushUndoStop();\n if (selections) editor.setSelections(selections);\n editor.setScrollPosition(scrollPosition);\n } finally {\n externalValueSyncRef.current = false;\n }\n }, []);\n\n useEffect(() => {\n let active = true;\n let release: (() => void) | undefined;\n setMonaco(null);\n setRuntimeError(undefined);\n void loadMonacoRuntime()\n .then(instance => {\n if (!active) return;\n release = acquireModelOwnership(\n instance,\n ownerId,\n modelPath,\n language,\n );\n if (active) setMonaco(instance);\n else release();\n })\n .catch(errorValue => {\n if (active) {\n setRuntimeError(\n errorValue instanceof Error\n ? errorValue.message\n : String(errorValue),\n );\n }\n });\n return () => {\n active = false;\n release?.();\n };\n }, [language, modelPath, ownerId]);\n\n useEffect(() => () => {\n disposablesRef.current.forEach(disposable => disposable.dispose());\n disposablesRef.current = [];\n editorRef.current = null;\n }, []);\n\n useEffect(() => {\n if (modelPathRef.current !== modelPath) {\n modelPathRef.current = modelPath;\n pendingLocalValuesRef.current = [];\n }\n const editor = editorRef.current;\n if (editor) synchronizeExternalValue(editor, value);\n }, [modelPath, synchronizeExternalValue, value]);\n\n const find = async (): Promise<void> => {\n editorRef.current?.focus();\n await editorRef.current?.getAction('actions.find')?.run();\n };\n const format = async (): Promise<void> => {\n editorRef.current?.focus();\n await editorRef.current?.getAction('editor.action.formatDocument')?.run();\n };\n\n useImperativeHandle(ref, () => ({\n focus: () => editorRef.current?.focus(),\n find,\n format,\n undo: () => editorRef.current?.trigger('code-editor', 'undo', null),\n redo: () => editorRef.current?.trigger('code-editor', 'redo', null),\n validate: async () => diagnosticsRef.current,\n }));\n\n const onMount: OnMount = editor => {\n editorRef.current = editor;\n synchronizeExternalValue(editor, valueRef.current);\n disposablesRef.current.forEach(disposable => disposable.dispose());\n disposablesRef.current = [\n editor.onDidChangeCursorPosition(event => setPosition(event.position)),\n editor.onDidBlurEditorText(() => onBlur?.()),\n ];\n const currentPosition = editor.getPosition();\n if (currentPosition) setPosition(currentPosition);\n };\n\n const copy = async (): Promise<void> => {\n try {\n await navigator.clipboard.writeText(\n editorRef.current?.getModel()?.getValue() ?? valueRef.current,\n );\n setCopyState('copied');\n } catch {\n setCopyState('failed');\n }\n };\n\n const runAction = (action: CodeEditorAction): void => {\n if (action === 'find') void find();\n if (action === 'copy') void copy();\n if (action === 'format') void format();\n if (action === 'undo') {\n editorRef.current?.trigger('code-editor', 'undo', null);\n }\n if (action === 'redo') {\n editorRef.current?.trigger('code-editor', 'redo', null);\n }\n if (action === 'fullscreen') setFullscreen(current => !current);\n };\n\n const actionLabel = (action: CodeEditorAction): string => {\n if (action === 'copy' && copyState === 'copied') return labels.copied;\n if (action === 'copy' && copyState === 'failed') return labels.copyFailed;\n if (action === 'fullscreen' && fullscreen) return labels.exitFullscreen;\n return labels[action];\n };\n\n if (runtimeError) {\n return <Alert severity=\"error\" role=\"alert\">{runtimeError}</Alert>;\n }\n\n if (!monaco) {\n return (\n <Box\n role=\"status\"\n aria-label={labels.loading}\n sx={{ display: 'grid', height, minHeight: 160, placeItems: 'center' }}\n >\n <CircularProgress aria-hidden=\"true\" />\n </Box>\n );\n }\n\n return (\n <Box\n role=\"region\"\n aria-label={`${ariaLabel} editor`}\n sx={{\n position: fullscreen ? 'fixed' : 'relative',\n inset: fullscreen ? 0 : undefined,\n zIndex: fullscreen ? theme.zIndex.modal : undefined,\n display: 'flex',\n flexDirection: 'column',\n height: fullscreen ? '100dvh' : height,\n minHeight: 160,\n overflow: 'hidden',\n bgcolor: 'background.paper',\n border: 1,\n borderColor: error ? 'error.main' : 'divider',\n borderRadius: fullscreen ? 0 : 1,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n minHeight: 40,\n px: 1,\n borderBottom: 1,\n borderColor: 'divider',\n }}\n >\n {toolbarStart}\n <Box sx={{ flex: 1 }} />\n {actions.map(action => (\n <Tooltip key={action} title={actionLabel(action)}>\n <span>\n <IconButton\n aria-label={actionLabel(action)}\n aria-pressed={action === 'fullscreen' ? fullscreen : undefined}\n disabled={disabled || (\n readOnly && ['format', 'undo', 'redo'].includes(action)\n )}\n size=\"small\"\n onClick={() => runAction(action)}\n >\n <ToolIcon path={paths[action]} />\n </IconButton>\n </span>\n </Tooltip>\n ))}\n {toolbarEnd}\n </Box>\n <Box sx={{ flex: '1 1 auto', minHeight: 0, overflow: 'hidden' }}>\n <Editor\n height=\"100%\"\n language={language}\n path={modelPath}\n theme={theme.palette.mode === 'dark' ? 'vs-dark' : 'vs'}\n defaultValue={value}\n keepCurrentModel\n onMount={onMount}\n onChange={nextValue => {\n if (externalValueSyncRef.current) return;\n const normalized = nextValue ?? '';\n const pending = pendingLocalValuesRef.current;\n if (pending.at(-1) !== normalized) {\n pending.push(normalized);\n if (pending.length > 64) {\n pending.splice(0, pending.length - 64);\n }\n }\n onChange(normalized);\n }}\n onValidate={markers => {\n const diagnostics = mapDiagnostics(markers, monaco);\n diagnosticsRef.current = diagnostics;\n setDiagnosticCount(diagnostics.filter(item => (\n item.severity === 'error'\n )).length);\n onDiagnostics?.(diagnostics);\n }}\n options={{\n ariaLabel,\n automaticLayout: true,\n bracketPairColorization: { enabled: true },\n folding: true,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',\n fontSize: 13,\n formatOnPaste: true,\n insertSpaces: true,\n lineHeight: 22,\n minimap: { enabled: false },\n occurrencesHighlight: 'off',\n padding: { top: 12, bottom: 12 },\n readOnly: readOnly || disabled,\n renderValidationDecorations: 'on',\n scrollBeyondLastLine: false,\n tabSize: 2,\n }}\n />\n </Box>\n <Box\n aria-live=\"polite\"\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n gap: 2,\n minHeight: 28,\n px: 1.5,\n py: 0.5,\n borderTop: 1,\n borderColor: 'divider',\n }}\n >\n <Typography variant=\"caption\">{language.toUpperCase()}</Typography>\n <Typography\n variant=\"caption\"\n color={error || diagnosticCount ? 'error' : 'text.secondary'}\n >\n {error ?? (\n diagnosticCount ? labels.errors(diagnosticCount) : labels.valid\n )}\n </Typography>\n <Typography variant=\"caption\">\n {labels.lineColumn(position.lineNumber, position.column)}\n </Typography>\n </Box>\n </Box>\n );\n },\n);\n"],"mappings":"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"}
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as acquireModelOwnership, r as loadMonacoRuntime, t as CodeEditor } from "./chunks/CodeEditor-CEfhCmSA.js";
1
+ import { n as acquireModelOwnership, r as loadMonacoRuntime, t as CodeEditor } from "./chunks/CodeEditor-BeDnriRO.js";
2
2
  import { DiffEditor } from "@monaco-editor/react";
3
3
  import Alert from "@mui/material/Alert";
4
4
  import Box from "@mui/material/Box";
@@ -89,6 +89,7 @@ function DiffCodeEditor({ originalValue, value, onChange, language, originalMode
89
89
  ariaLabel,
90
90
  automaticLayout: true,
91
91
  minimap: { enabled: false },
92
+ occurrencesHighlight: "off",
92
93
  originalEditable: false,
93
94
  readOnly,
94
95
  renderSideBySide: true,
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/DiffCodeEditor.tsx"],"sourcesContent":["import { DiffEditor } from '@monaco-editor/react';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport { useTheme } from '@mui/material/styles';\nimport { useEffect, useId, useRef, useState } from 'react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport type { CodeEditorLanguage } from './CodeEditor';\nimport { loadMonacoRuntime } from './runtime/loadMonaco';\nimport { acquireModelOwnership } from './runtime/modelOwnership';\n\nexport interface DiffCodeEditorProps {\n readonly originalValue: string;\n readonly value: string;\n readonly onChange?: (value: string) => void;\n readonly language: CodeEditorLanguage;\n readonly originalModelPath: string;\n readonly modelPath: string;\n readonly ariaLabel: string;\n readonly readOnly?: boolean;\n readonly height?: number | string;\n}\n\nexport function DiffCodeEditor({\n originalValue,\n value,\n onChange,\n language,\n originalModelPath,\n modelPath,\n ariaLabel,\n readOnly = false,\n height = 400,\n}: DiffCodeEditorProps) {\n const theme = useTheme();\n const ownerId = useId();\n const contentListenerRef = useRef<Monaco.IDisposable | null>(null);\n const valueRef = useRef(value);\n const [ready, setReady] = useState(false);\n const [runtimeError, setRuntimeError] = useState<string>();\n valueRef.current = value;\n\n useEffect(() => {\n let active = true;\n const releases: Array<() => void> = [];\n setReady(false);\n setRuntimeError(undefined);\n void loadMonacoRuntime()\n .then(monaco => {\n if (!active) return;\n if (originalModelPath === modelPath) {\n throw new Error('Diff editor model paths must be different');\n }\n releases.push(acquireModelOwnership(\n monaco,\n `${ownerId}:original`,\n originalModelPath,\n language,\n ));\n releases.push(acquireModelOwnership(\n monaco,\n `${ownerId}:modified`,\n modelPath,\n language,\n ));\n if (active) setReady(true);\n else releases.splice(0).reverse().forEach(release => release());\n })\n .catch(errorValue => {\n releases.splice(0).reverse().forEach(release => release());\n if (active) {\n setRuntimeError(\n errorValue instanceof Error\n ? errorValue.message\n : String(errorValue),\n );\n }\n });\n return () => {\n active = false;\n contentListenerRef.current?.dispose();\n contentListenerRef.current = null;\n releases.splice(0).reverse().forEach(release => release());\n };\n }, [language, modelPath, originalModelPath, ownerId]);\n\n if (runtimeError) {\n return <Alert severity=\"error\" role=\"alert\">{runtimeError}</Alert>;\n }\n\n if (!ready) {\n return (\n <Box\n role=\"status\"\n aria-label={`Loading ${ariaLabel}`}\n sx={{ display: 'grid', height, minHeight: 160, placeItems: 'center' }}\n >\n <CircularProgress aria-hidden=\"true\" />\n </Box>\n );\n }\n\n return (\n <Box\n role=\"region\"\n aria-label={ariaLabel}\n sx={{ height, minHeight: 160, overflow: 'hidden' }}\n >\n <DiffEditor\n height=\"100%\"\n language={language}\n original={originalValue}\n modified={value}\n originalModelPath={originalModelPath}\n modifiedModelPath={modelPath}\n theme={theme.palette.mode === 'dark' ? 'vs-dark' : 'vs'}\n keepCurrentOriginalModel\n keepCurrentModifiedModel\n onMount={editor => {\n contentListenerRef.current?.dispose();\n const modifiedEditor = editor.getModifiedEditor();\n contentListenerRef.current = modifiedEditor\n .onDidChangeModelContent(() => {\n const nextValue = modifiedEditor.getValue();\n if (nextValue !== valueRef.current) onChange?.(nextValue);\n });\n }}\n options={{\n ariaLabel,\n automaticLayout: true,\n minimap: { enabled: false },\n originalEditable: false,\n readOnly,\n renderSideBySide: true,\n scrollBeyondLastLine: false,\n }}\n />\n </Box>\n );\n}\n"],"mappings":";;;;;;;;;AAwBA,SAAgB,eAAe,EAC7B,eACA,OACA,UACA,UACA,mBACA,WACA,WACA,WAAW,OACX,SAAS,OACa;CACtB,MAAM,QAAQ,SAAS;CACvB,MAAM,UAAU,MAAM;CACtB,MAAM,qBAAqB,OAAkC,IAAI;CACjE,MAAM,WAAW,OAAO,KAAK;CAC7B,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK;CACxC,MAAM,CAAC,cAAc,mBAAmB,SAAiB;CACzD,SAAS,UAAU;CAEnB,gBAAgB;EACd,IAAI,SAAS;EACb,MAAM,WAA8B,CAAC;EACrC,SAAS,KAAK;EACd,gBAAgB,KAAA,CAAS;EACzB,kBAAuB,CAAC,CACrB,MAAK,WAAU;GACd,IAAI,CAAC,QAAQ;GACb,IAAI,sBAAsB,WACxB,MAAM,IAAI,MAAM,2CAA2C;GAE7D,SAAS,KAAK,sBACZ,QACA,GAAG,QAAQ,YACX,mBACA,QACF,CAAC;GACD,SAAS,KAAK,sBACZ,QACA,GAAG,QAAQ,YACX,WACA,QACF,CAAC;GACD,IAAI,QAAQ,SAAS,IAAI;QACpB,SAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAQ,YAAW,QAAQ,CAAC;EAChE,CAAC,CAAC,CACD,OAAM,eAAc;GACnB,SAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAQ,YAAW,QAAQ,CAAC;GACzD,IAAI,QACF,gBACE,sBAAsB,QAClB,WAAW,UACX,OAAO,UAAU,CACvB;EAEJ,CAAC;EACH,aAAa;GACX,SAAS;GACT,mBAAmB,SAAS,QAAQ;GACpC,mBAAmB,UAAU;GAC7B,SAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAQ,YAAW,QAAQ,CAAC;EAC3D;CACF,GAAG;EAAC;EAAU;EAAW;EAAmB;CAAO,CAAC;CAEpD,IAAI,cACF,OAAO,oBAAC,OAAD;EAAO,UAAS;EAAQ,MAAK;YAAS;CAAoB,CAAA;CAGnE,IAAI,CAAC,OACH,OACE,oBAAC,KAAD;EACE,MAAK;EACL,cAAY,WAAW;EACvB,IAAI;GAAE,SAAS;GAAQ;GAAQ,WAAW;GAAK,YAAY;EAAS;YAEpE,oBAAC,kBAAD,EAAkB,eAAY,OAAQ,CAAA;CACnC,CAAA;CAIT,OACE,oBAAC,KAAD;EACE,MAAK;EACL,cAAY;EACZ,IAAI;GAAE;GAAQ,WAAW;GAAK,UAAU;EAAS;YAEjD,oBAAC,YAAD;GACE,QAAO;GACG;GACV,UAAU;GACV,UAAU;GACS;GACnB,mBAAmB;GACnB,OAAO,MAAM,QAAQ,SAAS,SAAS,YAAY;GACnD,0BAAA;GACA,0BAAA;GACA,UAAS,WAAU;IACjB,mBAAmB,SAAS,QAAQ;IACpC,MAAM,iBAAiB,OAAO,kBAAkB;IAChD,mBAAmB,UAAU,eAC1B,8BAA8B;KAC7B,MAAM,YAAY,eAAe,SAAS;KAC1C,IAAI,cAAc,SAAS,SAAS,WAAW,SAAS;IAC1D,CAAC;GACL;GACA,SAAS;IACP;IACA,iBAAiB;IACjB,SAAS,EAAE,SAAS,MAAM;IAC1B,kBAAkB;IAClB;IACA,kBAAkB;IAClB,sBAAsB;GACxB;EACD,CAAA;CACE,CAAA;AAET"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/DiffCodeEditor.tsx"],"sourcesContent":["import { DiffEditor } from '@monaco-editor/react';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport { useTheme } from '@mui/material/styles';\nimport { useEffect, useId, useRef, useState } from 'react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport type { CodeEditorLanguage } from './CodeEditor';\nimport { loadMonacoRuntime } from './runtime/loadMonaco';\nimport { acquireModelOwnership } from './runtime/modelOwnership';\n\nexport interface DiffCodeEditorProps {\n readonly originalValue: string;\n readonly value: string;\n readonly onChange?: (value: string) => void;\n readonly language: CodeEditorLanguage;\n readonly originalModelPath: string;\n readonly modelPath: string;\n readonly ariaLabel: string;\n readonly readOnly?: boolean;\n readonly height?: number | string;\n}\n\nexport function DiffCodeEditor({\n originalValue,\n value,\n onChange,\n language,\n originalModelPath,\n modelPath,\n ariaLabel,\n readOnly = false,\n height = 400,\n}: DiffCodeEditorProps) {\n const theme = useTheme();\n const ownerId = useId();\n const contentListenerRef = useRef<Monaco.IDisposable | null>(null);\n const valueRef = useRef(value);\n const [ready, setReady] = useState(false);\n const [runtimeError, setRuntimeError] = useState<string>();\n valueRef.current = value;\n\n useEffect(() => {\n let active = true;\n const releases: Array<() => void> = [];\n setReady(false);\n setRuntimeError(undefined);\n void loadMonacoRuntime()\n .then(monaco => {\n if (!active) return;\n if (originalModelPath === modelPath) {\n throw new Error('Diff editor model paths must be different');\n }\n releases.push(acquireModelOwnership(\n monaco,\n `${ownerId}:original`,\n originalModelPath,\n language,\n ));\n releases.push(acquireModelOwnership(\n monaco,\n `${ownerId}:modified`,\n modelPath,\n language,\n ));\n if (active) setReady(true);\n else releases.splice(0).reverse().forEach(release => release());\n })\n .catch(errorValue => {\n releases.splice(0).reverse().forEach(release => release());\n if (active) {\n setRuntimeError(\n errorValue instanceof Error\n ? errorValue.message\n : String(errorValue),\n );\n }\n });\n return () => {\n active = false;\n contentListenerRef.current?.dispose();\n contentListenerRef.current = null;\n releases.splice(0).reverse().forEach(release => release());\n };\n }, [language, modelPath, originalModelPath, ownerId]);\n\n if (runtimeError) {\n return <Alert severity=\"error\" role=\"alert\">{runtimeError}</Alert>;\n }\n\n if (!ready) {\n return (\n <Box\n role=\"status\"\n aria-label={`Loading ${ariaLabel}`}\n sx={{ display: 'grid', height, minHeight: 160, placeItems: 'center' }}\n >\n <CircularProgress aria-hidden=\"true\" />\n </Box>\n );\n }\n\n return (\n <Box\n role=\"region\"\n aria-label={ariaLabel}\n sx={{ height, minHeight: 160, overflow: 'hidden' }}\n >\n <DiffEditor\n height=\"100%\"\n language={language}\n original={originalValue}\n modified={value}\n originalModelPath={originalModelPath}\n modifiedModelPath={modelPath}\n theme={theme.palette.mode === 'dark' ? 'vs-dark' : 'vs'}\n keepCurrentOriginalModel\n keepCurrentModifiedModel\n onMount={editor => {\n contentListenerRef.current?.dispose();\n const modifiedEditor = editor.getModifiedEditor();\n contentListenerRef.current = modifiedEditor\n .onDidChangeModelContent(() => {\n const nextValue = modifiedEditor.getValue();\n if (nextValue !== valueRef.current) onChange?.(nextValue);\n });\n }}\n options={{\n ariaLabel,\n automaticLayout: true,\n minimap: { enabled: false },\n occurrencesHighlight: 'off',\n originalEditable: false,\n readOnly,\n renderSideBySide: true,\n scrollBeyondLastLine: false,\n }}\n />\n </Box>\n );\n}\n"],"mappings":";;;;;;;;;AAwBA,SAAgB,eAAe,EAC7B,eACA,OACA,UACA,UACA,mBACA,WACA,WACA,WAAW,OACX,SAAS,OACa;CACtB,MAAM,QAAQ,SAAS;CACvB,MAAM,UAAU,MAAM;CACtB,MAAM,qBAAqB,OAAkC,IAAI;CACjE,MAAM,WAAW,OAAO,KAAK;CAC7B,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK;CACxC,MAAM,CAAC,cAAc,mBAAmB,SAAiB;CACzD,SAAS,UAAU;CAEnB,gBAAgB;EACd,IAAI,SAAS;EACb,MAAM,WAA8B,CAAC;EACrC,SAAS,KAAK;EACd,gBAAgB,KAAA,CAAS;EACzB,kBAAuB,CAAC,CACrB,MAAK,WAAU;GACd,IAAI,CAAC,QAAQ;GACb,IAAI,sBAAsB,WACxB,MAAM,IAAI,MAAM,2CAA2C;GAE7D,SAAS,KAAK,sBACZ,QACA,GAAG,QAAQ,YACX,mBACA,QACF,CAAC;GACD,SAAS,KAAK,sBACZ,QACA,GAAG,QAAQ,YACX,WACA,QACF,CAAC;GACD,IAAI,QAAQ,SAAS,IAAI;QACpB,SAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAQ,YAAW,QAAQ,CAAC;EAChE,CAAC,CAAC,CACD,OAAM,eAAc;GACnB,SAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAQ,YAAW,QAAQ,CAAC;GACzD,IAAI,QACF,gBACE,sBAAsB,QAClB,WAAW,UACX,OAAO,UAAU,CACvB;EAEJ,CAAC;EACH,aAAa;GACX,SAAS;GACT,mBAAmB,SAAS,QAAQ;GACpC,mBAAmB,UAAU;GAC7B,SAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAQ,YAAW,QAAQ,CAAC;EAC3D;CACF,GAAG;EAAC;EAAU;EAAW;EAAmB;CAAO,CAAC;CAEpD,IAAI,cACF,OAAO,oBAAC,OAAD;EAAO,UAAS;EAAQ,MAAK;YAAS;CAAoB,CAAA;CAGnE,IAAI,CAAC,OACH,OACE,oBAAC,KAAD;EACE,MAAK;EACL,cAAY,WAAW;EACvB,IAAI;GAAE,SAAS;GAAQ;GAAQ,WAAW;GAAK,YAAY;EAAS;YAEpE,oBAAC,kBAAD,EAAkB,eAAY,OAAQ,CAAA;CACnC,CAAA;CAIT,OACE,oBAAC,KAAD;EACE,MAAK;EACL,cAAY;EACZ,IAAI;GAAE;GAAQ,WAAW;GAAK,UAAU;EAAS;YAEjD,oBAAC,YAAD;GACE,QAAO;GACG;GACV,UAAU;GACV,UAAU;GACS;GACnB,mBAAmB;GACnB,OAAO,MAAM,QAAQ,SAAS,SAAS,YAAY;GACnD,0BAAA;GACA,0BAAA;GACA,UAAS,WAAU;IACjB,mBAAmB,SAAS,QAAQ;IACpC,MAAM,iBAAiB,OAAO,kBAAkB;IAChD,mBAAmB,UAAU,eAC1B,8BAA8B;KAC7B,MAAM,YAAY,eAAe,SAAS;KAC1C,IAAI,cAAc,SAAS,SAAS,WAAW,SAAS;IAC1D,CAAC;GACL;GACA,SAAS;IACP;IACA,iBAAiB;IACjB,SAAS,EAAE,SAAS,MAAM;IAC1B,sBAAsB;IACtB,kBAAkB;IAClB;IACA,kBAAkB;IAClB,sBAAsB;GACxB;EACD,CAAA;CACE,CAAA;AAET"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alauda/react-code-editor",
3
- "version": "0.1.0-next.20260812.1786527360",
3
+ "version": "0.1.0-next.20260817.1786952747",
4
4
  "description": "React Monaco code editor with schema-aware YAML support.",
5
5
  "type": "module",
6
6
  "main": "./index.js",
package/yaml/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { i as getSharedRuntimeState, r as loadMonacoRuntime, t as CodeEditor } from "../chunks/CodeEditor-CEfhCmSA.js";
1
+ import { i as getSharedRuntimeState, r as loadMonacoRuntime, t as CodeEditor } from "../chunks/CodeEditor-BeDnriRO.js";
2
2
  import Alert from "@mui/material/Alert";
3
3
  import Box from "@mui/material/Box";
4
4
  import CircularProgress from "@mui/material/CircularProgress";
@@ -1 +0,0 @@
1
- {"version":3,"file":"CodeEditor-CEfhCmSA.js","names":[],"sources":["../../../src/monacoEnvironment.ts","../../../src/runtime/runtimeState.ts","../../../src/runtime/loadMonaco.ts","../../../src/runtime/modelOwnership.ts","../../../src/CodeEditor.tsx"],"sourcesContent":["declare global {\n interface Window {\n MonacoEnvironment: {\n getWorker: (_moduleId: string, label: string) => Worker;\n };\n }\n}\n\nexport function configureMonacoEnvironment(): void {\n if (typeof window === 'undefined') return;\n const existing = Reflect.get(window, 'MonacoEnvironment') as\n | { readonly getWorker?: unknown }\n | undefined;\n if (typeof existing?.getWorker === 'function') return;\n\n window.MonacoEnvironment = {\n getWorker: (_moduleId, label) => {\n if (label === 'yaml') {\n return new Worker(new URL('./yaml/yaml.worker.js', import.meta.url));\n }\n if (label === 'json') {\n return new Worker(new URL(\n 'monaco-editor/esm/vs/language/json/json.worker.js',\n import.meta.url,\n ));\n }\n return new Worker(new URL(\n 'monaco-editor/esm/vs/editor/editor.worker.js',\n import.meta.url,\n ));\n },\n };\n}\n","import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nexport interface SharedCodeEditorRuntimeState {\n monaco?: typeof Monaco;\n monacoPromise?: Promise<typeof Monaco>;\n models?: Map<string, unknown>;\n yaml?: unknown;\n}\n\nconst runtimeKey = Symbol.for('alauda.react-code-editor.runtime');\n\nexport function getSharedRuntimeState(): SharedCodeEditorRuntimeState {\n const target = globalThis as typeof globalThis & {\n [runtimeKey]?: SharedCodeEditorRuntimeState;\n };\n target[runtimeKey] ??= {};\n return target[runtimeKey];\n}\n","import { loader } from '@monaco-editor/react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { configureMonacoEnvironment } from '../monacoEnvironment';\nimport { getSharedRuntimeState } from './runtimeState';\n\nexport function loadMonacoRuntime(): Promise<typeof Monaco> {\n const runtime = getSharedRuntimeState();\n if (runtime.monacoPromise) return runtime.monacoPromise;\n const promise = (async () => {\n configureMonacoEnvironment();\n const monaco = await import(\n 'monaco-editor/esm/vs/editor/editor.main.js'\n );\n loader.config({ monaco });\n runtime.monaco = monaco;\n return monaco;\n })();\n runtime.monacoPromise = promise;\n void promise.catch(() => {\n if (runtime.monacoPromise === promise) runtime.monacoPromise = undefined;\n });\n return promise;\n}\n","import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { getSharedRuntimeState } from './runtimeState';\n\ninterface ModelOwnership {\n readonly language: string;\n readonly owners: Set<string>;\n readonly uri: Monaco.Uri;\n readonly ownedByPackage: boolean;\n}\n\nfunction ownershipRegistry(): Map<string, ModelOwnership> {\n const runtime = getSharedRuntimeState();\n runtime.models ??= new Map();\n return runtime.models as Map<string, ModelOwnership>;\n}\n\nexport function acquireModelOwnership(\n monaco: typeof Monaco,\n ownerId: string,\n modelPath: string,\n language: string,\n): () => void {\n const registry = ownershipRegistry();\n const existing = registry.get(modelPath);\n if (existing && existing.language !== language) {\n throw new Error(\n `Conflicting editor languages for ${modelPath}: `\n + `${existing.language} and ${language}`,\n );\n }\n\n const ownership = existing ?? (() => {\n const uri = monaco.Uri.parse(modelPath);\n return {\n language,\n owners: new Set<string>(),\n uri,\n ownedByPackage: !monaco.editor.getModel(uri),\n } satisfies ModelOwnership;\n })();\n ownership.owners.add(ownerId);\n registry.set(modelPath, ownership);\n\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n ownership.owners.delete(ownerId);\n if (ownership.owners.size > 0) return;\n registry.delete(modelPath);\n if (ownership.ownedByPackage) {\n monaco.editor.getModel(ownership.uri)?.dispose();\n }\n };\n}\n","import Editor, { type OnMount } from '@monaco-editor/react';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport { useTheme } from '@mui/material/styles';\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n type FC,\n type ReactNode,\n} from 'react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { loadMonacoRuntime } from './runtime/loadMonaco';\nimport { acquireModelOwnership } from './runtime/modelOwnership';\n\nexport type CodeEditorLanguage =\n | 'json'\n | 'markdown'\n | 'plaintext'\n | 'yaml';\n\nexport type CodeEditorAction =\n | 'copy'\n | 'find'\n | 'format'\n | 'fullscreen'\n | 'redo'\n | 'undo';\n\nexport type CodeEditorDiagnosticSeverity =\n | 'error'\n | 'warning'\n | 'info'\n | 'hint';\n\nexport interface CodeEditorDiagnostic {\n readonly severity: CodeEditorDiagnosticSeverity;\n readonly message: string;\n readonly line: number;\n readonly column: number;\n readonly endLine: number;\n readonly endColumn: number;\n readonly code?: string;\n}\n\nexport interface CodeEditorLabels {\n readonly copy: string;\n readonly copied: string;\n readonly copyFailed: string;\n readonly find: string;\n readonly format: string;\n readonly fullscreen: string;\n readonly exitFullscreen: string;\n readonly undo: string;\n readonly redo: string;\n readonly loading: string;\n readonly valid: string;\n readonly errors: (count: number) => string;\n readonly lineColumn: (line: number, column: number) => string;\n}\n\nexport interface CodeEditorHandle {\n focus(): void;\n find(): Promise<void>;\n format(): Promise<void>;\n undo(): void;\n redo(): void;\n validate(): Promise<readonly CodeEditorDiagnostic[]>;\n}\n\nexport interface CodeEditorProps {\n readonly value: string;\n readonly onChange: (value: string) => void;\n readonly onBlur?: () => void;\n readonly language: CodeEditorLanguage;\n readonly modelPath: string;\n readonly ariaLabel: string;\n readonly readOnly?: boolean;\n readonly disabled?: boolean;\n readonly height?: number | string;\n readonly actions?: readonly CodeEditorAction[];\n readonly labels?: Partial<CodeEditorLabels>;\n readonly error?: string | null;\n readonly onDiagnostics?: (\n diagnostics: readonly CodeEditorDiagnostic[],\n ) => void;\n readonly toolbarStart?: ReactNode;\n readonly toolbarEnd?: ReactNode;\n}\n\nconst defaultLabels: CodeEditorLabels = {\n copy: 'Copy',\n copied: 'Copied',\n copyFailed: 'Copy failed',\n find: 'Search',\n format: 'Format',\n fullscreen: 'Enter fullscreen',\n exitFullscreen: 'Exit fullscreen',\n undo: 'Undo',\n redo: 'Redo',\n loading: 'Loading editor',\n valid: 'Validation passed',\n errors: count => `${count} validation error${count === 1 ? '' : 's'}`,\n lineColumn: (line, column) => `Ln ${line}, Col ${column}`,\n};\n\nconst defaultActions: readonly CodeEditorAction[] = [\n 'find',\n 'copy',\n 'format',\n 'undo',\n 'redo',\n 'fullscreen',\n];\n\nconst paths = {\n copy: 'M16 1H4a2 2 0 0 0-2 2v14h2V3h12zm3 4H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m0 16H8V7h11z',\n find: 'M9.5 3a6.5 6.5 0 1 0 3.98 11.64L19.85 21 21 19.85l-6.36-6.37A6.5 6.5 0 0 0 9.5 3m0 2a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9',\n format: 'M3 5h18v2H3zm0 6h12v2H3zm0 6h18v2H3z',\n fullscreen: 'M4 4h6v2H6v4H4zm10 0h6v6h-2V6h-4zM4 14h2v4h4v2H4zm14 0h2v6h-6v-2h4z',\n redo: 'M15 6V3l5 5-5 5v-3c-4 0-7 1-9 5 1-6 4-9 9-9',\n undo: 'M9 6V3L4 8l5 5v-3c4 0 7 1 9 5-1-6-4-9-9-9',\n} satisfies Record<CodeEditorAction, string>;\n\nconst ToolIcon: FC<{ readonly path: string }> = ({ path }) => (\n <Box\n component=\"svg\"\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n sx={{ width: 20, height: 20, fill: 'currentColor' }}\n >\n <path d={path} />\n </Box>\n);\n\nfunction markerSeverity(\n marker: Monaco.editor.IMarker,\n monaco: typeof Monaco,\n): CodeEditorDiagnosticSeverity {\n if (marker.severity === monaco.MarkerSeverity.Error) return 'error';\n if (marker.severity === monaco.MarkerSeverity.Warning) return 'warning';\n if (marker.severity === monaco.MarkerSeverity.Info) return 'info';\n return 'hint';\n}\n\nfunction mapDiagnostics(\n markers: readonly Monaco.editor.IMarker[],\n monaco: typeof Monaco,\n): readonly CodeEditorDiagnostic[] {\n return markers.map(marker => ({\n severity: markerSeverity(marker, monaco),\n message: marker.message,\n line: marker.startLineNumber,\n column: marker.startColumn,\n endLine: marker.endLineNumber,\n endColumn: marker.endColumn,\n ...(marker.code === undefined ? {} : { code: String(marker.code) }),\n }));\n}\n\nexport const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(\n function CodeEditor({\n value,\n onChange,\n onBlur,\n language,\n modelPath,\n ariaLabel,\n readOnly = false,\n disabled = false,\n height = 400,\n actions = defaultActions,\n labels: labelOverrides,\n error,\n onDiagnostics,\n toolbarStart,\n toolbarEnd,\n }, ref) {\n const theme = useTheme();\n const ownerId = useId();\n const editorRef = useRef<Monaco.editor.IStandaloneCodeEditor | null>(null);\n const disposablesRef = useRef<Monaco.IDisposable[]>([]);\n const diagnosticsRef = useRef<readonly CodeEditorDiagnostic[]>([]);\n const externalValueSyncRef = useRef(false);\n const pendingLocalValuesRef = useRef<string[]>([]);\n const modelPathRef = useRef(modelPath);\n const valueRef = useRef(value);\n const [monaco, setMonaco] = useState<typeof Monaco | null>(null);\n const [runtimeError, setRuntimeError] = useState<string>();\n const [position, setPosition] = useState({ lineNumber: 1, column: 1 });\n const [diagnosticCount, setDiagnosticCount] = useState(0);\n const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>('idle');\n const [fullscreen, setFullscreen] = useState(false);\n const labels = { ...defaultLabels, ...labelOverrides };\n valueRef.current = value;\n\n const synchronizeExternalValue = useCallback((\n editor: Monaco.editor.IStandaloneCodeEditor,\n nextValue: string,\n ): void => {\n const model = editor.getModel();\n if (!model) return;\n\n const pending = pendingLocalValuesRef.current;\n const acknowledgedIndex = pending.lastIndexOf(nextValue);\n if (acknowledgedIndex >= 0) {\n pending.splice(0, acknowledgedIndex + 1);\n return;\n }\n if (model.getValue() === nextValue) return;\n\n pending.length = 0;\n const selections = editor.getSelections();\n const scrollPosition = {\n scrollLeft: editor.getScrollLeft(),\n scrollTop: editor.getScrollTop(),\n };\n externalValueSyncRef.current = true;\n try {\n editor.pushUndoStop();\n const applied = editor.executeEdits(\n 'alauda.react-code-editor.external-value',\n [{\n range: model.getFullModelRange(),\n text: nextValue,\n forceMoveMarkers: true,\n }],\n selections ?? undefined,\n );\n if (!applied) model.setValue(nextValue);\n editor.pushUndoStop();\n if (selections) editor.setSelections(selections);\n editor.setScrollPosition(scrollPosition);\n } finally {\n externalValueSyncRef.current = false;\n }\n }, []);\n\n useEffect(() => {\n let active = true;\n let release: (() => void) | undefined;\n setMonaco(null);\n setRuntimeError(undefined);\n void loadMonacoRuntime()\n .then(instance => {\n if (!active) return;\n release = acquireModelOwnership(\n instance,\n ownerId,\n modelPath,\n language,\n );\n if (active) setMonaco(instance);\n else release();\n })\n .catch(errorValue => {\n if (active) {\n setRuntimeError(\n errorValue instanceof Error\n ? errorValue.message\n : String(errorValue),\n );\n }\n });\n return () => {\n active = false;\n release?.();\n };\n }, [language, modelPath, ownerId]);\n\n useEffect(() => () => {\n disposablesRef.current.forEach(disposable => disposable.dispose());\n disposablesRef.current = [];\n editorRef.current = null;\n }, []);\n\n useEffect(() => {\n if (modelPathRef.current !== modelPath) {\n modelPathRef.current = modelPath;\n pendingLocalValuesRef.current = [];\n }\n const editor = editorRef.current;\n if (editor) synchronizeExternalValue(editor, value);\n }, [modelPath, synchronizeExternalValue, value]);\n\n const find = async (): Promise<void> => {\n editorRef.current?.focus();\n await editorRef.current?.getAction('actions.find')?.run();\n };\n const format = async (): Promise<void> => {\n editorRef.current?.focus();\n await editorRef.current?.getAction('editor.action.formatDocument')?.run();\n };\n\n useImperativeHandle(ref, () => ({\n focus: () => editorRef.current?.focus(),\n find,\n format,\n undo: () => editorRef.current?.trigger('code-editor', 'undo', null),\n redo: () => editorRef.current?.trigger('code-editor', 'redo', null),\n validate: async () => diagnosticsRef.current,\n }));\n\n const onMount: OnMount = editor => {\n editorRef.current = editor;\n synchronizeExternalValue(editor, valueRef.current);\n disposablesRef.current.forEach(disposable => disposable.dispose());\n disposablesRef.current = [\n editor.onDidChangeCursorPosition(event => setPosition(event.position)),\n editor.onDidBlurEditorText(() => onBlur?.()),\n ];\n const currentPosition = editor.getPosition();\n if (currentPosition) setPosition(currentPosition);\n };\n\n const copy = async (): Promise<void> => {\n try {\n await navigator.clipboard.writeText(\n editorRef.current?.getModel()?.getValue() ?? valueRef.current,\n );\n setCopyState('copied');\n } catch {\n setCopyState('failed');\n }\n };\n\n const runAction = (action: CodeEditorAction): void => {\n if (action === 'find') void find();\n if (action === 'copy') void copy();\n if (action === 'format') void format();\n if (action === 'undo') {\n editorRef.current?.trigger('code-editor', 'undo', null);\n }\n if (action === 'redo') {\n editorRef.current?.trigger('code-editor', 'redo', null);\n }\n if (action === 'fullscreen') setFullscreen(current => !current);\n };\n\n const actionLabel = (action: CodeEditorAction): string => {\n if (action === 'copy' && copyState === 'copied') return labels.copied;\n if (action === 'copy' && copyState === 'failed') return labels.copyFailed;\n if (action === 'fullscreen' && fullscreen) return labels.exitFullscreen;\n return labels[action];\n };\n\n if (runtimeError) {\n return <Alert severity=\"error\" role=\"alert\">{runtimeError}</Alert>;\n }\n\n if (!monaco) {\n return (\n <Box\n role=\"status\"\n aria-label={labels.loading}\n sx={{ display: 'grid', height, minHeight: 160, placeItems: 'center' }}\n >\n <CircularProgress aria-hidden=\"true\" />\n </Box>\n );\n }\n\n return (\n <Box\n role=\"region\"\n aria-label={`${ariaLabel} editor`}\n sx={{\n position: fullscreen ? 'fixed' : 'relative',\n inset: fullscreen ? 0 : undefined,\n zIndex: fullscreen ? theme.zIndex.modal : undefined,\n display: 'flex',\n flexDirection: 'column',\n height: fullscreen ? '100dvh' : height,\n minHeight: 160,\n overflow: 'hidden',\n bgcolor: 'background.paper',\n border: 1,\n borderColor: error ? 'error.main' : 'divider',\n borderRadius: fullscreen ? 0 : 1,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n minHeight: 40,\n px: 1,\n borderBottom: 1,\n borderColor: 'divider',\n }}\n >\n {toolbarStart}\n <Box sx={{ flex: 1 }} />\n {actions.map(action => (\n <Tooltip key={action} title={actionLabel(action)}>\n <span>\n <IconButton\n aria-label={actionLabel(action)}\n aria-pressed={action === 'fullscreen' ? fullscreen : undefined}\n disabled={disabled || (\n readOnly && ['format', 'undo', 'redo'].includes(action)\n )}\n size=\"small\"\n onClick={() => runAction(action)}\n >\n <ToolIcon path={paths[action]} />\n </IconButton>\n </span>\n </Tooltip>\n ))}\n {toolbarEnd}\n </Box>\n <Box sx={{ flex: '1 1 auto', minHeight: 0, overflow: 'hidden' }}>\n <Editor\n height=\"100%\"\n language={language}\n path={modelPath}\n theme={theme.palette.mode === 'dark' ? 'vs-dark' : 'vs'}\n defaultValue={value}\n keepCurrentModel\n onMount={onMount}\n onChange={nextValue => {\n if (externalValueSyncRef.current) return;\n const normalized = nextValue ?? '';\n const pending = pendingLocalValuesRef.current;\n if (pending.at(-1) !== normalized) {\n pending.push(normalized);\n if (pending.length > 64) {\n pending.splice(0, pending.length - 64);\n }\n }\n onChange(normalized);\n }}\n onValidate={markers => {\n const diagnostics = mapDiagnostics(markers, monaco);\n diagnosticsRef.current = diagnostics;\n setDiagnosticCount(diagnostics.filter(item => (\n item.severity === 'error'\n )).length);\n onDiagnostics?.(diagnostics);\n }}\n options={{\n ariaLabel,\n automaticLayout: true,\n bracketPairColorization: { enabled: true },\n folding: true,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',\n fontSize: 13,\n formatOnPaste: true,\n insertSpaces: true,\n lineHeight: 22,\n minimap: { enabled: false },\n padding: { top: 12, bottom: 12 },\n readOnly: readOnly || disabled,\n renderValidationDecorations: 'on',\n scrollBeyondLastLine: false,\n tabSize: 2,\n }}\n />\n </Box>\n <Box\n aria-live=\"polite\"\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n gap: 2,\n minHeight: 28,\n px: 1.5,\n py: 0.5,\n borderTop: 1,\n borderColor: 'divider',\n }}\n >\n <Typography variant=\"caption\">{language.toUpperCase()}</Typography>\n <Typography\n variant=\"caption\"\n color={error || diagnosticCount ? 'error' : 'text.secondary'}\n >\n {error ?? (\n diagnosticCount ? labels.errors(diagnosticCount) : labels.valid\n )}\n </Typography>\n <Typography variant=\"caption\">\n {labels.lineColumn(position.lineNumber, position.column)}\n </Typography>\n </Box>\n </Box>\n );\n },\n);\n"],"mappings":"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"}