← back to Petitionyour

lib/store.js

37 lines

// Tiny durable JSON-file store. Synchronous by design — MVP scale, and sync
// fs calls remove any risk of interleaved writes corrupting the file (Node
// is single-threaded; a sync call can't be pre-empted by another request
// mid-write). Each write goes to a temp file then renames over the target,
// so a crash mid-write never leaves a half-written / corrupt JSON file.
const fs = require('fs');
const path = require('path');

const DATA_DIR = path.join(__dirname, '..', 'data');

function filePath(name) {
  return path.join(DATA_DIR, `${name}.json`);
}

function readJSON(name, fallback) {
  const p = filePath(name);
  try {
    const raw = fs.readFileSync(p, 'utf8');
    return JSON.parse(raw);
  } catch (err) {
    if (err.code === 'ENOENT') return fallback;
    // A corrupt file is a real problem — fail loud rather than silently
    // returning an empty dataset and letting the corruption get overwritten.
    console.error(`[store] failed to parse ${p}:`, err.message);
    throw err;
  }
}

function writeJSON(name, data) {
  const p = filePath(name);
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
  fs.writeFileSync(tmp, JSON.stringify(data, null, 2), 'utf8');
  fs.renameSync(tmp, p);
}

module.exports = { readJSON, writeJSON, DATA_DIR };