import type { Logger } from "../tracing/logger"; export interface SyncSettings { remoteUri: string; token: string; vaultName: string; syncConcurrency: number; isSyncEnabled: boolean; maxFileSizeMB: number; ignorePatterns: string[]; webSocketRetryIntervalMs: number; diffCacheSizeMB: number; enableTelemetry: boolean; } export const DEFAULT_SETTINGS: SyncSettings = { remoteUri: "", token: "", vaultName: "default", syncConcurrency: 1, isSyncEnabled: false, maxFileSizeMB: 10, ignorePatterns: [], webSocketRetryIntervalMs: 3500, diffCacheSizeMB: 4, enableTelemetry: false }; export class Settings { private settings: SyncSettings; private readonly onSettingsChangeHandlers: (( newSettings: SyncSettings, oldSettings: SyncSettings ) => unknown)[] = []; public constructor( private readonly logger: Logger, initialState: Partial | undefined, private readonly saveData: (data: SyncSettings) => Promise ) { this.settings = { ...DEFAULT_SETTINGS, ...(initialState ?? {}) }; this.logger.debug( `Loaded settings: ${JSON.stringify(this.settings, null, 2)}` ); } public getSettings(): SyncSettings { return this.settings; } public addOnSettingsChangeListener( listener: (settings: SyncSettings, oldSettings: SyncSettings) => unknown ): void { this.onSettingsChangeHandlers.push(listener); } public removeOnSettingsChangeListener( listener: (settings: SyncSettings, oldSettings: SyncSettings) => unknown ): void { const index = this.onSettingsChangeHandlers.indexOf(listener); if (index !== -1) { this.onSettingsChangeHandlers.splice(index, 1); } } public async setSetting( key: T, value: SyncSettings[T] ): Promise { this.logger.debug(`Setting '${key}' to '${value}'`); await this.setSettings({ [key]: value }); } public async setSettings(value: Partial): Promise { const oldSettings = this.settings; this.settings = { ...this.settings, ...value }; this.onSettingsChangeHandlers.forEach((handler) => { handler(this.settings, oldSettings); }); await this.save(); } private async save(): Promise { await this.saveData(this.settings); } }