53 lines
1.5 KiB
JavaScript
53 lines
1.5 KiB
JavaScript
import fs from 'fs';
|
|||
|
|
import os from 'os';
|
||
|
|
import path from 'path';
|
||
|
|
|
||
|
|
const resolveDataDir = () => (process.env.OPENCHAMBER_DATA_DIR
|
||
|
|
? path.resolve(process.env.OPENCHAMBER_DATA_DIR)
|
||
|
|
: path.join(os.homedir(), '.config', 'openchamber'));
|
||
|
|
|
||
|
|
const readJsonFile = (filePath) => {
|
||
|
|
try {
|
||
|
|
const raw = fs.readFileSync(filePath, 'utf8');
|
||
|
|
const parsed = JSON.parse(raw);
|
||
|
|
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
|
||
|
|
} catch {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Read a persisted cache object from the OpenChamber data directory.
|
||
|
|
* Returns null when the file is missing, unreadable, or malformed.
|
||
|
|
*/
|
||
|
|
export const readDiskCache = (fileName) => {
|
||
|
|
try {
|
||
|
|
return readJsonFile(path.join(resolveDataDir(), fileName));
|
||
|
|
} catch {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Persist a cache object to the OpenChamber data directory with an atomic
|
||
|
|
* temp-file rename. Failures are ignored: the in-memory cache stays
|
||
|
|
* authoritative and the next successful write retries persistence.
|
||
|
|
*/
|
||
|
|
export const writeDiskCache = (fileName, data) => {
|
||
|
|
const filePath = path.join(resolveDataDir(), fileName);
|
||
|
|
const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
||
|
|
try {
|
||
|
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||
|
|
fs.writeFileSync(tempPath, JSON.stringify(data), { encoding: 'utf8', mode: 0o600 });
|
||
|
|
fs.renameSync(tempPath, filePath);
|
||
|
|
return true;
|
||
|
|
} catch {
|
||
|
|
try {
|
||
|
|
fs.unlinkSync(tempPath);
|
||
|
|
} catch {
|
||
|
|
// ignore
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
};
|