Fix L29/L52: QUALITY_OPTIONS moved to UI module; installer spawn via child_process
L29: QUALITY_OPTIONS was a presentational constant living in store/downloads.ts,
coupling views to the store. Moved to src/renderer/src/qualityOptions.ts,
which assembles it directly from @shared/ipc. store/downloads.ts no longer
imports VIDEO/AUDIO_QUALITY_OPTIONS. Both consumers (DownloadBar, SettingsView)
updated to import from the new module.
L52: Replaced the fixed `setTimeout(app.quit, 1500)` installer handoff with a
detached spawn. The installer is spawned with stdio:'ignore' and unref'd so
it outlives AeroFetch even on a slow machine. app.quit() fires on setImmediate
so the IPC response returns to the renderer before the process exits.
typecheck + 242 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+9
-8
@@ -1,4 +1,5 @@
|
||||
import { app, net, shell, type WebContents } from 'electron'
|
||||
import { app, net, type WebContents } from 'electron'
|
||||
import { spawn } from 'child_process'
|
||||
import { createWriteStream, type WriteStream } from 'fs'
|
||||
import { stat, unlink } from 'fs/promises'
|
||||
import { join, normalize, dirname } from 'path'
|
||||
@@ -413,9 +414,6 @@ export async function downloadAppUpdate(url: string, wc: WebContents): Promise<A
|
||||
})
|
||||
}
|
||||
|
||||
/** Let the launched installer spawn before we quit to release our files (ms). */
|
||||
const INSTALLER_HANDOFF_MS = 1500
|
||||
|
||||
/** Launch a freshly-downloaded installer, then quit so it can replace the app. */
|
||||
export async function runAppUpdate(filePath: string): Promise<{ ok: boolean; error?: string }> {
|
||||
try {
|
||||
@@ -428,10 +426,13 @@ export async function runAppUpdate(filePath: string): Promise<{ ok: boolean; err
|
||||
return { ok: false, error: 'Refused to run an unexpected file.' }
|
||||
}
|
||||
await stat(target) // throws if the file is missing
|
||||
const err = await shell.openPath(target) // hand the installer to the OS
|
||||
if (err) return { ok: false, error: err }
|
||||
// Give the installer a beat to spawn, then quit so it can overwrite our files.
|
||||
setTimeout(() => app.quit(), INSTALLER_HANDOFF_MS)
|
||||
// Spawn the installer detached + unref'd so it outlives our process even on a
|
||||
// slow machine. shell.openPath goes through ShellExecute but gives us no child
|
||||
// PID to wait on; spawning directly lets us call unref() before we quit.
|
||||
const child = spawn(target, [], { detached: true, stdio: 'ignore', shell: false })
|
||||
child.unref()
|
||||
// Let the IPC response reach the renderer before we exit.
|
||||
setImmediate(() => app.quit())
|
||||
return { ok: true }
|
||||
} catch (e) {
|
||||
return { ok: false, error: e instanceof Error ? e.message : String(e) }
|
||||
|
||||
Reference in New Issue
Block a user