diff --git a/package.json b/package.json index 16766a9..c4be124 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "awesome-typescript-loader": "^5.2.0", "codelyzer": "~4.2.1", "core-js": "^2.5.4", + "dexie": "^2.0.4", "devtron": "^1.4.0", "electron": "^2.0.7", "electron-builder": "^20.27.1", diff --git a/src/commons/model/index.ts b/src/commons/model/index.ts new file mode 100644 index 0000000..59f8a92 --- /dev/null +++ b/src/commons/model/index.ts @@ -0,0 +1 @@ +export * from './launch-state'; diff --git a/src/commons/model/launch-state.ts b/src/commons/model/launch-state.ts new file mode 100644 index 0000000..b2bfda0 --- /dev/null +++ b/src/commons/model/launch-state.ts @@ -0,0 +1,20 @@ +/** The timing stats for app launch. */ +export interface LaunchState { + /** + * The time (in milliseconds) it takes from when our main process code is + * first loaded until the app `ready` event is emitted. + */ + readonly mainReadyTime: number + + /** + * The time (in milliseconds) it takes from when loading begins to loading + * end. + */ + readonly loadTime: number + + /** + * The time (in milliseconds) it takes from when our renderer process code is + * first loaded until the renderer `ready` event is emitted. + */ + readonly rendererReadyTime: number +} diff --git a/src/commons/service/database.service.ts b/src/commons/service/database.service.ts new file mode 100644 index 0000000..3ceca02 --- /dev/null +++ b/src/commons/service/database.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; +import Dexie from 'dexie'; +import { LaunchState } from '../model'; + +const DatabaseVersion = 1; + +@Injectable({ + providedIn: 'root' +}) +export class DatabaseService extends Dexie { + + public launches!: Dexie.Table + + + public constructor() { + super('overflow-scanner'); + this.version(1).stores({ + launches: '++', + }); + + } + +} diff --git a/src/commons/service/electron-proxy.service.ts b/src/commons/service/electron-proxy.service.ts index ab45415..b6ddc6b 100644 --- a/src/commons/service/electron-proxy.service.ts +++ b/src/commons/service/electron-proxy.service.ts @@ -1,13 +1,48 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; - +import { Observable, of } from 'rxjs'; +import { catchError, exhaustMap, map, tap, take } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; import { ipcRenderer } from 'electron'; -@Injectable() +import { MenuEvent } from '../type'; +import { LaunchState } from '../model'; +import { LaunchService } from './launch.service'; + +@Injectable({ + providedIn: 'root' +}) export class ElectronProxyService { public constructor( + private store: Store, + private launchService: LaunchService, ) { + this.bindIPCRenderer(); + } + + private bindIPCRenderer(): void { + ipcRenderer.on('menu-event', + (event: Electron.IpcMessageEvent, { name }: { name: MenuEvent }) => { + + } + ); + + ipcRenderer.on('launch-timing-stats', + (event: Electron.IpcMessageEvent, { state }: { state: LaunchState }) => { + console.info(`App ready time: ${state.mainReadyTime}ms`) + console.info(`Load time: ${state.loadTime}ms`) + console.info(`Renderer ready time: ${state.rendererReadyTime}ms`) + + this.launchService.save(state).pipe( + map((id: number) => { + }), + catchError(error => { + return of(); + }), + take(1), + ).subscribe(); + } + ) } public sendReady(time: number): void { diff --git a/src/commons/service/index.ts b/src/commons/service/index.ts index f9f0f35..70c0b38 100644 --- a/src/commons/service/index.ts +++ b/src/commons/service/index.ts @@ -1,5 +1,9 @@ +import { DatabaseService } from './database.service'; import { ElectronProxyService } from './electron-proxy.service'; +import { LaunchService } from './launch.service'; export const SERVICES = [ + DatabaseService, ElectronProxyService, + LaunchService, ]; diff --git a/src/commons/service/launch.service.ts b/src/commons/service/launch.service.ts new file mode 100644 index 0000000..e5d1792 --- /dev/null +++ b/src/commons/service/launch.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { Observable, defer } from 'rxjs'; + +import { DatabaseService } from './database.service'; +import { LaunchState } from '../model'; + + +@Injectable({ + providedIn: 'root' +}) +export class LaunchService { + + public constructor( + private readonly databaseService: DatabaseService, + ) { + } + + public save(launchState: LaunchState): Observable { + return defer(async () => { + return await this.databaseService.launches.add(launchState); + }); + } + +} diff --git a/src/electron/menu/index.ts b/src/commons/type/index.ts similarity index 100% rename from src/electron/menu/index.ts rename to src/commons/type/index.ts diff --git a/src/electron/menu/menu-event.ts b/src/commons/type/menu-event.ts similarity index 100% rename from src/electron/menu/menu-event.ts rename to src/commons/type/menu-event.ts diff --git a/src/electron/menu/menu-ids.ts b/src/commons/type/menu-ids.ts similarity index 100% rename from src/electron/menu/menu-ids.ts rename to src/commons/type/menu-ids.ts diff --git a/src/electron/app-window.ts b/src/electron/app-window.ts index 1a46536..df67fa0 100644 --- a/src/electron/app-window.ts +++ b/src/electron/app-window.ts @@ -11,7 +11,8 @@ import { registerWindowStateChangedEvents } from '@overflow/core/window-state'; import { URLActionType } from '@overflow/core/parse-app-url'; import { now } from '@overflow/core/now'; -import { MenuEvent } from './menu'; +import { MenuEvent } from '../commons/type'; +import { LaunchState } from '../commons/model'; let windowStateKeeper: any | null = null; @@ -217,9 +218,9 @@ export class AppWindow { } /** Send the app launch timing stats to the renderer. */ - // public sendLaunchTimingStats(stats: ILaunchStats) { - // this.window.webContents.send('launch-timing-stats', { stats }); - // } + public sendLaunchTimingStats(state: LaunchState) { + this.window.webContents.send('launch-timing-stats', { state }); + } /** Send the app menu to the renderer. */ // public sendAppMenu() { diff --git a/src/electron/main.ts b/src/electron/main.ts index 3e3ba11..d935bd5 100644 --- a/src/electron/main.ts +++ b/src/electron/main.ts @@ -27,7 +27,7 @@ let readyTime: number | null = null; type OnDidLoadFn = (window: AppWindow) => void; /** See the `onDidLoad` function. */ -const onDidLoadFns: Array | null = []; +let onDidLoadFns: Array | null = []; function handleUncaughtException(error: Error) { preventQuit = true; @@ -428,17 +428,17 @@ function createWindow() { window.onDidLoad((data: any) => { window.show(); - // window.sendLaunchTimingStats({ - // mainReadyTime: readyTime!, - // loadTime: window.loadTime!, - // rendererReadyTime: window.rendererReadyTime!, - // }); + window.sendLaunchTimingStats({ + mainReadyTime: readyTime!, + loadTime: window.loadTime!, + rendererReadyTime: window.rendererReadyTime!, + }); - // const fns = onDidLoadFns!; - // onDidLoadFns = null; - // for (const fn of fns) { - // fn(window); - // } + let fns = onDidLoadFns!; + onDidLoadFns = null; + for (const fn of fns) { + fn(window); + } }); window.load(); diff --git a/yarn.lock b/yarn.lock index 65706f4..b5f95bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1969,6 +1969,10 @@ devtron@^1.4.0: highlight.js "^9.3.0" humanize-plus "^1.8.1" +dexie@^2.0.4: + version "2.0.4" + resolved "https://nexus.loafle.net/repository/npm-all/dexie/-/dexie-2.0.4.tgz#6027a5e05879424e8f9979d8c14e7420f27e3a11" + di@^0.0.1: version "0.0.1" resolved "https://nexus.loafle.net/repository/npm-all/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"