/** 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(); } }; }