import { initializeApp } from "./main.common"; import { logger } from "./utils/logger"; const platform = process.env.VITE_PLATFORM; const pwa_enabled = process.env.VITE_PWA_ENABLED === "true"; logger.info("[Main Electron] Initializing app"); logger.info("[Main Electron] Platform:", { platform }); logger.info("[Main Electron] PWA enabled:", { pwa_enabled }); if (pwa_enabled) { logger.warn("[Main Electron] PWA is enabled, but not supported in electron"); } // Initialize app and SQLite const app = initializeApp(); /** * SQLite initialization configuration * Defines timeouts and retry settings for database operations * * @author Matthew Raymer */ const SQLITE_CONFIG = { INITIALIZATION: { TIMEOUT_MS: 10000, // 10 seconds for initial setup RETRY_ATTEMPTS: 3, RETRY_DELAY_MS: 1000 }, OPERATIONS: { TIMEOUT_MS: 5000, // 5 seconds for regular operations RETRY_ATTEMPTS: 2, RETRY_DELAY_MS: 500 }, CONNECTION: { MAX_CONNECTIONS: 5, IDLE_TIMEOUT_MS: 30000 } }; // Create a promise that resolves when SQLite is ready const sqliteReady = new Promise((resolve, reject) => { let retryCount = 0; let initializationTimeout: NodeJS.Timeout; const attemptInitialization = () => { // Clear any existing timeout if (initializationTimeout) { clearTimeout(initializationTimeout); } // Set timeout for this attempt initializationTimeout = setTimeout(() => { if (retryCount < SQLITE_CONFIG.INITIALIZATION.RETRY_ATTEMPTS) { retryCount++; logger.warn(`[Main Electron] SQLite initialization attempt ${retryCount} timed out, retrying...`); setTimeout(attemptInitialization, SQLITE_CONFIG.INITIALIZATION.RETRY_DELAY_MS); } else { logger.error("[Main Electron] SQLite initialization failed after all retries"); reject(new Error("SQLite initialization timeout after all retries")); } }, SQLITE_CONFIG.INITIALIZATION.TIMEOUT_MS); // Wait for electron bridge to be available const checkElectronBridge = () => { if (window.electron?.ipcRenderer) { logger.info("[Main Electron] IPC renderer bridge available"); // Listen for SQLite ready signal window.electron.ipcRenderer.once('sqlite-ready', () => { clearTimeout(initializationTimeout); logger.info("[Main Electron] Received SQLite ready signal"); resolve(); }); // Also listen for database errors window.electron.ipcRenderer.once('database-status', (...args: unknown[]) => { clearTimeout(initializationTimeout); const status = args[0] as { status: string; error?: string }; if (status.status === 'error') { logger.error("[Main Electron] Database error:", status.error); reject(new Error(status.error || 'Database initialization failed')); } }); // Check if SQLite is already available window.electron.ipcRenderer.invoke('sqlite-is-available') .then((result: unknown) => { const isAvailable = Boolean(result); if (isAvailable) { logger.info("[Main Electron] SQLite is already available"); // Don't resolve here - wait for the ready signal // This prevents race conditions where the ready signal arrives after this check } }) .catch((error: Error) => { logger.error("[Main Electron] Failed to check SQLite availability:", error); // Don't reject here - wait for either ready signal or timeout }); } else { // Check again in 100ms if bridge isn't ready setTimeout(checkElectronBridge, 100); } }; // Start checking for bridge checkElectronBridge(); }; // Start first initialization attempt attemptInitialization(); }); // Wait for SQLite to be ready before mounting sqliteReady .then(() => { logger.info("[Main Electron] SQLite ready, mounting app..."); app.mount("#app"); logger.info("[Main Electron] App mounted successfully"); }) .catch((error) => { logger.error("[Main Electron] Failed to initialize SQLite:", error instanceof Error ? error.message : 'Unknown error'); // Show error to user with retry option const errorDiv = document.createElement("div"); errorDiv.style.cssText = "position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #ffebee; color: #c62828; padding: 20px; border-radius: 4px; text-align: center; max-width: 80%; z-index: 9999;"; errorDiv.innerHTML = `

Failed to Initialize Application

There was an error initializing the database. This could be due to:

Error details: ${error instanceof Error ? error.message : 'Unknown error'}

`; document.body.appendChild(errorDiv); });