From e8c9f95d25b6219e72653db8986ba61f3c6e55fd Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Mon, 8 Jun 2026 06:24:34 +0530 Subject: [PATCH] feat(main): initialize updater, crash writer, and migration on app start --- src/main/index.js | 37 +++++++++++++++++ src/main/updater/migration-transform.js | 55 +++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 src/main/updater/migration-transform.js diff --git a/src/main/index.js b/src/main/index.js index f71217a..f047bc3 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,4 +1,10 @@ const { app, BrowserWindow, Menu, dialog, ipcMain, shell } = require('electron'); +const { autoUpdater } = require('electron-updater'); +const { UpdaterService } = require('./updater/updater-service'); +const { CrashWriter } = require('./updater/crash-writer'); +const { MigrationRunner } = require('./updater/migration-runner'); +const updaterHandlers = require('./ipc/updater-handlers'); +const crashHandlers = require('./ipc/crash-handlers'); const path = require('path'); const fs = require('fs'); const { exec, execFile, spawn } = require('child_process'); @@ -3066,6 +3072,37 @@ app.whenReady().then(() => { mainWindow = createMainWindow(); mainWindow.on('closed', () => { mainWindow = null; }); + // --- Updater, crash writer, migration (must run before any settings read) --- + const userData = app.getPath('userData'); + + // Migration + const migration = new MigrationRunner({ + dir: userData, + transform: (v4) => { + const { migrateV4ToV5 } = require('./updater/migration-transform'); + return migrateV4ToV5(v4); + }, + }); + migration.run(); + + // Crash writer + const crash = new CrashWriter(path.join(userData, 'crashDumps')); + process.on('uncaughtException', (err) => crash.handleUncaught(err, 'uncaughtException')); + process.on('unhandledRejection', (err) => crash.handleUncaught(err, 'unhandledRejection')); + + // Updater + const updater = new UpdaterService(autoUpdater); + updaterHandlers.register({ + updater, + getMainWindow: () => mainWindow, + getChannel: () => store.get('updateChannel') || 'github', + }); + crashHandlers.register({ + crash, + getMainWindow: () => mainWindow, + }); + // -------------------------------------------------------------------- + // Register file ops IPC handlers fileOps.register({ validatePath, diff --git a/src/main/updater/migration-transform.js b/src/main/updater/migration-transform.js new file mode 100644 index 0000000..74a2774 --- /dev/null +++ b/src/main/updater/migration-transform.js @@ -0,0 +1,55 @@ +// Mirror of src/renderer/lib/migrations/v4-to-v5.ts, plain JS, for main-process use. +// Kept in sync manually; if the renderer transform changes, update this too. +const { z } = require('zod'); + +const v4SettingsSchema = z.object({ + theme: z.enum(['light', 'dark', 'auto']).default('auto'), + customCss: z.string().optional().nullable(), + recentFiles: z.array(z.string()).default([]), + editorFontSize: z.number().min(10).max(28).default(14), + keyBindings: z.record(z.string(), z.string()).optional(), + snippets: z.array(z.unknown()).default([]), +}).passthrough(); + +const v5SettingsShape = { + fontSize: 14, + tabSize: 4, + lineNumbers: true, + wordWrap: true, + minimap: true, + theme: 'system', + accentColor: 'brand', + fontFamily: 'system', + pdfFormat: 'a4', + pdfMargins: 'normal', + pdfEmbedFonts: true, + docxTemplate: 'standard', + docxCustomTemplatePath: null, + replOpen: false, + breadcrumbSymbols: true, + htmlHighlightStyle: 'github', + renderTablesAsAscii: false, + welcomeDismissed: false, + editorFontSize: 14, + customCssPath: null, + userBindings: {}, + updateChannel: 'github', + autoCheckUpdates: true, + firstRun: true, +}; + +function migrateV4ToV5(v4) { + const parsed = v4SettingsSchema.parse(v4 || {}); + return { + ...v5SettingsShape, + ...parsed, + theme: parsed.theme === 'auto' ? 'system' : parsed.theme, + customCssPath: parsed.customCss ?? null, + recentFiles: parsed.recentFiles, + editorFontSize: parsed.editorFontSize, + userBindings: parsed.keyBindings ?? v5SettingsShape.userBindings, + snippets: parsed.snippets, + }; +} + +module.exports = { migrateV4ToV5, v5SettingsShape }; \ No newline at end of file