(set, get)
| 24 | import { toError } from "./utils"; |
| 25 | |
| 26 | export const createDBGroupSlice: AppSliceCreator<DBGroupSlice> = (set, get) => { |
| 27 | const unknownDatabaseGroup = createUnknownDatabaseGroup(); |
| 28 | |
| 29 | // Immutable cache write. A name maps to a single group + the view it was |
| 30 | // fetched with; overwriting is sufficient (no per-view keying needed). Also |
| 31 | // clears any stale error so a successful (re)fetch doesn't leave a prior |
| 32 | // failure visible to consumers reading `dbGroupErrorsByName`. |
| 33 | const setCache = (group: DatabaseGroup, view: DatabaseGroupView) => { |
| 34 | set((state) => ({ |
| 35 | dbGroupsByName: { ...state.dbGroupsByName, [group.name]: group }, |
| 36 | dbGroupViewByName: { ...state.dbGroupViewByName, [group.name]: view }, |
| 37 | dbGroupErrorsByName: { |
| 38 | ...state.dbGroupErrorsByName, |
| 39 | [group.name]: undefined, |
| 40 | }, |
| 41 | })); |
| 42 | }; |
| 43 | const removeCache = (name: string) => { |
| 44 | set((state) => { |
| 45 | const { [name]: _g, ...dbGroupsByName } = state.dbGroupsByName; |
| 46 | const { [name]: _v, ...dbGroupViewByName } = state.dbGroupViewByName; |
| 47 | return { dbGroupsByName, dbGroupViewByName }; |
| 48 | }); |
| 49 | }; |
| 50 | // Bulk variant of `setCache` — merges every group in one `set()` so a list |
| 51 | // fetch notifies subscribers once instead of N times. |
| 52 | const cacheGroups = (groups: DatabaseGroup[], view: DatabaseGroupView) => { |
| 53 | set((state) => { |
| 54 | const dbGroupsByName = { ...state.dbGroupsByName }; |
| 55 | const dbGroupViewByName = { ...state.dbGroupViewByName }; |
| 56 | for (const group of groups) { |
| 57 | dbGroupsByName[group.name] = group; |
| 58 | dbGroupViewByName[group.name] = view; |
| 59 | } |
| 60 | return { dbGroupsByName, dbGroupViewByName }; |
| 61 | }); |
| 62 | }; |
| 63 | |
| 64 | return { |
| 65 | dbGroupsByName: {}, |
| 66 | dbGroupViewByName: {}, |
| 67 | dbGroupRequests: {}, |
| 68 | dbGroupErrorsByName: {}, |
| 69 | |
| 70 | fetchDBGroup: async (name, view = DatabaseGroupView.BASIC) => { |
| 71 | if (!isValidDatabaseGroupName(name)) return undefined; |
| 72 | const existing = get().dbGroupsByName[name]; |
| 73 | // A FULL request needs `matchedDatabases`; only reuse the cache when it |
| 74 | // already holds the FULL view (a BASIC request is satisfied by either). |
| 75 | if ( |
| 76 | existing && |
| 77 | (view !== DatabaseGroupView.FULL || |
| 78 | get().dbGroupViewByName[name] === DatabaseGroupView.FULL) |
| 79 | ) { |
| 80 | return existing; |
| 81 | } |
| 82 | const pending = get().dbGroupRequests[name]; |
| 83 | if (pending) return pending; |
no test coverage detected