mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
feat(core): add Electron runtime, services, and app composition
This commit is contained in:
116
src/config/service.ts
Normal file
116
src/config/service.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { ConfigValidationWarning, RawConfig, ResolvedConfig } from '../types';
|
||||
import { DEFAULT_CONFIG, deepCloneConfig, deepMergeRawConfig } from './definitions';
|
||||
import { ConfigPaths, loadRawConfig, loadRawConfigStrict } from './load';
|
||||
import { resolveConfig } from './resolve';
|
||||
|
||||
export type ReloadConfigStrictResult =
|
||||
| {
|
||||
ok: true;
|
||||
config: ResolvedConfig;
|
||||
warnings: ConfigValidationWarning[];
|
||||
path: string;
|
||||
}
|
||||
| {
|
||||
ok: false;
|
||||
error: string;
|
||||
path: string;
|
||||
};
|
||||
|
||||
export class ConfigStartupParseError extends Error {
|
||||
readonly path: string;
|
||||
readonly parseError: string;
|
||||
|
||||
constructor(configPath: string, parseError: string) {
|
||||
super(
|
||||
`Failed to parse startup config at ${configPath}: ${parseError}. Fix the config file and restart SubMiner.`,
|
||||
);
|
||||
this.name = 'ConfigStartupParseError';
|
||||
this.path = configPath;
|
||||
this.parseError = parseError;
|
||||
}
|
||||
}
|
||||
|
||||
export class ConfigService {
|
||||
private readonly configPaths: ConfigPaths;
|
||||
private rawConfig: RawConfig = {};
|
||||
private resolvedConfig: ResolvedConfig = deepCloneConfig(DEFAULT_CONFIG);
|
||||
private warnings: ConfigValidationWarning[] = [];
|
||||
private configPathInUse!: string;
|
||||
|
||||
constructor(configDir: string) {
|
||||
this.configPaths = {
|
||||
configDir,
|
||||
configFileJsonc: path.join(configDir, 'config.jsonc'),
|
||||
configFileJson: path.join(configDir, 'config.json'),
|
||||
};
|
||||
const loadResult = loadRawConfigStrict(this.configPaths);
|
||||
if (!loadResult.ok) {
|
||||
throw new ConfigStartupParseError(loadResult.path, loadResult.error);
|
||||
}
|
||||
this.applyResolvedConfig(loadResult.config, loadResult.path);
|
||||
}
|
||||
|
||||
getConfigPath(): string {
|
||||
return this.configPathInUse;
|
||||
}
|
||||
|
||||
getConfig(): ResolvedConfig {
|
||||
return deepCloneConfig(this.resolvedConfig);
|
||||
}
|
||||
|
||||
getRawConfig(): RawConfig {
|
||||
return JSON.parse(JSON.stringify(this.rawConfig)) as RawConfig;
|
||||
}
|
||||
|
||||
getWarnings(): ConfigValidationWarning[] {
|
||||
return [...this.warnings];
|
||||
}
|
||||
|
||||
reloadConfig(): ResolvedConfig {
|
||||
const { config, path: configPath } = loadRawConfig(this.configPaths);
|
||||
return this.applyResolvedConfig(config, configPath);
|
||||
}
|
||||
|
||||
reloadConfigStrict(): ReloadConfigStrictResult {
|
||||
const loadResult = loadRawConfigStrict(this.configPaths);
|
||||
if (!loadResult.ok) {
|
||||
return loadResult;
|
||||
}
|
||||
|
||||
const { config, path: configPath } = loadResult;
|
||||
const resolvedConfig = this.applyResolvedConfig(config, configPath);
|
||||
return {
|
||||
ok: true,
|
||||
config: resolvedConfig,
|
||||
warnings: this.getWarnings(),
|
||||
path: configPath,
|
||||
};
|
||||
}
|
||||
|
||||
saveRawConfig(config: RawConfig): void {
|
||||
if (!fs.existsSync(this.configPaths.configDir)) {
|
||||
fs.mkdirSync(this.configPaths.configDir, { recursive: true });
|
||||
}
|
||||
const targetPath = this.configPathInUse.endsWith('.json')
|
||||
? this.configPathInUse
|
||||
: this.configPaths.configFileJsonc;
|
||||
fs.writeFileSync(targetPath, JSON.stringify(config, null, 2));
|
||||
this.applyResolvedConfig(config, targetPath);
|
||||
}
|
||||
|
||||
patchRawConfig(patch: RawConfig): void {
|
||||
const merged = deepMergeRawConfig(this.getRawConfig(), patch);
|
||||
this.saveRawConfig(merged);
|
||||
}
|
||||
|
||||
private applyResolvedConfig(config: RawConfig, configPath: string): ResolvedConfig {
|
||||
this.rawConfig = config;
|
||||
this.configPathInUse = configPath;
|
||||
const { resolved, warnings } = resolveConfig(config);
|
||||
this.resolvedConfig = resolved;
|
||||
this.warnings = warnings;
|
||||
return this.getConfig();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user