From f3a4d0a80fc60a5ce55bd1fc570124dba0e2488c Mon Sep 17 00:00:00 2001 From: arsam Date: Fri, 18 Sep 2026 23:13:33 +0330 Subject: [PATCH] Import source: backend/src/services/store Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality. --- backend/src/services/store.ts | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 backend/src/services/store.ts diff --git a/backend/src/services/store.ts b/backend/src/services/store.ts new file mode 100644 index 0000000..07cf020 --- /dev/null +++ b/backend/src/services/store.ts @@ -0,0 +1,55 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { env } from '../config/env.js'; +import type { DatabaseShape } from '../types.js'; + +const emptyDb = (): DatabaseShape => ({ + users: [], + refreshTokens: [], + files: [], + events: [], +}); + +export class JsonStore { + private dbPath: string; + private writeQueue: Promise = Promise.resolve(); + + constructor(dataDir = env.dataDir) { + this.dbPath = path.join(dataDir, 'db.json'); + } + + async init() { + await fs.mkdir(path.dirname(this.dbPath), { recursive: true }); + try { + await fs.access(this.dbPath); + } catch { + await fs.writeFile(this.dbPath, JSON.stringify(emptyDb(), null, 2)); + } + } + + async read(): Promise { + await this.init(); + const raw = await fs.readFile(this.dbPath, 'utf8'); + return { ...emptyDb(), ...JSON.parse(raw) }; + } + + async write(db: DatabaseShape) { + await this.init(); + this.writeQueue = this.writeQueue.then(async () => { + const tmpPath = `${this.dbPath}.tmp`; + await fs.writeFile(tmpPath, JSON.stringify(db, null, 2)); + await fs.rename(tmpPath, this.dbPath); + }); + await this.writeQueue; + } + + async update(mutator: (db: DatabaseShape) => T | Promise): Promise { + const db = await this.read(); + const result = await mutator(db); + await this.write(db); + return result; + } +} + +export const store = new JsonStore(); +