import { writeFileSync } from "node:fs"; import { writeFile, readFile } from "node:fs/promises"; import path from "node:path"; import { onExit } from "./util"; const store = ( name: string, init: () => T, { persistInterval = 60 * 1000 } = {} ) => { let state = init(); (state as any)._storeName = name; const filePath = path.join(process.cwd(), `${name}.json`); const persist = (sync = false) => { const write = sync ? writeFileSync : writeFile; return write(filePath, JSON.stringify(state)); }; const load = async () => { try { const newState = await readFile(filePath, { encoding: "utf8" }); state = JSON.parse(newState); if ((state as any)._storeName !== name) { console.error(`File at "${filePath}" expected to be a Rappli store`); process.exit(1); } } catch (err) { if (typeof err === "object" && (err as any).code !== "ENOENT") { console.dir(err); process.exit(1); } } }; const globals = globalThis as any; (async () => { await load(); const intervalKey = `_store-persist-${name}`; if (globals[intervalKey] != null) { clearInterval(globals[intervalKey]); } globals[intervalKey] = setInterval(function () { persist(); }, persistInterval); })(); const exitKey = `_store-exit-${name}`; if (globals[exitKey]) { globals[exitKey](); } globals[exitKey] = onExit(() => persist(true)); const getState = () => state; return [getState] as [typeof getState]; }; export const [state] = store("data", () => ({ version: 0, likes: 0, }));