import 'reflect-metadata'; import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles/variables.css'; import './index.css'; import App from './App.tsx'; import { KGCore } from './core/KGCore'; import { KGAudioInterface } from './core/audio-interface/KGAudioInterface'; import { KGMidiInput } from './core/midi-input/KGMidiInput'; import { KGDebugger } from './core/KGDebugger'; const root = createRoot(document.getElementById('root')!); // OPFS requires a secure context (HTTPS or localhost). Show a clear error instead of crashing. if (!window.isSecureContext) { root.render( 🔒 Secure Context Required K.G.Studio uses the browser's Origin Private File System (OPFS) to store projects, which requires a secure context. Use https:// instead of http:// or access via localhost / 127.0.0.1 , ); } else { // Initialize KGCore instance await KGCore.instance().initialize(); // Initialize KGMidiInput instance await KGMidiInput.instance().initialize(); // Attach debugger to global window in development mode if (import.meta.env.DEV) { const dbg = KGDebugger.instance(); (window as unknown as { KGDebugger: KGDebugger; sh: () => Promise }).KGDebugger = dbg; (window as unknown as { sh: () => Promise }).sh = () => dbg.startShell(); console.log('🔧 KGDebugger attached to window - try: KGDebugger.help() or sh()'); } // Start audio context on first user interaction let audioContextStarted = false; const tryStartAudioContext = async () => { if (!audioContextStarted) { audioContextStarted = true; try { const audioInterface = KGAudioInterface.instance(); if (!audioInterface.getIsAudioContextStarted()) { await audioInterface.startAudioContext(); console.log('Audio context started on first user interaction'); } } catch (error) { console.log('Audio context start failed:', error); audioContextStarted = false; // Allow retry } } }; // Request MIDI access on first user interaction let midiAccessRequested = false; const tryRequestMIDIAccess = async () => { if (!midiAccessRequested) { midiAccessRequested = true; try { const midiInput = KGMidiInput.instance(); if (!midiInput.getMIDIAccess()) { await midiInput.requestMIDIAccess(); console.log('MIDI access granted on first user interaction'); } } catch (error) { console.log('MIDI access failed:', error); midiAccessRequested = false; // Allow retry } } }; // Combined handler for first user interaction const handleFirstInteraction = async () => { await tryStartAudioContext(); await tryRequestMIDIAccess(); // Remove listeners after first attempt document.removeEventListener('click', handleFirstInteraction); document.removeEventListener('touchstart', handleFirstInteraction); document.removeEventListener('keydown', handleFirstInteraction); }; // Listen for first user interaction document.addEventListener('click', handleFirstInteraction, { passive: true }); document.addEventListener('touchstart', handleFirstInteraction, { passive: true }); document.addEventListener('keydown', handleFirstInteraction, { passive: true }); // Add event listener for beforeunload event window.addEventListener('beforeunload', (event) => { // Cancel the event event.preventDefault(); // Chrome requires returnValue to be set event.returnValue = ''; // The browser will show a standard confirmation dialog // with a message like "Changes you made may not be saved." // Note: Custom messages are no longer supported in modern browsers for security reasons }); root.render( , ); } // end isSecureContext else
K.G.Studio uses the browser's Origin Private File System (OPFS) to store projects, which requires a secure context.
https://
http://
localhost
127.0.0.1