aboutsummaryrefslogtreecommitdiffstats
path: root/packages/main/src/reactions/synchronizeConfig.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/main/src/reactions/synchronizeConfig.ts')
-rw-r--r--packages/main/src/reactions/synchronizeConfig.ts40
1 files changed, 21 insertions, 19 deletions
diff --git a/packages/main/src/reactions/synchronizeConfig.ts b/packages/main/src/reactions/synchronizeConfig.ts
index 7e366e2..247c2e2 100644
--- a/packages/main/src/reactions/synchronizeConfig.ts
+++ b/packages/main/src/reactions/synchronizeConfig.ts
@@ -18,7 +18,6 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import deepEqual from 'deep-equal';
22import { debounce } from 'lodash-es'; 21import { debounce } from 'lodash-es';
23import { reaction } from 'mobx'; 22import { reaction } from 'mobx';
24 23
@@ -32,36 +31,38 @@ const DEFAULT_CONFIG_DEBOUNCE_TIME_MS = 1000;
32 31
33const log = getLogger('synchronizeConfig'); 32const log = getLogger('synchronizeConfig');
34 33
34export function serializeConfig(config: Config): string {
35 return `${JSON.stringify(config, undefined, 2)}\n`;
36}
37
35export default async function synchronizeConfig( 38export default async function synchronizeConfig(
36 sharedStore: SharedStore, 39 sharedStore: SharedStore,
37 repository: ConfigRepository, 40 repository: ConfigRepository,
38 debounceTime: number = DEFAULT_CONFIG_DEBOUNCE_TIME_MS, 41 debounceTime: number = DEFAULT_CONFIG_DEBOUNCE_TIME_MS,
39): Promise<Disposer> { 42): Promise<Disposer> {
40 let lastConfigOnDisk: Config | undefined; 43 let lastConfigOnDisk: string | undefined;
41 44
42 async function writeConfig(): Promise<void> { 45 async function writeConfig(serializedConfig: string): Promise<void> {
43 const { config } = sharedStore; 46 await repository.writeConfig(serializedConfig);
44 await repository.writeConfig(config); 47 lastConfigOnDisk = serializedConfig;
45 lastConfigOnDisk = config;
46 } 48 }
47 49
48 async function readConfig(): Promise<boolean> { 50 async function readConfig(): Promise<boolean> {
49 const result = await repository.readConfig(); 51 const result = await repository.readConfig();
50 if (result.found) { 52 if (result.found) {
53 const { contents } = result;
51 try { 54 try {
52 // This cast is unsound if the config file is invalid, 55 // This cast is unsound if the config file is invalid,
53 // but we'll throw an error in the end anyways. 56 // but we'll throw an error in the end anyways.
54 sharedStore.loadConfig(result.data as Config); 57 const data = JSON.parse(contents) as Config;
58 sharedStore.loadConfig(data);
55 } catch (error) { 59 } catch (error) {
56 log.error('Failed to apply config snapshot', result.data, error); 60 log.error('Failed to apply config snapshot', contents, error);
57 return true; 61 return true;
58 } 62 }
59 lastConfigOnDisk = sharedStore.config; 63 lastConfigOnDisk = serializeConfig(sharedStore.config);
60 // We can't use `comparer.structural` from `mobx`, because 64 if (contents !== lastConfigOnDisk) {
61 // it handles missing values and `undefined` values differently, 65 await writeConfig(lastConfigOnDisk);
62 // but JSON is unable to distinguish them.
63 if (!deepEqual(result.data, lastConfigOnDisk, { strict: true })) {
64 await writeConfig();
65 } 66 }
66 } 67 }
67 return result.found; 68 return result.found;
@@ -69,16 +70,17 @@ export default async function synchronizeConfig(
69 70
70 if (!(await readConfig())) { 71 if (!(await readConfig())) {
71 log.info('Config file was not found'); 72 log.info('Config file was not found');
72 await writeConfig(); 73 const serializedConfig = serializeConfig(sharedStore.config);
74 await writeConfig(serializedConfig);
73 log.info('Created config file'); 75 log.info('Created config file');
74 } 76 }
75 77
76 const disposeReaction = reaction( 78 const disposeReaction = reaction(
77 () => sharedStore.config, 79 () => sharedStore.config,
78 debounce((config) => { 80 debounce(() => {
79 // We can compare snapshots by reference, since it is only recreated on store changes. 81 const serializedConfig = serializeConfig(sharedStore.config);
80 if (!deepEqual(config, lastConfigOnDisk, { strict: true })) { 82 if (serializedConfig !== lastConfigOnDisk) {
81 writeConfig().catch((error) => { 83 writeConfig(serializedConfig).catch((error) => {
82 log.error('Failed to write config on config change', error); 84 log.error('Failed to write config on config change', error);
83 }); 85 });
84 } 86 }