let _cmCache: {
    EditorView?: any;
    EditorState?: any;
    EditorSelection?: any;
    markdown?: any;
    markdownLanguage?: any;
    keymap?: any;
    defaultKeymap?: any;
    history?: any;
    historyKeymap?: any;
    lineNumbers?: any;
    highlightSpecialChars?: any;
    drawSelection?: any;
    dropCursor?: any;
    rectangularSelection?: any;
    crosshairCursor?: any;
    highlightActiveLine?: any;
    highlightActiveLineGutter?: any;
    indentWithTab?: any;
    indentUnit?: any;
    autocompletion?: any;
    completionKeymap?: any;
    closeBrackets?: any;
    closeBracketsKeymap?: any;
    searchKeymap?: any;
    highlightSelectionMatches?: any;
    lintKeymap?: any;
    EditorState_allowMultipleSelections?: any;
    EditorState_readOnly?: any;
    EditorView_lineWrapping?: any;
    EditorView_editable?: any;
    EditorView_contentAttributes?: any;
    bracketMatching?: any;
    foldGutter?: any;
    foldKeymap?: any;
    indentOnInput?: any;
    languages?: any;
    oneDark?: any;
    placeholderExt?: any;
} | null = null;

// ...existing code...
import { browser } from '$app/environment';

type CMCache = {
    EditorView: any;
    EditorState: any;
    EditorSelection?: any;
    markdown?: any;
    markdownLanguage?: any;
    keymap?: any;
    defaultKeymap?: any;
    history?: any;
    historyKeymap?: any;
    lineNumbers?: any;
    highlightSpecialChars?: any;
    drawSelection?: any;
    dropCursor?: any;
    rectangularSelection?: any;
    crosshairCursor?: any;
    highlightActiveLine?: any;
    highlightActiveLineGutter?: any;
    indentWithTab?: any;
    indentUnit?: any;
    autocompletion?: any;
    completionKeymap?: any;
    closeBrackets?: any;
    closeBracketsKeymap?: any;
    searchKeymap?: any;
    highlightSelectionMatches?: any;
    lintKeymap?: any;
    EditorState_allowMultipleSelections?: any;
    EditorState_readOnly?: any;
    EditorView_lineWrapping?: any;
    EditorView_editable?: any;
    EditorView_contentAttributes?: any;
    bracketMatching?: any;
    foldGutter?: any;
    foldKeymap?: any;
    indentOnInput?: any;
    languages?: any;
    oneDark?: any;
    placeholderExt?: any;
    Compartment?: any;
} | null;

const GLOBAL_KEY = '__cm_singleton_modules_v1';

export async function ensure_CodeMirror_modules(): Promise<CMCache> {
    if (!browser) return null;

    // Use a single global object so HMR/multiple module copies reuse same instance
    const globalAny = globalThis as any;
    if (globalAny[GLOBAL_KEY]) return globalAny[GLOBAL_KEY] as CMCache;

    const [
        viewMod,
        stateMod,
        markdownMod,
        commandsMod,
        languageMod,
        autocompleteMod,
        searchMod,
        lintMod,
        themeOneDarkMod
    ] = await Promise.all([
        import('@codemirror/view'),
        import('@codemirror/state'),
        import('@codemirror/lang-markdown'),
        import('@codemirror/commands'),
        import('@codemirror/language'),
        import('@codemirror/autocomplete'),
        import('@codemirror/search'),
        import('@codemirror/lint'),
        import('@codemirror/theme-one-dark')
    ]);

    const cache: CMCache = {
        EditorView: viewMod.EditorView,
        keymap: viewMod.keymap,
        lineNumbers: viewMod.lineNumbers,
        highlightSpecialChars: viewMod.highlightSpecialChars,
        drawSelection: viewMod.drawSelection,
        dropCursor: viewMod.dropCursor,
        rectangularSelection: viewMod.rectangularSelection,
        crosshairCursor: viewMod.crosshairCursor,
        highlightActiveLine: viewMod.highlightActiveLine,
        highlightActiveLineGutter: viewMod.highlightActiveLineGutter,
        EditorView_lineWrapping: viewMod.EditorView.lineWrapping,
        EditorView_editable: viewMod.EditorView.editable,
        EditorView_contentAttributes: viewMod.EditorView.contentAttributes,
        placeholderExt: viewMod.placeholder,

        EditorState: stateMod.EditorState,
        EditorSelection: stateMod.EditorSelection,
        EditorState_allowMultipleSelections:
            stateMod.EditorState.allowMultipleSelections,
        EditorState_readOnly: stateMod.EditorState.readOnly,
        Compartment: stateMod.Compartment,

        markdown: markdownMod?.markdown,
        markdownLanguage: markdownMod?.markdownLanguage,
        languages: (languageMod as any)?.languages, // Cast to any to avoid TS error if property is missing from types

        defaultKeymap: (commandsMod && commandsMod.defaultKeymap) || [],
        history: commandsMod?.history,
        historyKeymap: commandsMod?.historyKeymap || [],
        indentWithTab: commandsMod?.indentWithTab,

        indentUnit: languageMod?.indentUnit,
        indentOnInput: languageMod?.indentOnInput,
        bracketMatching: languageMod?.bracketMatching,
        foldGutter: languageMod?.foldGutter,
        foldKeymap: languageMod?.foldKeymap,

        autocompletion: autocompleteMod?.autocompletion,
        completionKeymap: autocompleteMod?.completionKeymap,
        closeBrackets: autocompleteMod?.closeBrackets,
        closeBracketsKeymap: autocompleteMod?.closeBracketsKeymap,

        searchKeymap: searchMod?.searchKeymap,
        highlightSelectionMatches: searchMod?.highlightSelectionMatches,

        lintKeymap: lintMod?.lintKeymap,

        oneDark: themeOneDarkMod?.oneDark
    };

    globalAny[GLOBAL_KEY] = cache;
    return cache;
}
