CompactAI's picture
Upload 126 files
f6b8770 verified
Raw
History Blame Contribute Delete
1.55 kB
// Tiny JSON-file persistence layer. No external DB, no config.
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const DB_PATH = path.join(__dirname, '..', 'data', 'db.json');
let db = null;
let saveTimer = null;
function uid(len = 12) {
return crypto.randomBytes(len).toString('base64url').slice(0, len);
}
function load() {
if (fs.existsSync(DB_PATH)) {
try {
db = JSON.parse(fs.readFileSync(DB_PATH, 'utf8'));
} catch (e) {
console.error('db corrupt, starting fresh:', e.message);
db = null;
}
}
if (!db) {
db = { users: {}, games: {}, sessions: {}, catalog: [] };
}
return db;
}
function get() {
if (!db) load();
return db;
}
function save() {
// Debounced write so rapid studio ops don't hammer the disk.
if (saveTimer) return;
saveTimer = setTimeout(() => {
saveTimer = null;
fs.writeFileSync(DB_PATH, JSON.stringify(db));
}, 500);
}
function saveNow() {
if (saveTimer) { clearTimeout(saveTimer); saveTimer = null; }
fs.writeFileSync(DB_PATH, JSON.stringify(db));
}
function findUserByName(username) {
const u = Object.values(get().users).find(
(x) => x.username.toLowerCase() === String(username).toLowerCase()
);
return u || null;
}
function publicUser(u) {
if (!u) return null;
return {
id: u.id,
username: u.username,
avatar: u.avatar,
created: u.created,
stats: u.stats,
system: !!u.system,
};
}
module.exports = { get, load, save, saveNow, uid, findUserByName, publicUser };