diff options
-rw-r--r-- | docs/architecture.md | 8 | ||||
-rw-r--r-- | packages/main/src/controllers/__tests__/initConfig.spec.ts | 4 | ||||
-rw-r--r-- | packages/main/src/controllers/initConfig.ts | 4 | ||||
-rw-r--r-- | packages/main/src/infrastructure/ConfigPersistence.ts (renamed from packages/main/src/services/ConfigPersistenceService.ts) | 2 | ||||
-rw-r--r-- | packages/main/src/infrastructure/impl/FileBasedConfigPersistence.ts (renamed from packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts) | 12 | ||||
-rw-r--r-- | packages/main/src/init.ts | 4 |
6 files changed, 16 insertions, 18 deletions
diff --git a/docs/architecture.md b/docs/architecture.md index 0122809..791b57b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md | |||
@@ -82,11 +82,11 @@ Instead, they purely rely on IPC messages to invoke actions in the main process | |||
82 | 82 | ||
83 | In the main process, _controllers_ react to `MainStore` changes by invoking Electron APIs and subscribe to Electron events in order to invoke `MainStore` actions. | 83 | In the main process, _controllers_ react to `MainStore` changes by invoking Electron APIs and subscribe to Electron events in order to invoke `MainStore` actions. |
84 | 84 | ||
85 | For easier testability, controllers may rely on _services_ abstracting away the underlying Electron APIs. | 85 | For better testability, controllers may rely on _infrastructure services_ (wrappers) abstracting away the underlying Electron APIs. |
86 | The service has to come with a TypeScript interface and an implementation. | 86 | Each infrastructure of the service has to come with a TypeScript interface and at least one implementation. |
87 | In the tests, the default implementation of the interface is replaced by a mock. | 87 | In the tests, the default implementations of the interfaces are replaced by mocks. |
88 | 88 | ||
89 | The services and controllers are instatiated and connected to the `MainStore` in the [composition root](https://gitlab.com/say-hi-to-sophie/sophie/-/blob/main/packages/main/src/compositionRoot.ts). | 89 | The infrastructure services and controllers are instantiated and connected to the `MainStore` in the [composition root](https://gitlab.com/say-hi-to-sophie/sophie/-/blob/main/packages/main/src/init.ts). |
90 | 90 | ||
91 | **TODO:** | 91 | **TODO:** |
92 | While a service is a common term in MVC application architecture, we should come up with a different name to avoid clashing witch services, i.e., web sites loaded by Sophie. | 92 | While a service is a common term in MVC application architecture, we should come up with a different name to avoid clashing witch services, i.e., web sites loaded by Sophie. |
diff --git a/packages/main/src/controllers/__tests__/initConfig.spec.ts b/packages/main/src/controllers/__tests__/initConfig.spec.ts index 241ab2d..dc00b9d 100644 --- a/packages/main/src/controllers/__tests__/initConfig.spec.ts +++ b/packages/main/src/controllers/__tests__/initConfig.spec.ts | |||
@@ -23,14 +23,14 @@ import { mocked } from 'jest-mock'; | |||
23 | import { getSnapshot } from 'mobx-state-tree'; | 23 | import { getSnapshot } from 'mobx-state-tree'; |
24 | import ms from 'ms'; | 24 | import ms from 'ms'; |
25 | 25 | ||
26 | import type ConfigPersistenceService from '../../services/ConfigPersistenceService'; | 26 | import type ConfigPersistence from '../../infrastructure/ConfigPersistence'; |
27 | import { Config, config as configModel } from '../../stores/Config'; | 27 | import { Config, config as configModel } from '../../stores/Config'; |
28 | import type Disposer from '../../utils/Disposer'; | 28 | import type Disposer from '../../utils/Disposer'; |
29 | import { silenceLogger } from '../../utils/log'; | 29 | import { silenceLogger } from '../../utils/log'; |
30 | import initConfig from '../initConfig'; | 30 | import initConfig from '../initConfig'; |
31 | 31 | ||
32 | let config: Config; | 32 | let config: Config; |
33 | const persistenceService: ConfigPersistenceService = { | 33 | const persistenceService: ConfigPersistence = { |
34 | readConfig: jest.fn(), | 34 | readConfig: jest.fn(), |
35 | writeConfig: jest.fn(), | 35 | writeConfig: jest.fn(), |
36 | watchConfig: jest.fn(), | 36 | watchConfig: jest.fn(), |
diff --git a/packages/main/src/controllers/initConfig.ts b/packages/main/src/controllers/initConfig.ts index 2dcabaf..c8cd335 100644 --- a/packages/main/src/controllers/initConfig.ts +++ b/packages/main/src/controllers/initConfig.ts | |||
@@ -23,7 +23,7 @@ import { debounce } from 'lodash-es'; | |||
23 | import { getSnapshot, onSnapshot } from 'mobx-state-tree'; | 23 | import { getSnapshot, onSnapshot } from 'mobx-state-tree'; |
24 | import ms from 'ms'; | 24 | import ms from 'ms'; |
25 | 25 | ||
26 | import type ConfigPersistenceService from '../services/ConfigPersistenceService'; | 26 | import type ConfigPersistence from '../infrastructure/ConfigPersistence'; |
27 | import { Config, ConfigFileIn, ConfigSnapshotOut } from '../stores/Config'; | 27 | import { Config, ConfigFileIn, ConfigSnapshotOut } from '../stores/Config'; |
28 | import type Disposer from '../utils/Disposer'; | 28 | import type Disposer from '../utils/Disposer'; |
29 | import { getLogger } from '../utils/log'; | 29 | import { getLogger } from '../utils/log'; |
@@ -34,7 +34,7 @@ const log = getLogger('config'); | |||
34 | 34 | ||
35 | export default async function initConfig( | 35 | export default async function initConfig( |
36 | config: Config, | 36 | config: Config, |
37 | persistenceService: ConfigPersistenceService, | 37 | persistenceService: ConfigPersistence, |
38 | debounceTime: number = DEFAULT_CONFIG_DEBOUNCE_TIME, | 38 | debounceTime: number = DEFAULT_CONFIG_DEBOUNCE_TIME, |
39 | ): Promise<Disposer> { | 39 | ): Promise<Disposer> { |
40 | log.trace('Initializing config controller'); | 40 | log.trace('Initializing config controller'); |
diff --git a/packages/main/src/services/ConfigPersistenceService.ts b/packages/main/src/infrastructure/ConfigPersistence.ts index ee5696d..4b96f01 100644 --- a/packages/main/src/services/ConfigPersistenceService.ts +++ b/packages/main/src/infrastructure/ConfigPersistence.ts | |||
@@ -25,7 +25,7 @@ export type ReadConfigResult = | |||
25 | | { found: true; data: unknown } | 25 | | { found: true; data: unknown } |
26 | | { found: false }; | 26 | | { found: false }; |
27 | 27 | ||
28 | export default interface ConfigPersistenceService { | 28 | export default interface ConfigPersistence { |
29 | readConfig(): Promise<ReadConfigResult>; | 29 | readConfig(): Promise<ReadConfigResult>; |
30 | 30 | ||
31 | writeConfig(configSnapshot: ConfigSnapshotOut): Promise<void>; | 31 | writeConfig(configSnapshot: ConfigSnapshotOut): Promise<void>; |
diff --git a/packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts b/packages/main/src/infrastructure/impl/FileBasedConfigPersistence.ts index a11a9da..06e3fab 100644 --- a/packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts +++ b/packages/main/src/infrastructure/impl/FileBasedConfigPersistence.ts | |||
@@ -27,14 +27,12 @@ import throttle from 'lodash-es/throttle'; | |||
27 | import type { ConfigSnapshotOut } from '../../stores/Config'; | 27 | import type { ConfigSnapshotOut } from '../../stores/Config'; |
28 | import type Disposer from '../../utils/Disposer'; | 28 | import type Disposer from '../../utils/Disposer'; |
29 | import { getLogger } from '../../utils/log'; | 29 | import { getLogger } from '../../utils/log'; |
30 | import type ConfigPersistenceService from '../ConfigPersistenceService'; | 30 | import type ConfigPersistence from '../ConfigPersistence'; |
31 | import type { ReadConfigResult } from '../ConfigPersistenceService'; | 31 | import type { ReadConfigResult } from '../ConfigPersistence'; |
32 | 32 | ||
33 | const log = getLogger('configPersistence'); | 33 | const log = getLogger('fileBasedConfigPersistence'); |
34 | 34 | ||
35 | export default class ConfigPersistenceServiceImpl | 35 | export default class FileBasedConfigPersistence implements ConfigPersistence { |
36 | implements ConfigPersistenceService | ||
37 | { | ||
38 | private readonly configFilePath: string; | 36 | private readonly configFilePath: string; |
39 | 37 | ||
40 | private writingConfig = false; | 38 | private writingConfig = false; |
@@ -50,7 +48,7 @@ export default class ConfigPersistenceServiceImpl | |||
50 | } | 48 | } |
51 | 49 | ||
52 | async readConfig(): Promise<ReadConfigResult> { | 50 | async readConfig(): Promise<ReadConfigResult> { |
53 | let configStr; | 51 | let configStr: string; |
54 | try { | 52 | try { |
55 | configStr = await readFile(this.configFilePath, 'utf8'); | 53 | configStr = await readFile(this.configFilePath, 'utf8'); |
56 | } catch (error) { | 54 | } catch (error) { |
diff --git a/packages/main/src/init.ts b/packages/main/src/init.ts index f3794bb..236a075 100644 --- a/packages/main/src/init.ts +++ b/packages/main/src/init.ts | |||
@@ -22,12 +22,12 @@ import { app } from 'electron'; | |||
22 | 22 | ||
23 | import initConfig from './controllers/initConfig'; | 23 | import initConfig from './controllers/initConfig'; |
24 | import initNativeTheme from './controllers/initNativeTheme'; | 24 | import initNativeTheme from './controllers/initNativeTheme'; |
25 | import ConfigPersistenceServiceImpl from './services/impl/ConfigPersistenceServiceImpl'; | 25 | import FileBasedConfigPersistence from './infrastructure/impl/FileBasedConfigPersistence'; |
26 | import { MainStore } from './stores/MainStore'; | 26 | import { MainStore } from './stores/MainStore'; |
27 | import type Disposer from './utils/Disposer'; | 27 | import type Disposer from './utils/Disposer'; |
28 | 28 | ||
29 | export default async function init(store: MainStore): Promise<Disposer> { | 29 | export default async function init(store: MainStore): Promise<Disposer> { |
30 | const configPersistenceService = new ConfigPersistenceServiceImpl( | 30 | const configPersistenceService = new FileBasedConfigPersistence( |
31 | app.getPath('userData'), | 31 | app.getPath('userData'), |
32 | ); | 32 | ); |
33 | const disposeConfigController = await initConfig( | 33 | const disposeConfigController = await initConfig( |