diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-01-08 21:36:43 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-01-09 19:53:03 +0100 |
commit | d07e7b834831230b53860d0919a68edc2d36193d (patch) | |
tree | a1f2a021563ddff54f33341c475fc6c6eb787388 /packages/main/src | |
parent | New configurations based on review comments (WIP) (diff) | |
download | sophie-d07e7b834831230b53860d0919a68edc2d36193d.tar.gz sophie-d07e7b834831230b53860d0919a68edc2d36193d.tar.zst sophie-d07e7b834831230b53860d0919a68edc2d36193d.zip |
build: Eslint fixes for multi-module project
Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages/main/src')
-rw-r--r-- | packages/main/src/controllers/__tests__/initConfig.spec.ts (renamed from packages/main/src/controllers/__tests__/config.spec.ts) | 18 | ||||
-rw-r--r-- | packages/main/src/controllers/__tests__/initNativeTheme.spec.ts (renamed from packages/main/src/controllers/__tests__/nativeTheme.spec.ts) | 4 | ||||
-rw-r--r-- | packages/main/src/controllers/initConfig.ts (renamed from packages/main/src/controllers/config.ts) | 12 | ||||
-rw-r--r-- | packages/main/src/controllers/initNativeTheme.ts (renamed from packages/main/src/controllers/nativeTheme.ts) | 8 | ||||
-rw-r--r-- | packages/main/src/devTools.ts | 7 | ||||
-rw-r--r-- | packages/main/src/index.ts | 109 | ||||
-rw-r--r-- | packages/main/src/init.ts (renamed from packages/main/src/compositionRoot.ts) | 10 | ||||
-rw-r--r-- | packages/main/src/services/ConfigPersistenceService.ts | 6 | ||||
-rw-r--r-- | packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts | 20 | ||||
-rw-r--r-- | packages/main/src/stores/Config.ts | 2 | ||||
-rw-r--r-- | packages/main/src/stores/MainStore.ts | 2 | ||||
-rw-r--r-- | packages/main/src/stores/SharedStore.ts | 2 | ||||
-rw-r--r-- | packages/main/src/utils/Disposer.ts (renamed from packages/main/src/utils/disposer.ts) | 4 | ||||
-rw-r--r-- | packages/main/src/utils/log.ts (renamed from packages/main/src/utils/logging.ts) | 10 |
14 files changed, 122 insertions, 92 deletions
diff --git a/packages/main/src/controllers/__tests__/config.spec.ts b/packages/main/src/controllers/__tests__/initConfig.spec.ts index eb67df0..e386a07 100644 --- a/packages/main/src/controllers/__tests__/config.spec.ts +++ b/packages/main/src/controllers/__tests__/initConfig.spec.ts | |||
@@ -22,20 +22,20 @@ import { jest } from '@jest/globals'; | |||
22 | import { mocked } from 'jest-mock'; | 22 | import { mocked } from 'jest-mock'; |
23 | import ms from 'ms'; | 23 | import ms from 'ms'; |
24 | 24 | ||
25 | import { initConfig } from '../config'; | 25 | import type ConfigPersistenceService from '../../services/ConfigPersistenceService'; |
26 | import type { ConfigPersistenceService } from '../../services/ConfigPersistenceService'; | ||
27 | import { Config, config as configModel } from '../../stores/Config'; | 26 | import { Config, config as configModel } from '../../stores/Config'; |
28 | import { Disposer } from '../../utils/disposer'; | 27 | import type Disposer from '../../utils/Disposer'; |
29 | import { silenceLogger } from '../../utils/logging'; | 28 | import { silenceLogger } from '../../utils/log'; |
29 | import initConfig from '../initConfig'; | ||
30 | 30 | ||
31 | let config: Config; | 31 | let config: Config; |
32 | let persistenceService: ConfigPersistenceService = { | 32 | const persistenceService: ConfigPersistenceService = { |
33 | readConfig: jest.fn(), | 33 | readConfig: jest.fn(), |
34 | writeConfig: jest.fn(), | 34 | writeConfig: jest.fn(), |
35 | watchConfig: jest.fn(), | 35 | watchConfig: jest.fn(), |
36 | }; | 36 | }; |
37 | let lessThanThrottleMs = ms('0.1s'); | 37 | const lessThanThrottleMs = ms('0.1s'); |
38 | let throttleMs = ms('1s'); | 38 | const throttleMs = ms('1s'); |
39 | 39 | ||
40 | beforeAll(() => { | 40 | beforeAll(() => { |
41 | jest.useFakeTimers(); | 41 | jest.useFakeTimers(); |
@@ -108,7 +108,7 @@ describe('when initializing', () => { | |||
108 | 108 | ||
109 | describe('when it has loaded the config', () => { | 109 | describe('when it has loaded the config', () => { |
110 | let sutDisposer: Disposer; | 110 | let sutDisposer: Disposer; |
111 | let watcherDisposer: Disposer = jest.fn(); | 111 | const watcherDisposer: Disposer = jest.fn(); |
112 | let configChangedCallback: () => Promise<void>; | 112 | let configChangedCallback: () => Promise<void>; |
113 | 113 | ||
114 | beforeEach(async () => { | 114 | beforeEach(async () => { |
@@ -118,7 +118,7 @@ describe('when it has loaded the config', () => { | |||
118 | }); | 118 | }); |
119 | mocked(persistenceService.watchConfig).mockReturnValueOnce(watcherDisposer); | 119 | mocked(persistenceService.watchConfig).mockReturnValueOnce(watcherDisposer); |
120 | sutDisposer = await initConfig(config, persistenceService, throttleMs); | 120 | sutDisposer = await initConfig(config, persistenceService, throttleMs); |
121 | configChangedCallback = mocked(persistenceService.watchConfig).mock.calls[0][0]; | 121 | [[configChangedCallback]] = mocked(persistenceService.watchConfig).mock.calls; |
122 | jest.resetAllMocks(); | 122 | jest.resetAllMocks(); |
123 | }); | 123 | }); |
124 | 124 | ||
diff --git a/packages/main/src/controllers/__tests__/nativeTheme.spec.ts b/packages/main/src/controllers/__tests__/initNativeTheme.spec.ts index 85d6dd2..bd33f48 100644 --- a/packages/main/src/controllers/__tests__/nativeTheme.spec.ts +++ b/packages/main/src/controllers/__tests__/initNativeTheme.spec.ts | |||
@@ -22,7 +22,7 @@ import { jest } from '@jest/globals'; | |||
22 | import { mocked } from 'jest-mock'; | 22 | import { mocked } from 'jest-mock'; |
23 | 23 | ||
24 | import { createMainStore, MainStore } from '../../stores/MainStore'; | 24 | import { createMainStore, MainStore } from '../../stores/MainStore'; |
25 | import { Disposer } from '../../utils/disposer'; | 25 | import type Disposer from '../../utils/Disposer'; |
26 | 26 | ||
27 | let shouldUseDarkColors = false; | 27 | let shouldUseDarkColors = false; |
28 | 28 | ||
@@ -38,7 +38,7 @@ jest.unstable_mockModule('electron', () => ({ | |||
38 | })); | 38 | })); |
39 | 39 | ||
40 | const { nativeTheme } = await import('electron'); | 40 | const { nativeTheme } = await import('electron'); |
41 | const { initNativeTheme } = await import('../nativeTheme'); | 41 | const { default: initNativeTheme } = await import('../initNativeTheme'); |
42 | 42 | ||
43 | let store: MainStore; | 43 | let store: MainStore; |
44 | let disposeSut: Disposer; | 44 | let disposeSut: Disposer; |
diff --git a/packages/main/src/controllers/config.ts b/packages/main/src/controllers/initConfig.ts index deaeac2..1d40762 100644 --- a/packages/main/src/controllers/config.ts +++ b/packages/main/src/controllers/initConfig.ts | |||
@@ -19,19 +19,19 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { debounce } from 'lodash-es'; | 21 | import { debounce } from 'lodash-es'; |
22 | import ms from 'ms'; | ||
23 | import { applySnapshot, getSnapshot, onSnapshot } from 'mobx-state-tree'; | 22 | import { applySnapshot, getSnapshot, onSnapshot } from 'mobx-state-tree'; |
23 | import ms from 'ms'; | ||
24 | 24 | ||
25 | import type { ConfigPersistenceService } from '../services/ConfigPersistenceService.js'; | 25 | import type ConfigPersistenceService from '../services/ConfigPersistenceService'; |
26 | import type { Config, ConfigSnapshotOut } from '../stores/Config.js'; | 26 | import type { Config, ConfigSnapshotOut } from '../stores/Config'; |
27 | import { Disposer } from '../utils/disposer'; | 27 | import type Disposer from '../utils/Disposer'; |
28 | import { getLogger } from '../utils/logging'; | 28 | import { getLogger } from '../utils/log'; |
29 | 29 | ||
30 | const DEFAULT_CONFIG_DEBOUNCE_TIME = ms('1s'); | 30 | const DEFAULT_CONFIG_DEBOUNCE_TIME = ms('1s'); |
31 | 31 | ||
32 | const log = getLogger('config'); | 32 | const log = getLogger('config'); |
33 | 33 | ||
34 | export async function initConfig( | 34 | export default async function initConfig( |
35 | config: Config, | 35 | config: Config, |
36 | persistenceService: ConfigPersistenceService, | 36 | persistenceService: ConfigPersistenceService, |
37 | debounceTime: number = DEFAULT_CONFIG_DEBOUNCE_TIME, | 37 | debounceTime: number = DEFAULT_CONFIG_DEBOUNCE_TIME, |
diff --git a/packages/main/src/controllers/nativeTheme.ts b/packages/main/src/controllers/initNativeTheme.ts index ccd12d8..d2074ab 100644 --- a/packages/main/src/controllers/nativeTheme.ts +++ b/packages/main/src/controllers/initNativeTheme.ts | |||
@@ -21,13 +21,13 @@ | |||
21 | import { nativeTheme } from 'electron'; | 21 | import { nativeTheme } from 'electron'; |
22 | import { autorun } from 'mobx'; | 22 | import { autorun } from 'mobx'; |
23 | 23 | ||
24 | import type { MainStore } from '../stores/MainStore.js'; | 24 | import type { MainStore } from '../stores/MainStore'; |
25 | import { Disposer } from '../utils/disposer'; | 25 | import type Disposer from '../utils/Disposer'; |
26 | import { getLogger } from '../utils/logging'; | 26 | import { getLogger } from '../utils/log'; |
27 | 27 | ||
28 | const log = getLogger('nativeTheme'); | 28 | const log = getLogger('nativeTheme'); |
29 | 29 | ||
30 | export function initNativeTheme(store: MainStore): Disposer { | 30 | export default function initNativeTheme(store: MainStore): Disposer { |
31 | log.trace('Initializing nativeTheme controller'); | 31 | log.trace('Initializing nativeTheme controller'); |
32 | 32 | ||
33 | const disposeThemeSourceReaction = autorun(() => { | 33 | const disposeThemeSourceReaction = autorun(() => { |
diff --git a/packages/main/src/devTools.ts b/packages/main/src/devTools.ts index 398904c..0486c36 100644 --- a/packages/main/src/devTools.ts +++ b/packages/main/src/devTools.ts | |||
@@ -46,7 +46,12 @@ export async function installDevToolsExtensions(): Promise<void> { | |||
46 | default: installExtension, | 46 | default: installExtension, |
47 | REACT_DEVELOPER_TOOLS, | 47 | REACT_DEVELOPER_TOOLS, |
48 | REDUX_DEVTOOLS, | 48 | REDUX_DEVTOOLS, |
49 | } = require('electron-devtools-installer'); | 49 | /* eslint-disable-next-line |
50 | import/no-extraneous-dependencies, | ||
51 | global-require, | ||
52 | @typescript-eslint/no-var-requires | ||
53 | */ | ||
54 | } = require('electron-devtools-installer') as typeof import('electron-devtools-installer'); | ||
50 | await installExtension( | 55 | await installExtension( |
51 | [ | 56 | [ |
52 | REACT_DEVELOPER_TOOLS, | 57 | REACT_DEVELOPER_TOOLS, |
diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts index d0191b7..bc10b4c 100644 --- a/packages/main/src/index.ts +++ b/packages/main/src/index.ts | |||
@@ -19,18 +19,10 @@ | |||
19 | * SPDX-License-Identifier: AGPL-3.0-only | 19 | * SPDX-License-Identifier: AGPL-3.0-only |
20 | */ | 20 | */ |
21 | 21 | ||
22 | import { | ||
23 | app, | ||
24 | BrowserView, | ||
25 | BrowserWindow, | ||
26 | ipcMain, | ||
27 | } from 'electron'; | ||
28 | import { arch } from 'os'; | 22 | import { arch } from 'os'; |
29 | import osName from 'os-name'; | ||
30 | import { ensureDirSync, readFile, readFileSync } from 'fs-extra'; | ||
31 | import { autorun } from 'mobx'; | ||
32 | import { getSnapshot, onPatch } from 'mobx-state-tree'; | ||
33 | import { join } from 'path'; | 23 | import { join } from 'path'; |
24 | import { URL } from 'url'; | ||
25 | |||
34 | import { | 26 | import { |
35 | ServiceToMainIpcMessage, | 27 | ServiceToMainIpcMessage, |
36 | unreadCount, | 28 | unreadCount, |
@@ -41,18 +33,30 @@ import { | |||
41 | MainToRendererIpcMessage, | 33 | MainToRendererIpcMessage, |
42 | RendererToMainIpcMessage, | 34 | RendererToMainIpcMessage, |
43 | } from '@sophie/shared'; | 35 | } from '@sophie/shared'; |
44 | import { URL } from 'url'; | 36 | import { |
37 | app, | ||
38 | BrowserView, | ||
39 | BrowserWindow, | ||
40 | ipcMain, | ||
41 | } from 'electron'; | ||
42 | import { ensureDirSync, readFile, readFileSync } from 'fs-extra'; | ||
43 | import { autorun } from 'mobx'; | ||
44 | import { getSnapshot, onPatch } from 'mobx-state-tree'; | ||
45 | import osName from 'os-name'; | ||
45 | 46 | ||
46 | import { init } from './compositionRoot'; | ||
47 | import { | 47 | import { |
48 | DEVMODE_ALLOWED_URL_PREFIXES, | 48 | DEVMODE_ALLOWED_URL_PREFIXES, |
49 | installDevToolsExtensions, | 49 | installDevToolsExtensions, |
50 | openDevToolsWhenReady, | 50 | openDevToolsWhenReady, |
51 | } from './devTools'; | 51 | } from './devTools'; |
52 | import init from './init'; | ||
52 | import { createMainStore } from './stores/MainStore'; | 53 | import { createMainStore } from './stores/MainStore'; |
54 | import { getLogger } from './utils/log'; | ||
53 | 55 | ||
54 | const isDevelopment = import.meta.env.MODE === 'development'; | 56 | const isDevelopment = import.meta.env.MODE === 'development'; |
55 | 57 | ||
58 | const log = getLogger('index'); | ||
59 | |||
56 | // Always enable sandboxing. | 60 | // Always enable sandboxing. |
57 | app.enableSandbox(); | 61 | app.enableSandbox(); |
58 | 62 | ||
@@ -93,7 +97,7 @@ app.setAboutPanelOptions({ | |||
93 | `Node.js: ${process.versions.node}`, | 97 | `Node.js: ${process.versions.node}`, |
94 | `Platform: ${osName()}`, | 98 | `Platform: ${osName()}`, |
95 | `Arch: ${arch()}`, | 99 | `Arch: ${arch()}`, |
96 | `Build date: ${new Date(Number(import.meta.env.BUILD_DATE))}`, | 100 | `Build date: ${new Date(Number(import.meta.env.BUILD_DATE)).toLocaleString()}`, |
97 | `Git SHA: ${import.meta.env.GIT_SHA}`, | 101 | `Git SHA: ${import.meta.env.GIT_SHA}`, |
98 | `Git branch: ${import.meta.env.GIT_BRANCH}`, | 102 | `Git branch: ${import.meta.env.GIT_BRANCH}`, |
99 | ].join('\n'), | 103 | ].join('\n'), |
@@ -109,9 +113,9 @@ function getResourceUrl(relativePath: string): string { | |||
109 | return new URL(relativePath, baseUrl).toString(); | 113 | return new URL(relativePath, baseUrl).toString(); |
110 | } | 114 | } |
111 | 115 | ||
112 | let serviceInjectRelativePath = '../../service-inject/dist/index.js'; | 116 | const serviceInjectRelativePath = '../../service-inject/dist/index.js'; |
113 | let serviceInjectPath = getResourcePath(serviceInjectRelativePath); | 117 | const serviceInjectPath = getResourcePath(serviceInjectRelativePath); |
114 | let serviceInject: WebSource = { | 118 | const serviceInject: WebSource = { |
115 | code: readFileSync(serviceInjectPath, 'utf8'), | 119 | code: readFileSync(serviceInjectPath, 'utf8'), |
116 | url: getResourceUrl(serviceInjectRelativePath), | 120 | url: getResourceUrl(serviceInjectRelativePath), |
117 | }; | 121 | }; |
@@ -122,7 +126,7 @@ const store = createMainStore(); | |||
122 | init(store).then((disposeCompositionRoot) => { | 126 | init(store).then((disposeCompositionRoot) => { |
123 | app.on('will-quit', disposeCompositionRoot); | 127 | app.on('will-quit', disposeCompositionRoot); |
124 | }).catch((err) => { | 128 | }).catch((err) => { |
125 | console.log('Failed to initialize application', err); | 129 | log.log('Failed to initialize application', err); |
126 | }); | 130 | }); |
127 | 131 | ||
128 | const rendererBaseUrl = getResourceUrl('../renderer/'); | 132 | const rendererBaseUrl = getResourceUrl('../renderer/'); |
@@ -211,7 +215,7 @@ async function createWindow(): Promise<unknown> { | |||
211 | 215 | ||
212 | ipcMain.handle(RendererToMainIpcMessage.GetSharedStoreSnapshot, (event) => { | 216 | ipcMain.handle(RendererToMainIpcMessage.GetSharedStoreSnapshot, (event) => { |
213 | if (event.sender.id !== webContents.id) { | 217 | if (event.sender.id !== webContents.id) { |
214 | console.warn( | 218 | log.warn( |
215 | 'Unexpected', | 219 | 'Unexpected', |
216 | RendererToMainIpcMessage.GetSharedStoreSnapshot, | 220 | RendererToMainIpcMessage.GetSharedStoreSnapshot, |
217 | 'from webContents', | 221 | 'from webContents', |
@@ -224,7 +228,7 @@ async function createWindow(): Promise<unknown> { | |||
224 | 228 | ||
225 | ipcMain.on(RendererToMainIpcMessage.DispatchAction, (event, rawAction) => { | 229 | ipcMain.on(RendererToMainIpcMessage.DispatchAction, (event, rawAction) => { |
226 | if (event.sender.id !== webContents.id) { | 230 | if (event.sender.id !== webContents.id) { |
227 | console.warn( | 231 | log.warn( |
228 | 'Unexpected', | 232 | 'Unexpected', |
229 | RendererToMainIpcMessage.DispatchAction, | 233 | RendererToMainIpcMessage.DispatchAction, |
230 | 'from webContents', | 234 | 'from webContents', |
@@ -242,17 +246,26 @@ async function createWindow(): Promise<unknown> { | |||
242 | store.config.setThemeSource(actionToDispatch.themeSource); | 246 | store.config.setThemeSource(actionToDispatch.themeSource); |
243 | break; | 247 | break; |
244 | case 'reload-all-services': | 248 | case 'reload-all-services': |
245 | readFile(serviceInjectPath, 'utf8').then((data) => { | 249 | readFile(serviceInjectPath, 'utf8') |
246 | serviceInject.code = data; | 250 | .then((data) => { |
247 | }).catch((err) => { | 251 | serviceInject.code = data; |
248 | console.error('Error while reloading', serviceInjectPath, err); | 252 | }) |
249 | }).then(() => { | 253 | .catch((err) => { |
250 | browserView.webContents.reload(); | 254 | log.error('Error while reloading', serviceInjectPath, err); |
251 | }); | 255 | }) |
256 | .then(() => { | ||
257 | browserView.webContents.reload(); | ||
258 | }) | ||
259 | .catch((err) => { | ||
260 | log.error('Failed to reload browserView', err); | ||
261 | }); | ||
262 | break; | ||
263 | default: | ||
264 | log.error('Unexpected action from UI renderer:', actionToDispatch); | ||
252 | break; | 265 | break; |
253 | } | 266 | } |
254 | } catch (err) { | 267 | } catch (err) { |
255 | console.error('Error while dispatching renderer action', rawAction, err); | 268 | log.error('Error while dispatching renderer action', rawAction, err); |
256 | } | 269 | } |
257 | }); | 270 | }); |
258 | 271 | ||
@@ -260,11 +273,10 @@ async function createWindow(): Promise<unknown> { | |||
260 | webContents.send(MainToRendererIpcMessage.SharedStorePatch, patch); | 273 | webContents.send(MainToRendererIpcMessage.SharedStorePatch, patch); |
261 | }); | 274 | }); |
262 | 275 | ||
263 | ipcMain.handle(ServiceToMainIpcMessage.ApiExposedInMainWorld, (event) => { | 276 | ipcMain.handle( |
264 | return event.sender.id === browserView.webContents.id | 277 | ServiceToMainIpcMessage.ApiExposedInMainWorld, |
265 | ? serviceInject | 278 | (event) => (event.sender.id === browserView.webContents.id ? serviceInject : null), |
266 | : null; | 279 | ); |
267 | }); | ||
268 | 280 | ||
269 | browserView.webContents.on('ipc-message', (_event, channel, ...args) => { | 281 | browserView.webContents.on('ipc-message', (_event, channel, ...args) => { |
270 | try { | 282 | try { |
@@ -274,14 +286,14 @@ async function createWindow(): Promise<unknown> { | |||
274 | // otherwise electron emits a no handler registered warning. | 286 | // otherwise electron emits a no handler registered warning. |
275 | break; | 287 | break; |
276 | case ServiceToMainIpcMessage.SetUnreadCount: | 288 | case ServiceToMainIpcMessage.SetUnreadCount: |
277 | console.log('Unread count:', unreadCount.parse(args[0])); | 289 | log.log('Unread count:', unreadCount.parse(args[0])); |
278 | break; | 290 | break; |
279 | default: | 291 | default: |
280 | console.error('Unknown IPC message:', channel, args); | 292 | log.error('Unknown IPC message:', channel, args); |
281 | break; | 293 | break; |
282 | } | 294 | } |
283 | } catch (err) { | 295 | } catch (err) { |
284 | console.error('Error while processing IPC message:', channel, args, err); | 296 | log.error('Error while processing IPC message:', channel, args, err); |
285 | } | 297 | } |
286 | }); | 298 | }); |
287 | 299 | ||
@@ -291,17 +303,22 @@ async function createWindow(): Promise<unknown> { | |||
291 | }, | 303 | }, |
292 | ); | 304 | ); |
293 | 305 | ||
294 | browserView.webContents.session.webRequest.onBeforeSendHeaders(({ url, requestHeaders }, callback) => { | 306 | browserView.webContents.session.webRequest.onBeforeSendHeaders( |
295 | if (url.match(/^[^:]+:\/\/accounts\.google\.[^.\/]+\//)) { | 307 | ({ url, requestHeaders }, callback) => { |
296 | requestHeaders['User-Agent'] = chromelessUserAgent; | 308 | const requestUserAgent = url.match(/^[^:]+:\/\/accounts\.google\.[^./]+\//) |
297 | } else { | 309 | ? chromelessUserAgent |
298 | requestHeaders['User-Agent'] = userAgent; | 310 | : userAgent; |
299 | } | 311 | callback({ |
300 | callback({ requestHeaders }); | 312 | requestHeaders: { |
301 | }); | 313 | ...requestHeaders, |
314 | 'User-Agent': requestUserAgent, | ||
315 | }, | ||
316 | }); | ||
317 | }, | ||
318 | ); | ||
302 | 319 | ||
303 | browserView.webContents.loadURL('https://gitlab.com/say-hi-to-sophie/sophie').catch((err) => { | 320 | browserView.webContents.loadURL('https://gitlab.com/say-hi-to-sophie/sophie').catch((err) => { |
304 | console.error('Failed to load browser', err); | 321 | log.error('Failed to load browser', err); |
305 | }); | 322 | }); |
306 | 323 | ||
307 | return mainWindow.loadURL(pageUrl); | 324 | return mainWindow.loadURL(pageUrl); |
@@ -330,12 +347,12 @@ app.whenReady().then(async () => { | |||
330 | try { | 347 | try { |
331 | await installDevToolsExtensions(); | 348 | await installDevToolsExtensions(); |
332 | } catch (err) { | 349 | } catch (err) { |
333 | console.error('Failed to install devtools extensions', err); | 350 | log.error('Failed to install devtools extensions', err); |
334 | } | 351 | } |
335 | } | 352 | } |
336 | 353 | ||
337 | return createWindow(); | 354 | return createWindow(); |
338 | }).catch((err) => { | 355 | }).catch((err) => { |
339 | console.error('Failed to create window', err); | 356 | log.error('Failed to create window', err); |
340 | process.exit(1); | 357 | process.exit(1); |
341 | }); | 358 | }); |
diff --git a/packages/main/src/compositionRoot.ts b/packages/main/src/init.ts index 76835a1..4487cc4 100644 --- a/packages/main/src/compositionRoot.ts +++ b/packages/main/src/init.ts | |||
@@ -20,13 +20,13 @@ | |||
20 | 20 | ||
21 | import { app } from 'electron'; | 21 | import { app } from 'electron'; |
22 | 22 | ||
23 | import { initConfig } from './controllers/config'; | 23 | import initConfig from './controllers/initConfig'; |
24 | import { initNativeTheme } from './controllers/nativeTheme'; | 24 | import initNativeTheme from './controllers/initNativeTheme'; |
25 | import { ConfigPersistenceServiceImpl } from './services/impl/ConfigPersistenceServiceImpl'; | 25 | import ConfigPersistenceServiceImpl from './services/impl/ConfigPersistenceServiceImpl'; |
26 | import { MainStore } from './stores/MainStore'; | 26 | import { MainStore } from './stores/MainStore'; |
27 | import { Disposer } from './utils/disposer'; | 27 | import type Disposer from './utils/Disposer'; |
28 | 28 | ||
29 | export async function init(store: MainStore): Promise<Disposer> { | 29 | export default async function init(store: MainStore): Promise<Disposer> { |
30 | const configPersistenceService = new ConfigPersistenceServiceImpl(app.getPath('userData')); | 30 | const configPersistenceService = new ConfigPersistenceServiceImpl(app.getPath('userData')); |
31 | const disposeConfigController = await initConfig(store.config, configPersistenceService); | 31 | const disposeConfigController = await initConfig(store.config, configPersistenceService); |
32 | const disposeNativeThemeController = initNativeTheme(store); | 32 | const disposeNativeThemeController = initNativeTheme(store); |
diff --git a/packages/main/src/services/ConfigPersistenceService.ts b/packages/main/src/services/ConfigPersistenceService.ts index aed0ba3..7d508c5 100644 --- a/packages/main/src/services/ConfigPersistenceService.ts +++ b/packages/main/src/services/ConfigPersistenceService.ts | |||
@@ -18,12 +18,12 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import type { ConfigSnapshotOut } from '../stores/Config'; | 21 | import type { ConfigSnapshotOut } from '../stores/Config'; |
22 | import { Disposer } from '../utils/disposer'; | 22 | import type Disposer from '../utils/Disposer'; |
23 | 23 | ||
24 | export type ReadConfigResult = { found: true; data: unknown; } | { found: false; }; | 24 | export type ReadConfigResult = { found: true; data: unknown; } | { found: false; }; |
25 | 25 | ||
26 | export interface ConfigPersistenceService { | 26 | export default interface ConfigPersistenceService { |
27 | readConfig(): Promise<ReadConfigResult>; | 27 | readConfig(): Promise<ReadConfigResult>; |
28 | 28 | ||
29 | writeConfig(configSnapshot: ConfigSnapshotOut): Promise<void>; | 29 | writeConfig(configSnapshot: ConfigSnapshotOut): Promise<void>; |
diff --git a/packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts b/packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts index 2d19632..df8c807 100644 --- a/packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts +++ b/packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts | |||
@@ -19,18 +19,20 @@ | |||
19 | */ | 19 | */ |
20 | import { watch } from 'fs'; | 20 | import { watch } from 'fs'; |
21 | import { readFile, stat, writeFile } from 'fs/promises'; | 21 | import { readFile, stat, writeFile } from 'fs/promises'; |
22 | import JSON5 from 'json5'; | ||
23 | import { throttle } from 'lodash-es'; | ||
24 | import { join } from 'path'; | 22 | import { join } from 'path'; |
25 | 23 | ||
26 | import type { ConfigPersistenceService, ReadConfigResult } from '../ConfigPersistenceService.js'; | 24 | import JSON5 from 'json5'; |
27 | import type { ConfigSnapshotOut } from '../../stores/Config.js'; | 25 | import throttle from 'lodash-es/throttle'; |
28 | import { Disposer } from '../../utils/disposer'; | 26 | |
29 | import { getLogger } from '../../utils/logging'; | 27 | import type { ConfigSnapshotOut } from '../../stores/Config'; |
28 | import type Disposer from '../../utils/Disposer'; | ||
29 | import { getLogger } from '../../utils/log'; | ||
30 | import type ConfigPersistenceService from '../ConfigPersistenceService'; | ||
31 | import type { ReadConfigResult } from '../ConfigPersistenceService'; | ||
30 | 32 | ||
31 | const log = getLogger('configPersistence'); | 33 | const log = getLogger('configPersistence'); |
32 | 34 | ||
33 | export class ConfigPersistenceServiceImpl implements ConfigPersistenceService { | 35 | export default class ConfigPersistenceServiceImpl implements ConfigPersistenceService { |
34 | private readonly configFilePath: string; | 36 | private readonly configFilePath: string; |
35 | 37 | ||
36 | private writingConfig = false; | 38 | private writingConfig = false; |
@@ -103,7 +105,7 @@ export class ConfigPersistenceServiceImpl implements ConfigPersistenceService { | |||
103 | 'whish is newer than last written', | 105 | 'whish is newer than last written', |
104 | this.timeLastWritten, | 106 | this.timeLastWritten, |
105 | ); | 107 | ); |
106 | return callback(); | 108 | await callback(); |
107 | } | 109 | } |
108 | }, throttleMs); | 110 | }, throttleMs); |
109 | 111 | ||
@@ -115,7 +117,7 @@ export class ConfigPersistenceServiceImpl implements ConfigPersistenceService { | |||
115 | if (eventType === 'change' | 117 | if (eventType === 'change' |
116 | && (filename === this.configFileName || filename === null)) { | 118 | && (filename === this.configFileName || filename === null)) { |
117 | configChanged()?.catch((err) => { | 119 | configChanged()?.catch((err) => { |
118 | console.log('Unhandled error while listening for config changes', err); | 120 | log.error('Unhandled error while listening for config changes', err); |
119 | }); | 121 | }); |
120 | } | 122 | } |
121 | }); | 123 | }); |
diff --git a/packages/main/src/stores/Config.ts b/packages/main/src/stores/Config.ts index 7d1168f..06dbdeb 100644 --- a/packages/main/src/stores/Config.ts +++ b/packages/main/src/stores/Config.ts | |||
@@ -18,13 +18,13 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { Instance } from 'mobx-state-tree'; | ||
22 | import { | 21 | import { |
23 | config as originalConfig, | 22 | config as originalConfig, |
24 | ConfigSnapshotIn, | 23 | ConfigSnapshotIn, |
25 | ConfigSnapshotOut, | 24 | ConfigSnapshotOut, |
26 | ThemeSource, | 25 | ThemeSource, |
27 | } from '@sophie/shared'; | 26 | } from '@sophie/shared'; |
27 | import { Instance } from 'mobx-state-tree'; | ||
28 | 28 | ||
29 | export const config = originalConfig.actions((self) => ({ | 29 | export const config = originalConfig.actions((self) => ({ |
30 | setThemeSource(mode: ThemeSource) { | 30 | setThemeSource(mode: ThemeSource) { |
diff --git a/packages/main/src/stores/MainStore.ts b/packages/main/src/stores/MainStore.ts index f8a09d6..7b26c52 100644 --- a/packages/main/src/stores/MainStore.ts +++ b/packages/main/src/stores/MainStore.ts | |||
@@ -18,8 +18,8 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { applySnapshot, Instance, types } from 'mobx-state-tree'; | ||
22 | import { BrowserViewBounds } from '@sophie/shared'; | 21 | import { BrowserViewBounds } from '@sophie/shared'; |
22 | import { applySnapshot, Instance, types } from 'mobx-state-tree'; | ||
23 | 23 | ||
24 | import type { Config } from './Config.js'; | 24 | import type { Config } from './Config.js'; |
25 | import { sharedStore } from './SharedStore'; | 25 | import { sharedStore } from './SharedStore'; |
diff --git a/packages/main/src/stores/SharedStore.ts b/packages/main/src/stores/SharedStore.ts index e20150d..c023fc7 100644 --- a/packages/main/src/stores/SharedStore.ts +++ b/packages/main/src/stores/SharedStore.ts | |||
@@ -18,8 +18,8 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { Instance, types } from 'mobx-state-tree'; | ||
22 | import { sharedStore as originalSharedStore } from '@sophie/shared'; | 21 | import { sharedStore as originalSharedStore } from '@sophie/shared'; |
22 | import { Instance, types } from 'mobx-state-tree'; | ||
23 | 23 | ||
24 | import { config } from './Config'; | 24 | import { config } from './Config'; |
25 | 25 | ||
diff --git a/packages/main/src/utils/disposer.ts b/packages/main/src/utils/Disposer.ts index 0d469dd..2e0ca25 100644 --- a/packages/main/src/utils/disposer.ts +++ b/packages/main/src/utils/Disposer.ts | |||
@@ -20,4 +20,6 @@ | |||
20 | 20 | ||
21 | import { IDisposer } from 'mobx-state-tree'; | 21 | import { IDisposer } from 'mobx-state-tree'; |
22 | 22 | ||
23 | export type Disposer = IDisposer; | 23 | type Disposer = IDisposer; |
24 | |||
25 | export default Disposer; | ||
diff --git a/packages/main/src/utils/logging.ts b/packages/main/src/utils/log.ts index f703749..c704797 100644 --- a/packages/main/src/utils/logging.ts +++ b/packages/main/src/utils/log.ts | |||
@@ -45,7 +45,11 @@ prefix.reg(loglevel); | |||
45 | prefix.apply(loglevel, { | 45 | prefix.apply(loglevel, { |
46 | format(level, name, timestamp) { | 46 | format(level, name, timestamp) { |
47 | const levelColor = getColor(level); | 47 | const levelColor = getColor(level); |
48 | return `${chalk.gray(`[${timestamp}]`)} ${levelColor(level)} ${chalk.green(`${name}:`)}`; | 48 | const timeStr = timestamp.toString(); |
49 | const nameStr = typeof name === 'undefined' | ||
50 | ? levelColor(':') | ||
51 | : ` ${chalk.green(`${name}:`)}`; | ||
52 | return `${chalk.gray(`[${timeStr}]`)} ${levelColor(level)}${nameStr}`; | ||
49 | }, | 53 | }, |
50 | }); | 54 | }); |
51 | 55 | ||
@@ -56,7 +60,7 @@ export function getLogger(loggerName: string): Logger { | |||
56 | export function silenceLogger(): void { | 60 | export function silenceLogger(): void { |
57 | loglevel.disableAll(); | 61 | loglevel.disableAll(); |
58 | const loggers = loglevel.getLoggers(); | 62 | const loggers = loglevel.getLoggers(); |
59 | for (const loggerName of Object.keys(loggers)) { | 63 | Object.keys(loggers).forEach((loggerName) => { |
60 | loggers[loggerName].disableAll(); | 64 | loggers[loggerName].disableAll(); |
61 | } | 65 | }); |
62 | } | 66 | } |