UNPKG

@reduxjs/toolkit

Version:

The official, opinionated, batteries-included toolset for efficient Redux development

69 lines (58 loc) 1.78 kB
import type { Draft } from 'immer' import { current, isDraft } from 'immer' import type { DraftableEntityState, EntityId, IdSelector, Update, } from './models' export function selectIdValue<T, Id extends EntityId>( entity: T, selectId: IdSelector<T, Id>, ) { const key = selectId(entity) if (process.env.NODE_ENV !== 'production' && key === undefined) { console.warn( 'The entity passed to the `selectId` implementation returned undefined.', 'You should probably provide your own `selectId` implementation.', 'The entity that was passed:', entity, 'The `selectId` implementation:', selectId.toString(), ) } return key } export function ensureEntitiesArray<T, Id extends EntityId>( entities: readonly T[] | Record<Id, T>, ): readonly T[] { if (!Array.isArray(entities)) { entities = Object.values(entities) } return entities } export function getCurrent<T>(value: T | Draft<T>): T { return (isDraft(value) ? current(value) : value) as T } export function splitAddedUpdatedEntities<T, Id extends EntityId>( newEntities: readonly T[] | Record<Id, T>, selectId: IdSelector<T, Id>, state: DraftableEntityState<T, Id>, ): [T[], Update<T, Id>[], Id[]] { newEntities = ensureEntitiesArray(newEntities) const existingIdsArray = getCurrent(state.ids) const existingIds = new Set<Id>(existingIdsArray) const added: T[] = [] const addedIds = new Set<Id>([]) const updated: Update<T, Id>[] = [] for (const entity of newEntities) { const id = selectIdValue(entity, selectId) if (existingIds.has(id) || addedIds.has(id)) { updated.push({ id, changes: entity }) } else { addedIds.add(id) added.push(entity) } } return [added, updated, existingIdsArray] }