Files
KrisHD_AI/public/js/draftStore.js
T
2026-10-06 00:32:18 +02:00

38 lines
2.0 KiB
JavaScript

/** Text and uploaded attachment references only, scoped to the signed-in account. */
export function createDraftStore(username, {storage = globalThis.localStorage, onError = () => {}} = {}) {
const key = `krishd-drafts-v1:${encodeURIComponent(username)}`;
let records = {};
let warned = false;
const report = () => { if (!warned) onError("Draft recovery is unavailable in this browser. Keep this page open to retain your draft."); warned = true; };
try {
const saved = JSON.parse(storage.getItem(key) || "{}");
if (saved && typeof saved === "object" && !Array.isArray(saved)) records = saved;
} catch { report(); }
const normalizeId = id => id == null ? "new" : String(id);
const save = () => {
for (const [id, record] of Object.entries(records)) {
if (!record.text && !record.attachments?.length) delete records[id];
}
try { storage.setItem(key, JSON.stringify(records)); } catch { report(); }
};
const update = (id, changes) => {
id = normalizeId(id);
records[id] = {...records[id], ...changes};
save();
};
const textDrafts = new Map(Object.entries(records).filter(([, record]) => typeof record?.text === "string")
.map(([id, record]) => [id === "new" ? id : Number(id), record.text]));
const set = textDrafts.set.bind(textDrafts), remove = textDrafts.delete.bind(textDrafts);
textDrafts.set = (id, text) => { update(id, {text}); return set(id, text); };
textDrafts.delete = id => { update(id, {text: ""}); return remove(id); };
return {
textDrafts,
attachments(id) {
const items = records[normalizeId(id)]?.attachments;
return Array.isArray(items) ? items.filter(item => typeof item?.id === "string" && /^[a-f0-9-]{36}$/.test(item.id)) : [];
},
setAttachments(id, attachments) { update(id, {attachments}); },
clear(id) { delete records[normalizeId(id)]; remove(id); save(); }
};
}