feat(settings): add support for mirroring settings to SD card if mounted

This commit is contained in:
Jaime Idolpx 2026-06-09 13:31:14 -04:00
parent 8d5de3f92f
commit 7ca7d478cc

View File

@ -16,12 +16,14 @@ import {
createFolder, createFolder,
getFileContents, getFileContents,
putFileContents, putFileContents,
stat,
} from './webdav'; } from './webdav';
/** The canonical paths on the WebDAV server. */ /** The canonical paths on the WebDAV server. */
export const SETTINGS_PATH = '/.sys/config.json'; export const SETTINGS_PATH = '/.sys/config.json';
export const DEVICES_PATH = '/.sys/devices.json'; export const DEVICES_PATH = '/.sys/devices.json';
const SETTINGS_DIR = '/.sys'; const SETTINGS_DIR = '/.sys';
const SD_SYS_DIR = '/sd/.sys';
/** /**
* How long to wait after the last change before writing to disk. * How long to wait after the last change before writing to disk.
@ -75,17 +77,29 @@ export async function readSettings(): Promise<SettingsConfig | null> {
* indentation so the file is diff-friendly. * indentation so the file is diff-friendly.
*/ */
export async function writeSettings(config: SettingsConfig): Promise<void> { export async function writeSettings(config: SettingsConfig): Promise<void> {
try { try { await createFolder(SETTINGS_DIR, true); } catch { /* exists */ }
await createFolder(SETTINGS_DIR, true);
} catch {
/* directory may already exist; ignore */
}
const { iec, ...mainConfig } = config; const { iec, ...mainConfig } = config;
const { devices: iecDevices, ...iecBusConfig } = (iec ?? {}) as any; const { devices: iecDevices, ...iecBusConfig } = (iec ?? {}) as any;
const configJson = JSON.stringify({ ...mainConfig, iec: iecBusConfig }, null, 2) + '\n';
const devicesJson = JSON.stringify({ iec: { devices: iecDevices } }, null, 2) + '\n';
await Promise.all([ await Promise.all([
putFileContents(SETTINGS_PATH, JSON.stringify({ ...mainConfig, iec: iecBusConfig }, null, 2) + '\n'), putFileContents(SETTINGS_PATH, configJson),
putFileContents(DEVICES_PATH, JSON.stringify({ iec: { devices: iecDevices } }, null, 2) + '\n'), putFileContents(DEVICES_PATH, devicesJson),
]); ]);
// Mirror to /sd/.sys/ if the SD card is mounted.
try {
const sdStat = await stat('/sd');
if (sdStat) {
try { await createFolder(SD_SYS_DIR, true); } catch { /* exists */ }
await Promise.all([
putFileContents(SD_SYS_DIR + '/config.json', configJson),
putFileContents(SD_SYS_DIR + '/devices.json', devicesJson),
]);
}
} catch { /* /sd unreachable — skip mirror */ }
} }
export type SaveStatus = export type SaveStatus =