90 lines
No EOL
3.1 KiB
TypeScript
90 lines
No EOL
3.1 KiB
TypeScript
import fs from "fs";
|
|
import path from "path";
|
|
import { PollState, VoteEntry } from "@src/types";
|
|
import { Store } from "@systems/store";
|
|
import { Paths } from "@helpers/paths";
|
|
|
|
const PERSIST_PATH = Paths.data("poll-state.json");
|
|
|
|
// ─── Serialized shape ─────────────────────────────────────────────────────────
|
|
// Maps → arrays of [key, value] tuples, Sets → arrays of values
|
|
|
|
interface SerializedPollState {
|
|
messageId?: string | null;
|
|
slot: number;
|
|
yes: [string, VoteEntry][];
|
|
no: [string, VoteEntry][];
|
|
locked: boolean;
|
|
confirmed?: "yes" | "no" | null;
|
|
lockMessage?: string;
|
|
confirmMessage?: string;
|
|
lockedYesKeys?: string[];
|
|
}
|
|
|
|
// ─── Serialize / deserialize ──────────────────────────────────────────────────
|
|
|
|
function serialize(polls: Map<number, PollState>): SerializedPollState[] {
|
|
return [...polls.values()].map((s) => ({
|
|
messageId: s.messageId,
|
|
slot: s.slot,
|
|
yes: [...s.yes.entries()],
|
|
no: [...s.no.entries()],
|
|
locked: s.locked,
|
|
confirmed: s.confirmed,
|
|
lockMessage: s.lockMessage,
|
|
confirmMessage: s.confirmMessage,
|
|
lockedYesKeys: s.lockedYesKeys ? [...s.lockedYesKeys] : undefined,
|
|
}));
|
|
}
|
|
|
|
function deserialize(data: SerializedPollState[]): Map<number, PollState> {
|
|
const polls = new Map<number, PollState>();
|
|
for (const s of data) {
|
|
polls.set(s.slot, {
|
|
messageId: s.messageId,
|
|
slot: s.slot,
|
|
yes: new Map(s.yes),
|
|
no: new Map(s.no),
|
|
locked: s.locked,
|
|
confirmed: s.confirmed,
|
|
lockMessage: s.lockMessage,
|
|
confirmMessage: s.confirmMessage,
|
|
lockedYesKeys: s.lockedYesKeys ? new Set(s.lockedYesKeys) : undefined,
|
|
});
|
|
}
|
|
return polls;
|
|
}
|
|
|
|
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
|
|
export namespace persist {
|
|
export function save(polls: Map<number, PollState>): void {
|
|
try {
|
|
Store.write(PERSIST_PATH, serialize(polls));
|
|
} catch (err) {
|
|
console.error("[pollPersistence] Failed to save poll state:", err);
|
|
}
|
|
}
|
|
|
|
export function load(): Map<number, PollState> | null {
|
|
try {
|
|
const data = Store.read<SerializedPollState[]>(PERSIST_PATH);
|
|
if (!data) return null;
|
|
|
|
const polls = deserialize(data);
|
|
console.log(`[pollPersistence] Restored ${polls.size} poll(s) from disk.`);
|
|
return polls;
|
|
} catch (err) {
|
|
console.error("[pollPersistence] Failed to load poll state:", err);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function clear(): void {
|
|
try {
|
|
Store.delete(PERSIST_PATH);
|
|
} catch (err) {
|
|
console.error("[pollPersistence] Failed to clear poll state:", err);
|
|
}
|
|
}
|
|
} |