1+ """ Global Monaco initialization - ensures syntax highlighting is loaded once."""
2+
3+ import from "monaco -textmate " { Registry }
4+ import from "monaco -editor -textmate " { wireTmGrammars }
5+ import from "onigasm " { loadWASM }
6+
7+ # CORRECTED PATHS - Use absolute paths from web root
8+ glob ONIG_WASM_PATH = " /static/assets/onigasm.wasm" ;
9+ glob LANGUAGE_CONFIG_PATH = " /static/assets/language-configuration.json" ;
10+
11+ # Global initialization state
12+ glob monacoInitialized = false;
13+ glob initializationPromise = null;
14+ glob cachedGrammarConfig = null;
15+ glob cachedRegistry = null;
16+ glob cachedGrammarMap = null;
17+
18+ """ Internal function to perform the actual initialization."""
19+ async def _performInitialization() - > any {
20+ try {
21+ # Load WASM
22+ await loadWASM(ONIG_WASM_PATH );
23+
24+ # Fetch Jac grammar from GitHub
25+ response = await fetch(" https://raw.githubusercontent.com/jaseci-labs/jac-vscode/main/syntaxes/jac.tmLanguage.json" );
26+
27+ if not response.ok {
28+ raise Reflect.construct(Error, [f " Failed to fetch grammar: { response.status} " ]);
29+ }
30+
31+ grammarConfigRes = await fetch(LANGUAGE_CONFIG_PATH );
32+
33+ if not grammarConfigRes.ok {
34+ raise Reflect.construct(Error, [f " Failed to fetch language config: { grammarConfigRes.status} " ]);
35+ }
36+
37+ jacGrammar = await response.json();
38+ cachedGrammarConfig = await grammarConfigRes.json();
39+
40+ # Create TextMate registry
41+ registry = Reflect.construct(Registry, [{
42+ getGrammarDefinition: lambda {
43+ return {
44+ format : " json" ,
45+ content: JSON .stringify(jacGrammar)
46+ };
47+ }
48+ }]);
49+
50+ cachedRegistry = registry;
51+
52+ # Create grammar map
53+ grammar = Reflect.construct(Map, []);
54+ grammar.set(" jac" , " source.jac" );
55+ cachedGrammarMap = grammar;
56+
57+ monacoInitialized = true;
58+
59+ return cachedGrammarConfig;
60+
61+ } except Exception as error {
62+ initializationPromise = null; # Reset on error to allow retry
63+ return null;
64+ }
65+ }
66+
67+ """ Initialize Monaco globally - call this once when the app loads."""
68+ async def :pub initializeMonacoGlobally() - > any {
69+ # If already initialized or in progress, return the existing promise
70+ if monacoInitialized {
71+ return cachedGrammarConfig;
72+ }
73+
74+ if initializationPromise {
75+ return await initializationPromise;
76+ }
77+
78+ # Create initialization promise by calling the async function
79+ initializationPromise = _performInitialization();
80+
81+ return await initializationPromise;
82+ }
83+
84+ """ Setup Monaco editor instance with Jac syntax highlighting."""
85+ async def :pub setupMonacoEditor(monaco: any , editor: any ) - > any {
86+ try {
87+ # Ensure global initialization is complete
88+ if not monacoInitialized {
89+ await initializeMonacoGlobally();
90+ }
91+
92+ # Register language if not already registered
93+ languages = monaco.languages.getLanguages();
94+ isJacRegistered = languages.some(lambda lang: any { return lang.id == " jac" ; });
95+
96+ if not isJacRegistered {
97+ monaco.languages.register({ id : " jac" });
98+ }
99+
100+ # Wire grammar to this specific editor instance (lightweight operation)
101+ if editor and cachedRegistry and cachedGrammarMap {
102+ await wireTmGrammars(monaco, cachedRegistry, cachedGrammarMap, editor);
103+ }
104+
105+ return cachedGrammarConfig;
106+
107+ } except Exception as error {
108+ return null;
109+ }
110+ }
111+
112+ """ Configure Monaco theme - only needs to be called once per Monaco instance."""
113+ def :pub defineJacTheme (monaco : any ) -> None {
114+ try {
115+ monaco.editor.defineTheme(" jac-theme" , {
116+ base: " vs-dark" ,
117+ inherit: true,
118+ rules: [
119+ # Keywords - Orange
120+ { token: " storage.type.class.jac" , foreground: " f97316" , fontStyle: " bold" },
121+ { token: " storage.type.function.jac" , foreground: " f97316" , fontStyle: " bold" },
122+ { token: " keyword.control.flow.jac" , foreground: " f97316" , fontStyle: " bold" },
123+ { token: " keyword.control.import.jac" , foreground: " f97316" },
124+ { token: " storage.type.has.jac" , foreground: " f97316" },
125+ { token: " storage.modifier.declaration.jac" , foreground: " f97316" },
126+
127+ # Class/Function Names - Amber
128+ { token: " entity.name.type.class.jac" , foreground: " fbbf24" },
129+ { token: " entity.name.function.jac" , foreground: " fbbf24" },
130+
131+ # Types - Light Orange
132+ { token: " support.type.jac" , foreground: " fb923c" },
133+ { token: " constant.language.jac" , foreground: " fb923c" },
134+
135+ # Strings - Green
136+ { token: " string.quoted.single.jac" , foreground: " 86efac" },
137+ { token: " string.quoted.double.jac" , foreground: " 86efac" },
138+ { token: " string.interpolated.jac" , foreground: " 86efac" },
139+
140+ # Numbers - Purple
141+ { token: " constant.numeric.jac" , foreground: " c084fc" },
142+
143+ # Comments - Gray
144+ { token: " comment.line.jac" , foreground: " 6b7280" , fontStyle: " italic" },
145+ { token: " comment.block.jac" , foreground: " 6b7280" , fontStyle: " italic" },
146+
147+ # Variables - Light Blue
148+ { token: " variable.parameter.jac" , foreground: " 93c5fd" },
149+ { token: " variable.language.special.self.jac" , foreground: " 93c5fd" }
150+ ],
151+ colors: {
152+ " editor.background" : " #1a1b1e" ,
153+ " editor.foreground" : " #e4e4e7" ,
154+ " editorLineNumber.foreground" : " #6b7280" ,
155+ " editorLineNumber.activeForeground" : " #f97316" ,
156+ " editorCursor.foreground" : " #f97316" ,
157+ " editor.selectionBackground" : " #f9731633"
158+ }
159+ });
160+ } except Exception as error {
161+ }
162+ }
163+
164+ """ Configure Monaco theme - only needs to be called once per Monaco instance."""
165+ def :pub configureMonacoTheme (monaco : any , grammarConfig : any ) -> None {
166+ try {
167+ # Set language configuration
168+ if grammarConfig {
169+ monaco.languages.setLanguageConfiguration(" jac" , grammarConfig);
170+ }
171+
172+ # Define and apply the theme
173+ defineJacTheme(monaco);
174+ monaco.editor.setTheme(" jac-theme" );
175+
176+ } except Exception as error {
177+ }
178+ }
0 commit comments