Monaco-lataus refaktoroitu: singleton Promise, parempi virheenkäsittely

initMonaco palauttaa nyt aina saman Promisen (ei moninkertaista latausta).
AMD-loader virheet ja CDN-virheet napataan ja logitetaan.
monacoLoaded-lippu korvattu Promise-pohjaisella tilanhallinnalla.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jaakko Vanhala
2026-04-09 21:24:08 +03:00
parent 5528be1812
commit 44067efdb6

View File

@@ -57,7 +57,6 @@ import AgentBar from "../components/AgentBar.astro";
} }
// === Globaalit tilat === // === Globaalit tilat ===
let monacoLoaded = false;
// === Tab switching === // === Tab switching ===
window.switchTab = function(tab) { window.switchTab = function(tab) {
@@ -545,26 +544,29 @@ import AgentBar from "../components/AgentBar.astro";
// === Monaco Editor (lazy load) === // === Monaco Editor (lazy load) ===
window.MonacoEnvironment = { getWorkerUrl: () => `data:text/javascript,self.MonacoEnvironment={baseUrl:'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/'};importScripts('https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/base/worker/workerMain.js')` }; window.MonacoEnvironment = { getWorkerUrl: () => `data:text/javascript,self.MonacoEnvironment={baseUrl:'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/'};importScripts('https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/base/worker/workerMain.js')` };
async function initMonaco() { let _monacoInitPromise = null;
if (monacoLoaded) return; function initMonaco() {
monacoLoaded = true; if (_monacoInitPromise) return _monacoInitPromise;
await new Promise(r => { _monacoInitPromise = new Promise((resolve, reject) => {
const s = document.createElement('script'); const s = document.createElement('script');
s.src = 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js'; s.src = 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js';
s.onerror = () => reject(new Error('Monaco loader lataus epäonnistui'));
s.onload = () => { s.onload = () => {
require.config({ paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs' }}); require.config({ paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs' }});
require(['vs/editor/editor.main'], () => { require(['vs/editor/editor.main'], () => {
window.monaco = monaco; // Varmistetaan globaali window.monaco = monaco;
r(); window._monaco = monaco.editor.create(document.getElementById('monaco-container'), {
});
};
document.head.appendChild(s);
});
window._monaco = window.monaco.editor.create(document.getElementById('monaco-container'), {
value: '// Valitse tiedosto tai generoi projekti\n', value: '// Valitse tiedosto tai generoi projekti\n',
language: 'plaintext', theme: 'vs-dark', fontSize: 14, language: 'plaintext', theme: 'vs-dark', fontSize: 14,
minimap: { enabled: false }, automaticLayout: true, padding: { top: 10 } minimap: { enabled: false }, automaticLayout: true, padding: { top: 10 }
}); });
console.log('[Monaco] Valmis');
resolve();
}, (err) => reject(new Error('Monaco AMD load: ' + err)));
};
document.head.appendChild(s);
});
return _monacoInitPromise;
} }
window._editorModels = {}; window._editorModels = {};
@@ -572,7 +574,7 @@ import AgentBar from "../components/AgentBar.astro";
window.openInEditor = async function(files) { window.openInEditor = async function(files) {
switchTab('editor'); switchTab('editor');
await initMonaco(); try { await initMonaco(); } catch(e) { console.error('Monaco-virhe:', e); return; }
const m = window.monaco; const m = window.monaco;
if (!m) { console.error('Monaco ei latautunut'); return; } if (!m) { console.error('Monaco ei latautunut'); return; }
for (const [name,code] of Object.entries(files)) { for (const [name,code] of Object.entries(files)) {