"use strict"; const electron = require("electron"); const path = require("path"); const fsSync = require("fs"); const Store = require("electron-store"); const crypto = require("crypto"); function _interopNamespaceDefault(e) { const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } }); if (e) { for (const k in e) { if (k !== "default") { const d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: () => e[k] }); } } } n.default = e; return Object.freeze(n); } const fsSync__namespace = /* @__PURE__ */ _interopNamespaceDefault(fsSync); let store = null; function initStore() { if (store) { console.warn("Store 已经初始化过了"); return; } store = new Store({ // 存储文件名 name: "asset-pro-config", // 默认值 defaults: { settings: { count: 0, theme: "system" }, windowBounds: { width: 1600, height: 900 } }, // Schema 验证(可选但推荐) schema: { settings: { type: "object", properties: { count: { type: "number", default: 0 }, theme: { type: "string", enum: ["light", "dark", "system"], default: "system" } }, default: {} }, windowBounds: { type: "object", properties: { width: { type: "number", default: 1600 }, height: { type: "number", default: 900 }, x: { type: "number" }, y: { type: "number" } }, default: {} } } }); console.log("Store 初始化完成,存储路径:", store.path); } function getStore() { if (!store) { throw new Error("Store 未初始化,请先调用 initStore()"); } return store; } function getSettings(key) { const s = getStore(); if (key) { return s.get(`settings.${key}`); } return s.get("settings"); } function saveSettings(key, value) { const s = getStore(); s.set(`settings.${key}`, value); } function getWindowBounds() { const s = getStore(); const bounds = s.get("windowBounds"); const newBounds = { width: 1600, height: 900 }; if (bounds.x !== void 0 && bounds.y !== void 0) { newBounds.x = bounds.x; newBounds.y = bounds.y; } if (bounds.width !== 1600 || bounds.height !== 900) { s.set("windowBounds", newBounds); } return newBounds; } function saveWindowBounds(bounds) { const s = getStore(); s.set("windowBounds", bounds); } class CacheManager { constructor() { this.cacheDir = ""; this.metadataMap = /* @__PURE__ */ new Map(); this.initialized = false; } /** * 初始化缓存管理器 * 必须在 app.whenReady() 之后调用 */ async init() { if (this.initialized) { console.warn("CacheManager 已经初始化过了"); return; } try { const isDev = !electron.app.isPackaged; if (isDev) { this.cacheDir = path.join(process.cwd(), ".cache"); } else { const exePath = process.execPath; const exeDir = path.dirname(exePath); this.cacheDir = path.join(exeDir, "cache"); } await fsSync.promises.mkdir(this.cacheDir, { recursive: true }); await this.loadMetadata(); this.initialized = true; console.log("CacheManager 初始化完成"); console.log("缓存目录:", this.cacheDir); console.log("当前环境:", isDev ? "开发环境" : "生产环境"); } catch (error) { console.error("CacheManager 初始化失败:", error); throw error; } } /** * 确保缓存管理器已初始化 */ ensureInitialized() { if (!this.initialized) { throw new Error("CacheManager 未初始化,请先调用 init()"); } } /** * 生成缓存键的哈希值(用于文件名) */ hashKey(key) { return crypto.createHash("md5").update(key).digest("hex"); } /** * 获取缓存文件路径 */ getCacheFilePath(key, namespace) { const hash = this.hashKey(key); if (namespace) { const namespaceDir = path.join(this.cacheDir, namespace); return path.join(namespaceDir, hash); } return path.join(this.cacheDir, hash); } /** * 获取元数据文件路径 */ getMetadataPath() { return path.join(this.cacheDir, "_metadata.json"); } /** * 加载元数据 */ async loadMetadata() { try { const metadataPath = this.getMetadataPath(); const exists = await fsSync.promises.access(metadataPath).then(() => true).catch(() => false); if (exists) { const content = await fsSync.promises.readFile(metadataPath, "utf-8"); const data = JSON.parse(content); this.metadataMap = new Map(Object.entries(data)); console.log(`加载了 ${this.metadataMap.size} 条缓存元数据`); } } catch (error) { console.warn("加载缓存元数据失败:", error); this.metadataMap = /* @__PURE__ */ new Map(); } } /** * 保存元数据 */ async saveMetadata() { try { const metadataPath = this.getMetadataPath(); const data = Object.fromEntries(this.metadataMap); await fsSync.promises.writeFile(metadataPath, JSON.stringify(data, null, 2), "utf-8"); } catch (error) { console.error("保存缓存元数据失败:", error); } } /** * 检查缓存是否过期 */ isExpired(metadata) { if (!metadata.ttl) return false; const now = Date.now(); return now - metadata.updatedAt > metadata.ttl; } /** * 设置缓存 (JSON数据) */ async setJSON(key, data, config) { var _a; this.ensureInitialized(); try { const namespace = config == null ? void 0 : config.namespace; const filePath = this.getCacheFilePath(key, namespace); if (namespace) { const namespaceDir = path.join(this.cacheDir, namespace); await fsSync.promises.mkdir(namespaceDir, { recursive: true }); } const jsonString = JSON.stringify(data, null, 2); await fsSync.promises.writeFile(filePath, jsonString, "utf-8"); const stats = await fsSync.promises.stat(filePath); const metadata = { key, type: "json", createdAt: ((_a = this.metadataMap.get(key)) == null ? void 0 : _a.createdAt) || Date.now(), updatedAt: Date.now(), size: stats.size, ttl: config == null ? void 0 : config.maxAge }; this.metadataMap.set(key, metadata); await this.saveMetadata(); console.log(`缓存已设置: ${key} (${stats.size} bytes)`); } catch (error) { console.error(`设置缓存失败 [${key}]:`, error); throw error; } } /** * 获取缓存 (JSON数据) */ async getJSON(key, config) { this.ensureInitialized(); try { const metadata = this.metadataMap.get(key); if (!metadata || metadata.type !== "json") { console.log(`缓存不存在或类型不匹配: ${key}`); return null; } if (this.isExpired(metadata)) { console.log(`缓存已过期: ${key}`); await this.delete(key, config == null ? void 0 : config.namespace); return null; } const namespace = config == null ? void 0 : config.namespace; const filePath = this.getCacheFilePath(key, namespace); const content = await fsSync.promises.readFile(filePath, "utf-8"); const data = JSON.parse(content); console.log(`读取缓存: ${key}`); return data; } catch (error) { console.error(`读取缓存失败 [${key}]:`, error); return null; } } /** * 设置缓存 (二进制数据 - 用于图片等) */ async setBinary(key, buffer, type = "binary", config) { var _a; this.ensureInitialized(); try { const namespace = config == null ? void 0 : config.namespace; const filePath = this.getCacheFilePath(key, namespace); if (namespace) { const namespaceDir = path.join(this.cacheDir, namespace); await fsSync.promises.mkdir(namespaceDir, { recursive: true }); } await fsSync.promises.writeFile(filePath, buffer); const stats = await fsSync.promises.stat(filePath); const metadata = { key, type, createdAt: ((_a = this.metadataMap.get(key)) == null ? void 0 : _a.createdAt) || Date.now(), updatedAt: Date.now(), size: stats.size, ttl: config == null ? void 0 : config.maxAge }; this.metadataMap.set(key, metadata); await this.saveMetadata(); console.log(`二进制缓存已设置: ${key} (${stats.size} bytes)`); } catch (error) { console.error(`设置二进制缓存失败 [${key}]:`, error); throw error; } } /** * 获取缓存 (二进制数据) */ async getBinary(key, config) { this.ensureInitialized(); try { const metadata = this.metadataMap.get(key); if (!metadata || metadata.type !== "binary" && metadata.type !== "image") { console.log(`二进制缓存不存在或类型不匹配: ${key}`); return null; } if (this.isExpired(metadata)) { console.log(`二进制缓存已过期: ${key}`); await this.delete(key, config == null ? void 0 : config.namespace); return null; } const namespace = config == null ? void 0 : config.namespace; const filePath = this.getCacheFilePath(key, namespace); const buffer = await fsSync.promises.readFile(filePath); console.log(`读取二进制缓存: ${key}`); return buffer; } catch (error) { console.error(`读取二进制缓存失败 [${key}]:`, error); return null; } } /** * 检查缓存是否存在 */ async has(key, config) { this.ensureInitialized(); try { const metadata = this.metadataMap.get(key); if (!metadata) return false; if (this.isExpired(metadata)) { await this.delete(key, config == null ? void 0 : config.namespace); return false; } const namespace = config == null ? void 0 : config.namespace; const filePath = this.getCacheFilePath(key, namespace); const exists = await fsSync.promises.access(filePath).then(() => true).catch(() => false); return exists; } catch (error) { console.error(`检查缓存失败 [${key}]:`, error); return false; } } /** * 删除单个缓存 */ async delete(key, namespace) { this.ensureInitialized(); try { const filePath = this.getCacheFilePath(key, namespace); await fsSync.promises.unlink(filePath).catch(() => { }); this.metadataMap.delete(key); await this.saveMetadata(); console.log(`缓存已删除: ${key}`); } catch (error) { console.error(`删除缓存失败 [${key}]:`, error); } } /** * 清空指定命名空间的所有缓存 */ async clearNamespace(namespace) { this.ensureInitialized(); try { const namespaceDir = path.join(this.cacheDir, namespace); await fsSync.promises.rm(namespaceDir, { recursive: true, force: true }); const keysToDelete = []; this.metadataMap.forEach((metadata, key) => { const filePath = this.getCacheFilePath(key, namespace); if (filePath.startsWith(namespaceDir)) { keysToDelete.push(key); } }); keysToDelete.forEach((key) => this.metadataMap.delete(key)); await this.saveMetadata(); console.log(`命名空间缓存已清空: ${namespace} (${keysToDelete.length} 项)`); } catch (error) { console.error(`清空命名空间缓存失败 [${namespace}]:`, error); } } /** * 清空所有缓存 */ async clearAll() { this.ensureInitialized(); try { const files = await fsSync.promises.readdir(this.cacheDir, { withFileTypes: true }); for (const file of files) { const filePath = path.join(this.cacheDir, file.name); if (file.name === "_metadata.json") continue; if (file.isDirectory()) { await fsSync.promises.rm(filePath, { recursive: true, force: true }); } else { await fsSync.promises.unlink(filePath); } } this.metadataMap.clear(); await this.saveMetadata(); console.log("所有缓存已清空"); } catch (error) { console.error("清空所有缓存失败:", error); } } /** * 获取缓存统计信息 */ async getStats() { this.ensureInitialized(); let totalSize = 0; this.metadataMap.forEach((metadata) => { totalSize += metadata.size; }); return { totalItems: this.metadataMap.size, totalSize, cacheDir: this.cacheDir }; } /** * 获取所有缓存键 */ async getAllKeys() { this.ensureInitialized(); return Array.from(this.metadataMap.keys()); } } const cacheManager = new CacheManager(); const IPC_CHANNELS = { // 文件操作 SAVE_FILE: "file:save", READ_FILE: "file:read", // 设置操作 GET_SETTINGS: "settings:get", SAVE_SETTINGS: "settings:save", // 缓存操作 CACHE_SET_JSON: "cache:setJSON", CACHE_GET_JSON: "cache:getJSON", CACHE_SET_BINARY: "cache:setBinary", CACHE_GET_BINARY: "cache:getBinary", CACHE_HAS: "cache:has", CACHE_DELETE: "cache:delete", CACHE_CLEAR_NAMESPACE: "cache:clearNamespace", CACHE_CLEAR_ALL: "cache:clearAll", CACHE_GET_STATS: "cache:getStats", // 窗口操作 WINDOW_MINIMIZE: "window:minimize", WINDOW_MAXIMIZE: "window:maximize", WINDOW_CLOSE: "window:close", // Git/System 操作 DIALOG_OPEN_DIRECTORY: "dialog:openDirectory", GIT_CLONE: "git:clone" }; function setupIpcHandlers() { electron.ipcMain.handle( IPC_CHANNELS.SAVE_FILE, async (_event, content, filename = "demo-note.txt") => { try { const desktopPath = electron.app.getPath("desktop"); const filePath = path.join(desktopPath, filename); await fsSync.promises.writeFile(filePath, content, "utf-8"); return { success: true, message: `文件已保存到: ${filePath}`, path: filePath }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("保存文件失败:", errorMessage); return { success: false, message: `保存失败: ${errorMessage}`, path: null }; } } ); electron.ipcMain.handle( IPC_CHANNELS.READ_FILE, async (_event, filename = "demo-note.txt") => { try { const desktopPath = electron.app.getPath("desktop"); const filePath = path.join(desktopPath, filename); try { await fsSync.promises.access(filePath); } catch { return { success: false, message: "文件不存在,请先保存一个文件", content: null }; } const content = await fsSync.promises.readFile(filePath, "utf-8"); return { success: true, message: "文件读取成功", content }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("读取文件失败:", errorMessage); return { success: false, message: `读取失败: ${errorMessage}`, content: null }; } } ); electron.ipcMain.handle(IPC_CHANNELS.GET_SETTINGS, async (_event, key) => { try { const settings = getSettings(key); return { success: true, data: settings }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("获取设置失败:", errorMessage); return { success: false, data: null, message: errorMessage }; } }); electron.ipcMain.handle( IPC_CHANNELS.SAVE_SETTINGS, async (_event, key, value) => { try { saveSettings(key, value); return { success: true, message: "设置已保存" }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("保存设置失败:", errorMessage); return { success: false, message: `保存失败: ${errorMessage}` }; } } ); electron.ipcMain.handle( IPC_CHANNELS.CACHE_SET_JSON, async (_event, key, data, config) => { try { await cacheManager.setJSON(key, data, config); return { success: true, message: "缓存已设置" }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("设置JSON缓存失败:", errorMessage); return { success: false, message: `设置失败: ${errorMessage}` }; } } ); electron.ipcMain.handle( IPC_CHANNELS.CACHE_GET_JSON, async (_event, key, config) => { try { const data = await cacheManager.getJSON(key, config); return { success: true, data }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("获取JSON缓存失败:", errorMessage); return { success: false, data: null, message: errorMessage }; } } ); electron.ipcMain.handle( IPC_CHANNELS.CACHE_SET_BINARY, async (_event, key, buffer, type = "binary", config) => { try { await cacheManager.setBinary(key, buffer, type, config); return { success: true, message: "二进制缓存已设置" }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("设置二进制缓存失败:", errorMessage); return { success: false, message: `设置失败: ${errorMessage}` }; } } ); electron.ipcMain.handle( IPC_CHANNELS.CACHE_GET_BINARY, async (_event, key, config) => { try { const buffer = await cacheManager.getBinary(key, config); return { success: true, data: buffer }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("获取二进制缓存失败:", errorMessage); return { success: false, data: null, message: errorMessage }; } } ); electron.ipcMain.handle( IPC_CHANNELS.CACHE_HAS, async (_event, key, config) => { try { const exists = await cacheManager.has(key, config); return { success: true, exists }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("检查缓存失败:", errorMessage); return { success: false, exists: false, message: errorMessage }; } } ); electron.ipcMain.handle( IPC_CHANNELS.CACHE_DELETE, async (_event, key, namespace) => { try { await cacheManager.delete(key, namespace); return { success: true, message: "缓存已删除" }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("删除缓存失败:", errorMessage); return { success: false, message: `删除失败: ${errorMessage}` }; } } ); electron.ipcMain.handle( IPC_CHANNELS.CACHE_CLEAR_NAMESPACE, async (_event, namespace) => { try { await cacheManager.clearNamespace(namespace); return { success: true, message: `命名空间 ${namespace} 的缓存已清空` }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("清空命名空间缓存失败:", errorMessage); return { success: false, message: `清空失败: ${errorMessage}` }; } } ); electron.ipcMain.handle( IPC_CHANNELS.CACHE_CLEAR_ALL, async (_event) => { try { await cacheManager.clearAll(); return { success: true, message: "所有缓存已清空" }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("清空所有缓存失败:", errorMessage); return { success: false, message: `清空失败: ${errorMessage}` }; } } ); electron.ipcMain.handle( IPC_CHANNELS.CACHE_GET_STATS, async (_event) => { try { const stats = await cacheManager.getStats(); return { success: true, data: stats }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("获取缓存统计信息失败:", errorMessage); return { success: false, data: null, message: errorMessage }; } } ); electron.ipcMain.handle(IPC_CHANNELS.WINDOW_MINIMIZE, async (event) => { try { const window = electron.BrowserWindow.fromWebContents(event.sender); if (window) { window.minimize(); return { success: true }; } return { success: false, message: "无法找到窗口" }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("最小化窗口失败:", errorMessage); return { success: false, message: errorMessage }; } }); electron.ipcMain.handle(IPC_CHANNELS.WINDOW_MAXIMIZE, async (event) => { try { const window = electron.BrowserWindow.fromWebContents(event.sender); if (window) { if (window.isMaximized()) { window.unmaximize(); } else { window.maximize(); } return { success: true, isMaximized: window.isMaximized() }; } return { success: false, message: "无法找到窗口" }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("最大化窗口失败:", errorMessage); return { success: false, message: errorMessage }; } }); electron.ipcMain.handle(IPC_CHANNELS.WINDOW_CLOSE, async (event) => { try { const window = electron.BrowserWindow.fromWebContents(event.sender); if (window) { window.close(); return { success: true }; } return { success: false, message: "无法找到窗口" }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("关闭窗口失败:", errorMessage); return { success: false, message: errorMessage }; } }); electron.ipcMain.handle(IPC_CHANNELS.DIALOG_OPEN_DIRECTORY, async (event) => { try { const window = electron.BrowserWindow.fromWebContents(event.sender); if (!window) return { success: false, message: "无法找到窗口" }; const result = await electron.dialog.showOpenDialog(window, { properties: ["openDirectory", "createDirectory"] }); if (result.canceled) { return { success: false, canceled: true }; } return { success: true, path: result.filePaths[0], canceled: false }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "未知错误"; console.error("打开目录失败:", errorMessage); return { success: false, message: errorMessage }; } }); electron.ipcMain.handle(IPC_CHANNELS.GIT_CLONE, async (event, repoUrl, targetDir) => { return new Promise((resolve) => { const window = electron.BrowserWindow.fromWebContents(event.sender); try { if (!fsSync__namespace.existsSync(targetDir)) { fsSync__namespace.mkdirSync(targetDir, { recursive: true }); } else { const files = fsSync__namespace.readdirSync(targetDir); if (files.length > 0) { return resolve({ success: false, message: `目标文件夹不为空。请选择一个空文件夹。` }); } } } catch (err) { return resolve({ success: false, message: `检查目录失败: ${err}` }); } console.log(`开始 Git Clone (spawn): ${repoUrl} -> ${targetDir}`); const { spawn } = require("child_process"); const child = spawn("git", ["clone", "--progress", repoUrl, "."], { cwd: targetDir }); let stdoutData = ""; let stderrData = ""; child.stdout.on("data", (data) => { const text = data.toString(); stdoutData += text; console.log("Git Stdout:", text); }); child.stderr.on("data", (data) => { const text = data.toString(); stderrData += text; if (window) { window.webContents.send("git:progress", { repoUrl, raw: text }); } }); child.on("close", (code) => { console.log(`Git clone process exited with code ${code}`); if (code === 0) { resolve({ success: true, message: "项目克隆成功", stdout: stdoutData }); } else { resolve({ success: false, message: `Git clone 失败 (Code ${code})`, stdout: stderrData // git 错误通常在 stderr }); } }); child.on("error", (err) => { console.error("Git spawn error:", err); resolve({ success: false, message: `启动 Git 进程失败: ${err.message}` }); }); }); }); } const VITE_DEV_SERVER_URL = process.env["VITE_DEV_SERVER_URL"]; let mainWindow = null; function createWindow() { const bounds = getWindowBounds(); const windowOptions = { width: bounds.width, height: bounds.height, webPreferences: { // 安全配置:启用上下文隔离 contextIsolation: true, // 安全配置:禁用 Node.js 集成 nodeIntegration: false, // 预加载脚本路径 preload: path.join(__dirname, "preload.js"), // 启用沙盒模式 sandbox: false // 需要设为 false 才能使用 preload }, // 窗口样式 title: "AssetPro", show: false, // 先隐藏,等准备好再显示 backgroundColor: "#ffffff", // 无边框窗口 frame: false }; if (bounds.x !== void 0 && bounds.y !== void 0) { windowOptions.x = bounds.x; windowOptions.y = bounds.y; } else { windowOptions.center = true; } mainWindow = new electron.BrowserWindow(windowOptions); mainWindow.once("ready-to-show", () => { mainWindow == null ? void 0 : mainWindow.show(); }); setTimeout(() => { if (mainWindow && !mainWindow.isVisible()) { console.log("超时后强制显示窗口"); mainWindow.show(); } }, 3e3); mainWindow.on("close", () => { if (mainWindow) { const bounds2 = mainWindow.getBounds(); saveWindowBounds(bounds2); } }); if (VITE_DEV_SERVER_URL) { mainWindow.loadURL(VITE_DEV_SERVER_URL); } else { const fs = require("fs"); const possiblePaths = [ path.join(electron.app.getAppPath(), "dist-renderer", "index.html"), // asar 内部(主要路径) path.join(process.resourcesPath, "dist-renderer", "index.html"), // resources/dist-renderer(如果 extraResources 存在) path.join(process.resourcesPath, "dist", "index.html") // resources/dist(备用) ]; console.log("尝试加载页面,检查以下路径:"); possiblePaths.forEach((p) => { const exists = fs.existsSync(p); console.log(` ${exists ? "✓" : "✗"} ${p}`); }); console.log("process.resourcesPath:", process.resourcesPath); console.log("app.getAppPath():", electron.app.getAppPath()); let indexPath = null; for (const testPath of possiblePaths) { if (fs.existsSync(testPath)) { indexPath = testPath; console.log("找到页面文件:", indexPath); break; } } if (!indexPath) { console.error("无法找到 index.html 文件!"); mainWindow.loadURL("data:text/html,

无法找到页面文件

请检查控制台输出

"); return; } mainWindow.loadFile(indexPath).catch((error) => { console.error("loadFile 失败:", error); let fileUrl = indexPath.replace(/\\/g, "/"); if (fileUrl.match(/^[A-Z]:/)) { fileUrl = `file:///${fileUrl}`; } else { fileUrl = `file://${fileUrl}`; } console.log("尝试使用 loadURL:", fileUrl); mainWindow.loadURL(fileUrl).catch((urlError) => { console.error("loadURL 也失败:", urlError); mainWindow.loadURL("data:text/html,

页面加载失败

请查看控制台错误信息

"); }); }); } mainWindow.webContents.on("did-fail-load", (event, errorCode, errorDescription) => { console.error("页面加载失败:", errorCode, errorDescription); }); mainWindow.webContents.on("before-input-event", (event, input) => { if (input.key === "F12" || input.key === "f12" || input.code === "F12") { if (mainWindow) { if (mainWindow.webContents.isDevToolsOpened()) { mainWindow.webContents.closeDevTools(); } else { mainWindow.webContents.openDevTools(); } } event.preventDefault(); } }); electron.globalShortcut.register("F12", () => { if (mainWindow) { if (mainWindow.webContents.isDevToolsOpened()) { mainWindow.webContents.closeDevTools(); } else { mainWindow.webContents.openDevTools(); } } }); } electron.app.whenReady().then(async () => { initStore(); await cacheManager.init(); setupIpcHandlers(); createWindow(); electron.app.on("activate", () => { if (electron.BrowserWindow.getAllWindows().length === 0) { createWindow(); } }); }); electron.app.on("window-all-closed", () => { if (process.platform !== "darwin") { electron.app.quit(); } }); electron.app.on("will-quit", () => { electron.globalShortcut.unregisterAll(); });