diff --git a/artifacts/tx-os/src/lib/notes-api.ts b/artifacts/tx-os/src/lib/notes-api.ts index 5d37aa8a..475d2ae4 100644 --- a/artifacts/tx-os/src/lib/notes-api.ts +++ b/artifacts/tx-os/src/lib/notes-api.ts @@ -275,48 +275,34 @@ export function useToggleChecklistItem() { return changed ? next : items; }; - // Personal notes lists (owner-side cards). - for (const [key, data] of qc.getQueriesData({ - queryKey: ["notes"], - })) { - if (!Array.isArray(data)) continue; - snapshots.push([key, data]); - qc.setQueryData( - key, - data.map((n) => - n.id === id ? { ...n, items: patchItems(n.items) as ChecklistItem[] | null } : n, - ), - ); - } - // Sent grid: same shape as Note, items field at top level. - for (const [key, data] of qc.getQueriesData({ - queryKey: sentNotesKey, - })) { - if (!Array.isArray(data)) continue; - snapshots.push([key, data]); - qc.setQueryData( - key, - data.map((n) => - n.id === id - ? { ...n, items: patchItems(n.items) as ChecklistItem[] | null } - : n, - ), - ); - } - // Received inbox (recipient-side snapshots). - for (const [key, data] of qc.getQueriesData({ - queryKey: ["notes", "received"], - })) { - if (!Array.isArray(data)) continue; - snapshots.push([key, data]); - qc.setQueryData( - key, - data.map((n) => - n.id === id - ? { ...n, items: patchItems(n.items) as ChecklistItem[] | null } - : n, - ), - ); + // Single broad pass over every cached note-list query + // (`["notes"]`, `["notes", "received"]`, sent grid, etc.) — react- + // query does prefix matching on the queryKey, so this catches all + // array-of-note caches in one place. Each entry is snapshotted + // exactly once so rollback on error is deterministic. + const arrayQueryKeys: ReadonlyArray = [ + ["notes"], + sentNotesKey, + ]; + const seen = new Set(); + for (const qk of arrayQueryKeys) { + for (const [key, data] of qc.getQueriesData< + Array + >({ queryKey: qk })) { + if (!Array.isArray(data)) continue; + const sig = JSON.stringify(key); + if (seen.has(sig)) continue; + seen.add(sig); + snapshots.push([key, data]); + qc.setQueryData( + key, + data.map((n) => + n.id === id + ? { ...n, items: patchItems(n.items) as ChecklistItem[] | null } + : n, + ), + ); + } } // Open thread dialog (single object, not an array). const threadKey = noteThreadKey(id);