Skip to content

Commit

Permalink
refactor: refactor main package (#1042)
Browse files Browse the repository at this point in the history
  • Loading branch information
cawa-93 authored Nov 9, 2024
2 parents 8e14756 + acbaa75 commit e608283
Show file tree
Hide file tree
Showing 23 changed files with 418 additions and 297 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@



node_modules
.DS_Store
dist
Expand Down
5 changes: 5 additions & 0 deletions .idea/runConfigurations/Attach_Debugger.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion .idea/vite-electron-builder.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion .npmrc

This file was deleted.

1 change: 1 addition & 0 deletions packages/entry-point.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ if (process.env.NODE_ENV === 'development' || process.env.PLAYWRIGHT_TEST === 't
process.on('unhandledRejection', showAndExit);
}

// noinspection JSIgnoredPromiseFromCall
/**
* We resolve '@vite-electron-builder/renderer' and '@vite-electron-builder/preload'
* here and not in '@vite-electron-builder/main'
Expand Down
1 change: 1 addition & 0 deletions packages/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
},
"devDependencies": {
"@vite-electron-builder/electron-versions": "*",
"electron-devtools-installer": "^3.2.0",
"typescript": "5.6.3",
"vite": "5.4.10"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/main/src/AppModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type {ModuleContext} from './ModuleContext.js';

export interface AppModule {
enable(context: ModuleContext): Promise<void>|void;
}
3 changes: 3 additions & 0 deletions packages/main/src/ModuleContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type ModuleContext = {
readonly app: Electron.App;
}
35 changes: 35 additions & 0 deletions packages/main/src/ModuleRunner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {AppModule} from './AppModule.js';
import {ModuleContext} from './ModuleContext.js';
import {app} from 'electron';

class ModuleRunner implements PromiseLike<void> {
#promise: Promise<void>;

constructor() {
this.#promise = Promise.resolve();
}

then<TResult1 = void, TResult2 = never>(onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): PromiseLike<TResult1 | TResult2> {
return this.#promise.then(onfulfilled, onrejected);
}

init(module: AppModule) {
const p = module.enable(this.#createModuleContext());

if (p instanceof Promise) {
this.#promise = this.#promise.then(() => p);
}

return this;
}

#createModuleContext(): ModuleContext {
return {
app,
};
}
}

export function createModuleRunner() {
return new ModuleRunner();
}
24 changes: 0 additions & 24 deletions packages/main/src/auto-updater.ts

This file was deleted.

66 changes: 0 additions & 66 deletions packages/main/src/createWindowManager.ts

This file was deleted.

117 changes: 44 additions & 73 deletions packages/main/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,46 @@
import {app} from 'electron';
import './security-restrictions';
import {platform} from 'node:process';
import type {AppInitConfig} from './AppInitConfig.js';
import {createWindowManager} from './createWindowManager.js';
import {runAutoUpdater} from './auto-updater.js';

// Used in packages/entry-point.js
export function initApp(initConfig: AppInitConfig) {
const {restoreOrCreateWindow} = createWindowManager({
preload: initConfig.preload,
renderer: initConfig.renderer,
});

/**
* Prevent electron from running multiple instances.
*/
const isSingleInstance = app.requestSingleInstanceLock();
if (!isSingleInstance) {
app.quit();
process.exit(0);
}
app.on('second-instance', restoreOrCreateWindow);

/**
* Disable Hardware Acceleration to save more system resources.
*/
app.disableHardwareAcceleration();

/**
* Shout down background process if all windows was closed
*/
app.on('window-all-closed', () => {
if (platform !== 'darwin') {
app.quit();
}
});

/**
* @see https://www.electronjs.org/docs/latest/api/app#event-activate-macos Event: 'activate'.
*/
app.on('activate', restoreOrCreateWindow);

/**
* Create the application window when the background process is ready.
*/
app
.whenReady()
.then(restoreOrCreateWindow)
.catch(e => console.error('Failed create window:', e));

/**
* Install any extension in development mode only.
* Note: You must install `electron-devtools-installer` manually
*/
// if (import.meta.env.DEV) {
// app
// .whenReady()
// .then(() => import('electron-devtools-installer'))
// .then(module => {
// const {default: installExtension, VUEJS_DEVTOOLS} =
// //@ts-expect-error Hotfix for https://github.com/cawa-93/vite-electron-builder/issues/915
// typeof module.default === 'function' ? module : (module.default as typeof module);
//
// return installExtension(VUEJS_DEVTOOLS, {
// loadExtensionOptions: {
// allowFileAccess: true,
// },
// });
// })
// .catch(e => console.error('Failed install extension:', e));
// }

runAutoUpdater();
import {createModuleRunner} from './ModuleRunner.js';
import {disallowMultipleAppInstance} from './modules/SingleInstanceApp.js';
import {createWindowManagerModule} from './modules/WindowManager.js';
import {terminateAppOnLastWindowClose} from './modules/ApplicationTerminatorOnLastWindowClose.js';
import {hardwareAccelerationMode} from './modules/HardwareAccelerationModule.js';
import {autoUpdater} from './modules/AutoUpdater.js';
import {allowInternalOrigins} from './modules/BlockNotAllowdOrigins.js';
import {allowExternalUrls} from './modules/ExternalUrls.js';


export async function initApp(initConfig: AppInitConfig) {
const moduleRunner = createModuleRunner()
.init(createWindowManagerModule({initConfig, openDevTools: import.meta.env.DEV}))
.init(disallowMultipleAppInstance())
.init(terminateAppOnLastWindowClose())
.init(hardwareAccelerationMode({enable: false}))
.init(autoUpdater())

// Install DevTools extension if needed
// .init(chromeDevToolsExtension({extension: 'VUEJS3_DEVTOOLS'}))

// Security
.init(allowInternalOrigins(
new Set(initConfig.renderer instanceof URL ? [initConfig.renderer.origin] : []),
))
.init(allowExternalUrls(
new Set(
initConfig.renderer instanceof URL
? [
'https://vite.dev',
'https://developer.mozilla.org',
'https://solidjs.com',
'https://qwik.dev',
'https://lit.dev',
'https://react.dev',
'https://preactjs.com',
'https://www.typescriptlang.org',
'https://vuejs.org',
]
: [],
)),
);

await moduleRunner;
}
10 changes: 10 additions & 0 deletions packages/main/src/modules/AbstractSecurityModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {AppModule} from '../AppModule.js';
import {ModuleContext} from '../ModuleContext.js';

export abstract class AbstractSecurityRule implements AppModule {
enable({app}: ModuleContext): Promise<void> | void {
app.on('web-contents-created', (_, contents) => this.applyRule(contents))
}

abstract applyRule(contents: Electron.WebContents): Promise<void> | void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {AppModule} from '../AppModule.js';
import {ModuleContext} from '../ModuleContext.js';

class ApplicationTerminatorOnLastWindowClose implements AppModule {
enable({app}: ModuleContext): Promise<void> | void {
app.on('window-all-closed', () => app.quit());
}
}


export function terminateAppOnLastWindowClose(...args: ConstructorParameters<typeof ApplicationTerminatorOnLastWindowClose>) {
return new ApplicationTerminatorOnLastWindowClose(...args);
}
58 changes: 58 additions & 0 deletions packages/main/src/modules/AutoUpdater.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {AppModule} from '../AppModule.js';
import electronUpdater, {type AppUpdater, type Logger} from 'electron-updater';

type DownloadNotification = Parameters<AppUpdater['checkForUpdatesAndNotify']>[0];

export class AutoUpdater implements AppModule {

readonly #logger: Logger | null;
readonly #notification: DownloadNotification;

constructor(
{
logger = null,
downloadNotification = undefined,
}:
{
logger?: Logger | null | undefined,
downloadNotification?: DownloadNotification
} = {},
) {
this.#logger = logger;
this.#notification = downloadNotification;
}

async enable(): Promise<void> {
await this.runAutoUpdater();
}

getAutoUpdater(): AppUpdater {
// Using destructuring to access autoUpdater due to the CommonJS module of 'electron-updater'.
// It is a workaround for ESM compatibility issues, see https://github.com/electron-userland/electron-builder/issues/7976.
const {autoUpdater} = electronUpdater;
return autoUpdater;
}

async runAutoUpdater() {
const updater = this.getAutoUpdater();
try {
updater.logger = this.#logger || null;
updater.fullChangelog = true;

return await updater.checkForUpdatesAndNotify(this.#notification);
} catch (error) {
if (error instanceof Error) {
if (error.message.includes('No published versions')) {
return null;
}
}

throw error;
}
}
}


export function autoUpdater(...args: ConstructorParameters<typeof AutoUpdater>) {
return new AutoUpdater(...args);
}
Loading

0 comments on commit e608283

Please sign in to comment.