pleroma/app/soapbox/entity-store/reducer.ts

81 lines
2.1 KiB
TypeScript
Raw Normal View History

2022-12-04 14:58:13 -08:00
import produce, { enableMapSet } from 'immer';
import {
ENTITIES_IMPORT,
ENTITIES_FETCH_REQUEST,
ENTITIES_FETCH_SUCCESS,
ENTITIES_FETCH_FAIL,
EntityAction,
} from './actions';
2022-12-04 14:58:13 -08:00
import { createCache, createList, updateStore, updateList } from './utils';
2022-12-04 15:53:56 -08:00
import type { Entity, EntityCache, EntityListState } from './types';
2022-12-04 14:58:13 -08:00
enableMapSet();
/** Entity reducer state. */
interface State {
[entityType: string]: EntityCache | undefined
}
2022-12-04 14:58:13 -08:00
/** Import entities into the cache. */
const importEntities = (
state: State,
2022-12-04 14:58:13 -08:00
entityType: string,
entities: Entity[],
listKey?: string,
2022-12-04 15:53:56 -08:00
newState?: EntityListState,
2022-12-04 14:58:13 -08:00
): State => {
return produce(state, draft => {
const cache = draft[entityType] ?? createCache();
2022-12-04 14:58:13 -08:00
cache.store = updateStore(cache.store, entities);
if (typeof listKey === 'string') {
let list = { ...(cache.lists[listKey] ?? createList()) };
2022-12-04 15:53:56 -08:00
list = updateList(list, entities);
if (newState) {
list.state = newState;
}
cache.lists[listKey] = list;
2022-12-04 14:58:13 -08:00
}
draft[entityType] = cache;
2022-12-04 14:58:13 -08:00
});
};
const setFetching = (
state: State,
entityType: string,
listKey: string | undefined,
isFetching: boolean,
) => {
return produce(state, draft => {
const cache = draft[entityType] ?? createCache();
if (typeof listKey === 'string') {
const list = cache.lists[listKey] ?? createList();
list.state.fetching = isFetching;
cache.lists[listKey] = list;
}
draft[entityType] = cache;
});
};
2022-12-04 14:58:13 -08:00
/** Stores various entity data and lists in a one reducer. */
function reducer(state: Readonly<State> = {}, action: EntityAction): State {
2022-12-04 14:58:13 -08:00
switch (action.type) {
case ENTITIES_IMPORT:
return importEntities(state, action.entityType, action.entities, action.listKey);
2022-12-04 15:53:56 -08:00
case ENTITIES_FETCH_SUCCESS:
return importEntities(state, action.entityType, action.entities, action.listKey, action.newState);
case ENTITIES_FETCH_REQUEST:
return setFetching(state, action.entityType, action.listKey, true);
case ENTITIES_FETCH_FAIL:
return setFetching(state, action.entityType, action.listKey, false);
2022-12-04 14:58:13 -08:00
default:
return state;
}
}
export default reducer;