/** * Helpers to handle updating messages in the cache * Messages are ordered by ULID on the client so we may * have diverging logic from other kinds of api data */ import { ApiCollection, ResourceObject } from '../../types' /** * updateRecordInPagesData * Updates record if found in the cache, otherwise noops. */ export function updateRecordInPagesData({ data, record, processRecord = r => r, }: { data?: { pages: ApiCollection[]; pageParams: any } record: T processRecord?: (_next: T, _prev: T) => T }) { if (!data) return data const newPages = data.pages.map(page => { const newData = page.data.map(message => { if (message.id === record.id) { return processRecord(record, message) } return message }) return { ...page, data: newData } }) return { ...data, pages: newPages } } /** * updateOrCreateRecordInPagesData * Updates record if found in the cache, otherwise inserts. */ export function updateOrCreateRecordInPagesData({ data, record, processRecord = r => r, }: { data?: { pages: ApiCollection[]; pageParams: any } record: T processRecord?: (_next: T, _prev?: T) => T }) { if (!data) return data let foundRecord = false const newPages = data.pages.map(page => { const newData = page.data.map(message => { if (message.id === record.id) { foundRecord = true return processRecord(record, message) } return message }) return { ...page, data: newData } }) if (!foundRecord) { // This is a fallback for when the record is not found in the cache. const firstPage = { ...newPages[0] } firstPage.data = [processRecord(record), ...firstPage.data] newPages[0] = firstPage } return { ...data, pages: newPages } } /** * updateAllRecordsInPagesData * Updates all records in the cache using the provided processRecord function. */ export function updateAllRecordsInPagesData({ data, processRecord = r => r, }: { data?: { pages: ApiCollection[]; pageParams: any } processRecord?: (_next: T) => T }) { if (!data) return data const newPages = data.pages.map(page => { const newData = page.data.map(processRecord) return { ...page, data: newData } }) return { ...data, pages: newPages } } export function addRecordInPagesData({ data, record, processRecord = r => r, }: { data?: { pages: ApiCollection[]; pageParams: any } record: T processRecord?: (_next: T) => T }) { if (!data) return data const newPages = [...data.pages] const firstPage = { ...newPages[0] } firstPage.data = [processRecord(record), ...firstPage.data] newPages[0] = firstPage return { ...data, pages: newPages } } /** * deleteRecordInPagesData */ export function deleteRecordInPagesData({ data, record, matchFn = (message, rec) => message.id === rec.id, }: { data?: { pages: ApiCollection[]; pageParams: any } record: { id: string | number } matchFn?: (message: T, record: { id: string | number }) => boolean }) { if (!data) return data const newPages = data.pages.map(page => { const newData = page.data.filter(message => { return !matchFn(message, record) }) return { ...page, data: newData } }) return { ...data, pages: newPages } }