From 73077c93ef512ee20dcd92ac1d062b42276f8808 Mon Sep 17 00:00:00 2001 From: abdo Date: Wed, 30 Sep 2026 19:59:14 +0300 Subject: [PATCH 1/2] fix(electron): register getGitHubStars IPC handler and guard window teardown --- electron/lifecycle/fatal-events.cjs | 8 +++++++- electron/main.cjs | 10 ++++++++++ vite.config.ts | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/electron/lifecycle/fatal-events.cjs b/electron/lifecycle/fatal-events.cjs index 0c1b4c78a..10efc99a1 100644 --- a/electron/lifecycle/fatal-events.cjs +++ b/electron/lifecycle/fatal-events.cjs @@ -14,7 +14,13 @@ function registerFatalLifecycle({ app, powerMonitor, coordinator, log = () => {} processTarget.on('uncaughtException', (error) => exitAfterShutdown('fatal', `Uncaught exception: ${error?.stack || error}`), ); - processTarget.on('unhandledRejection', (reason) => exitAfterShutdown('fatal', `Unhandled rejection: ${reason}`)); + processTarget.on('unhandledRejection', (reason) => { + if (String(reason?.message || reason).includes('Object has been destroyed')) { + log(`Ignored destroyed object rejection: ${reason}`); + return; + } + exitAfterShutdown('fatal', `Unhandled rejection: ${reason}`); + }); powerMonitor.on('shutdown', requestQuit); app.on('render-process-gone', (_event, contents, details) => exitAfterShutdown( diff --git a/electron/main.cjs b/electron/main.cjs index 75a19f93c..123c11abf 100644 --- a/electron/main.cjs +++ b/electron/main.cjs @@ -345,6 +345,16 @@ function initializeApplication() { const updater = initializeApplicationUpdater({ app, BrowserWindow, autoUpdater, coordinator, applicationIpc }); applicationIpc.handle('community:open-discord', () => shell.openExternal(DISCORD_INVITE_URL)); applicationIpc.handle('community:open-github', () => shell.openExternal(GITHUB_REPOSITORY_URL)); + applicationIpc.handle('community:get-github-stars', async () => { + try { + const res = await fetch('https://api.github.com/repos/BeamRecorder/Beam'); + if (!res.ok) return { stars: 0 }; + const data = await res.json(); + return { stars: data.stargazers_count ?? 0 }; + } catch { + return { stars: 0 }; + } + }); ipcMain.on('app:quit', () => { if (coordinator.canAcceptWork()) app.quit(); }); diff --git a/vite.config.ts b/vite.config.ts index 0577dd51f..45f70ff7e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -90,6 +90,7 @@ export default defineConfig({ }, server: { port: 6500, + strictPort: true, }, test: { include: ['src/**/*.test.ts', 'tests/**/*.test.ts'], From a3831604b7b2a6b46bca482757076c26a0d0355c Mon Sep 17 00:00:00 2001 From: abdo Date: Wed, 30 Sep 2026 20:40:16 +0300 Subject: [PATCH 2/2] fix(test): use recursive rmSync on symlinked directory in screenshot test --- test/screenshot-images.test.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/screenshot-images.test.cjs b/test/screenshot-images.test.cjs index 2c8fb2efc..1b7cd19cb 100644 --- a/test/screenshot-images.test.cjs +++ b/test/screenshot-images.test.cjs @@ -238,7 +238,7 @@ test('does not resolve symlinked screenshot media directories or files', (t) => fs.symlinkSync(outside, mediaDirectory, 'dir'); const url = `project-media://screenshot/${fx.document.id}/media/${fileName}`; assert.equal(fx.store.fileForUrl(url), null); - fs.rmSync(mediaDirectory, { force: true }); + fs.rmSync(mediaDirectory, { recursive: true, force: true }); fs.mkdirSync(mediaDirectory); fs.symlinkSync(externalFile, path.join(mediaDirectory, fileName), 'file');