From 98ee7d7da0fa14b1e1b56152a2930e0031ac23e3 Mon Sep 17 00:00:00 2001 From: Arthur Lobo <64273139+ArthurLobopro@users.noreply.github.com> Date: Thu, 13 Feb 2025 22:56:14 -0300 Subject: [PATCH 1/5] feat: start/stop updater --- src/index.ts | 81 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 21 deletions(-) diff --git a/src/index.ts b/src/index.ts index c378898..7492f17 100644 --- a/src/index.ts +++ b/src/index.ts @@ -115,6 +115,13 @@ export interface IUpdateElectronAppOptions { readonly onNotifyUser?: (info: IUpdateInfo) => void; } +export interface IUpdater { + readonly isSupported: boolean; + readonly isLookingForUpdates: boolean; + readonly stopLookingForUpdates: () => void; + readonly startLookingForUpdates: () => void; +} + // eslint-disable-next-line @typescript-eslint/no-require-imports const pkg = require('../package.json'); const userAgent = format('%s/%s (%s: %s)', pkg.name, pkg.version, os.platform(), os.arch()); @@ -128,30 +135,33 @@ const isHttpsUrl = (maybeURL: string) => { } }; -export function updateElectronApp(opts: IUpdateElectronAppOptions = {}) { - // check for bad input early, so it will be logged during development - const safeOpts = validateInput(opts); +export async function updateElectronApp(opts: IUpdateElectronAppOptions = {}): Promise { + return new Promise((resolve, reject) => { + // check for bad input early, so it will be logged during development + const safeOpts = validateInput(opts); + + // don't attempt to update during development + if (!app.isPackaged) { + const message = + 'update-electron-app config looks good; aborting updates since app is in development mode'; + if (opts.logger) { + opts.logger.log(message); + } else { + console.log(message); + } - // don't attempt to update during development - if (!app.isPackaged) { - const message = - 'update-electron-app config looks good; aborting updates since app is in development mode'; - if (opts.logger) { - opts.logger.log(message); - } else { - console.log(message); + return reject(); } - return; - } - if (app.isReady()) { - initUpdater(safeOpts); - } else { - app.on('ready', () => initUpdater(safeOpts)); - } + if (app.isReady()) { + resolve(initUpdater(safeOpts)); + } else { + app.on('ready', () => resolve(initUpdater(safeOpts))); + } + }); } -function initUpdater(opts: ReturnType) { +function initUpdater(opts: ReturnType): IUpdater { const { updateSource, updateInterval, logger } = opts; // exit early on unsupported platforms, e.g. `linux` @@ -159,7 +169,12 @@ function initUpdater(opts: ReturnType) { log( `Electron's autoUpdater does not support the '${process.platform}' platform. Ref: https://www.electronjs.org/docs/latest/api/auto-updater#platform-notices`, ); - return; + return { + isSupported: false, + isLookingForUpdates: false, + stopLookingForUpdates: () => {}, + startLookingForUpdates: () => {}, + }; } let feedURL: string; @@ -243,9 +258,33 @@ function initUpdater(opts: ReturnType) { // check for updates right away and keep checking later autoUpdater.checkForUpdates(); - setInterval(() => { + + let intervalID = setInterval(() => { autoUpdater.checkForUpdates(); }, ms(updateInterval)); + + let isLookingForUpdates = true; + + return { + isSupported: true, + get isLookingForUpdates() { + return isLookingForUpdates; + }, + stopLookingForUpdates() { + if (isLookingForUpdates) { + clearInterval(intervalID); + isLookingForUpdates = false; + } + }, + startLookingForUpdates() { + if (!isLookingForUpdates) { + intervalID = setInterval(() => { + autoUpdater.checkForUpdates(); + }, ms(updateInterval)); + isLookingForUpdates = true; + } + }, + }; } /** From ac9ee2ee0ee10449306f785fd205b815efe25738 Mon Sep 17 00:00:00 2001 From: Arthur Lobo <64273139+ArthurLobopro@users.noreply.github.com> Date: Thu, 13 Feb 2025 22:58:01 -0300 Subject: [PATCH 2/5] Update test.yml --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ac6a4af..cd80227 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,6 +7,7 @@ on: schedule: - cron: '0 22 * * 3' workflow_call: + workflow_dispatch: permissions: contents: read From e24e1284b0121981601f64715ae7a9322856d3ea Mon Sep 17 00:00:00 2001 From: Arthur Lobo <64273139+ArthurLobopro@users.noreply.github.com> Date: Thu, 13 Feb 2025 23:16:11 -0300 Subject: [PATCH 3/5] fix: update tests to be async --- test/index.test.ts | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/test/index.test.ts b/test/index.test.ts index f45de9b..a7d25ae 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -25,18 +25,19 @@ describe('updateElectronApp', () => { describe('repository', () => { const tmpdir = os.tmpdir(); const packageJson = path.join(tmpdir, 'package.json'); + beforeAll(() => { fs.writeFileSync(packageJson, JSON.stringify({})); }); it('is required', () => { - expect(() => { - updateElectronApp(); - }).toThrow("repo not found. Add repository string to your app's package.json file"); + expect(async () => { + await updateElectronApp(); + }).rejects.toThrow("repo not found. Add repository string to your app's package.json file"); }); - it('from opts', () => { - updateElectronApp({ repo: 'foo/bar' }); + it('from opts', async () => { + await updateElectronApp({ repo: 'foo/bar' }); }); it('from package.json', () => { @@ -51,13 +52,13 @@ describe('updateElectronApp', () => { describe('host', () => { it('must a valid HTTPS URL', () => { - expect(() => { - updateElectronApp({ repo, host: 'http://example.com' }); - }).toThrow('host must be a valid HTTPS URL'); + expect(async () => { + await updateElectronApp({ repo, host: 'http://example.com' }); + }).rejects.toThrow('host must be a valid HTTPS URL'); }); - it('from default', () => { - updateElectronApp({ + it('from default', async () => { + await updateElectronApp({ updateSource: { type: UpdateSourceType.ElectronPublicUpdateService, repo, @@ -68,9 +69,9 @@ describe('updateElectronApp', () => { describe('updateInterval', () => { it('must be 5 minutes or more', () => { - expect(() => { - updateElectronApp({ repo, updateInterval: '20 seconds' }); - }).toThrow('updateInterval must be `5 minutes` or more'); + expect(async () => { + await updateElectronApp({ repo, updateInterval: '20 seconds' }); + }).rejects.toThrow('updateInterval must be `5 minutes` or more'); }); }); }); From f4645959234351d0a01dbdbc1dbaab340a3ff45f Mon Sep 17 00:00:00 2001 From: Arthur Lobo <64273139+ArthurLobopro@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:00:01 -0300 Subject: [PATCH 4/5] refactor: turn updateElectronApp sync again --- src/index.ts | 59 +++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/src/index.ts b/src/index.ts index 7492f17..5dd8f1a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -135,33 +135,36 @@ const isHttpsUrl = (maybeURL: string) => { } }; -export async function updateElectronApp(opts: IUpdateElectronAppOptions = {}): Promise { - return new Promise((resolve, reject) => { - // check for bad input early, so it will be logged during development - const safeOpts = validateInput(opts); - - // don't attempt to update during development - if (!app.isPackaged) { - const message = - 'update-electron-app config looks good; aborting updates since app is in development mode'; - if (opts.logger) { - opts.logger.log(message); - } else { - console.log(message); - } - - return reject(); - } - - if (app.isReady()) { - resolve(initUpdater(safeOpts)); +export function updateElectronApp(opts: IUpdateElectronAppOptions = {}): IUpdater { + // check for bad input early, so it will be logged during development + const safeOpts = validateInput(opts); + + // don't attempt to update during development + if (!app.isPackaged) { + const message = + 'update-electron-app config looks good; aborting updates since app is in development mode'; + if (opts.logger) { + opts.logger.log(message); } else { - app.on('ready', () => resolve(initUpdater(safeOpts))); + console.log(message); } - }); + + //Return Updater but does not start + return makeUpdater(safeOpts); + } + + const updater = makeUpdater(safeOpts); + + if (app.isReady()) { + updater.startLookingForUpdates(); + } else { + app.on('ready', () => updater.startLookingForUpdates()); + } + + return updater; } -function initUpdater(opts: ReturnType): IUpdater { +function makeUpdater(opts: ReturnType): IUpdater { const { updateSource, updateInterval, logger } = opts; // exit early on unsupported platforms, e.g. `linux` @@ -256,14 +259,8 @@ function initUpdater(opts: ReturnType): IUpdater { ); } - // check for updates right away and keep checking later - autoUpdater.checkForUpdates(); - - let intervalID = setInterval(() => { - autoUpdater.checkForUpdates(); - }, ms(updateInterval)); - - let isLookingForUpdates = true; + let intervalID: ReturnType; + let isLookingForUpdates = false; return { isSupported: true, From 08a389c8f52d75adc8561d4e3005982c93da1a1d Mon Sep 17 00:00:00 2001 From: Arthur Lobo <64273139+ArthurLobopro@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:00:15 -0300 Subject: [PATCH 5/5] Revert "fix: update tests to be async" This reverts commit e24e1284b0121981601f64715ae7a9322856d3ea. --- test/index.test.ts | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/test/index.test.ts b/test/index.test.ts index a7d25ae..f45de9b 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -25,19 +25,18 @@ describe('updateElectronApp', () => { describe('repository', () => { const tmpdir = os.tmpdir(); const packageJson = path.join(tmpdir, 'package.json'); - beforeAll(() => { fs.writeFileSync(packageJson, JSON.stringify({})); }); it('is required', () => { - expect(async () => { - await updateElectronApp(); - }).rejects.toThrow("repo not found. Add repository string to your app's package.json file"); + expect(() => { + updateElectronApp(); + }).toThrow("repo not found. Add repository string to your app's package.json file"); }); - it('from opts', async () => { - await updateElectronApp({ repo: 'foo/bar' }); + it('from opts', () => { + updateElectronApp({ repo: 'foo/bar' }); }); it('from package.json', () => { @@ -52,13 +51,13 @@ describe('updateElectronApp', () => { describe('host', () => { it('must a valid HTTPS URL', () => { - expect(async () => { - await updateElectronApp({ repo, host: 'http://example.com' }); - }).rejects.toThrow('host must be a valid HTTPS URL'); + expect(() => { + updateElectronApp({ repo, host: 'http://example.com' }); + }).toThrow('host must be a valid HTTPS URL'); }); - it('from default', async () => { - await updateElectronApp({ + it('from default', () => { + updateElectronApp({ updateSource: { type: UpdateSourceType.ElectronPublicUpdateService, repo, @@ -69,9 +68,9 @@ describe('updateElectronApp', () => { describe('updateInterval', () => { it('must be 5 minutes or more', () => { - expect(async () => { - await updateElectronApp({ repo, updateInterval: '20 seconds' }); - }).rejects.toThrow('updateInterval must be `5 minutes` or more'); + expect(() => { + updateElectronApp({ repo, updateInterval: '20 seconds' }); + }).toThrow('updateInterval must be `5 minutes` or more'); }); }); });