| [a762898] | 1 | import type { CreateSelectorFunction, Selector } from 'reselect'
|
|---|
| 2 | import { createDraftSafeSelector } from '../createDraftSafeSelector'
|
|---|
| 3 | import type { EntityId, EntitySelectors, EntityState } from './models'
|
|---|
| 4 |
|
|---|
| 5 | type AnyCreateSelectorFunction = CreateSelectorFunction<any, any, any>
|
|---|
| 6 |
|
|---|
| 7 | export type GetSelectorsOptions = {
|
|---|
| 8 | createSelector?: AnyCreateSelectorFunction
|
|---|
| 9 | }
|
|---|
| 10 |
|
|---|
| 11 | export function createSelectorsFactory<T, Id extends EntityId>() {
|
|---|
| 12 | function getSelectors(
|
|---|
| 13 | selectState?: undefined,
|
|---|
| 14 | options?: GetSelectorsOptions,
|
|---|
| 15 | ): EntitySelectors<T, EntityState<T, Id>, Id>
|
|---|
| 16 | function getSelectors<V>(
|
|---|
| 17 | selectState: (state: V) => EntityState<T, Id>,
|
|---|
| 18 | options?: GetSelectorsOptions,
|
|---|
| 19 | ): EntitySelectors<T, V, Id>
|
|---|
| 20 | function getSelectors<V>(
|
|---|
| 21 | selectState?: (state: V) => EntityState<T, Id>,
|
|---|
| 22 | options: GetSelectorsOptions = {},
|
|---|
| 23 | ): EntitySelectors<T, any, Id> {
|
|---|
| 24 | const {
|
|---|
| 25 | createSelector = createDraftSafeSelector as AnyCreateSelectorFunction,
|
|---|
| 26 | } = options
|
|---|
| 27 |
|
|---|
| 28 | const selectIds = (state: EntityState<T, Id>) => state.ids
|
|---|
| 29 |
|
|---|
| 30 | const selectEntities = (state: EntityState<T, Id>) => state.entities
|
|---|
| 31 |
|
|---|
| 32 | const selectAll = createSelector(
|
|---|
| 33 | selectIds,
|
|---|
| 34 | selectEntities,
|
|---|
| 35 | (ids, entities): T[] => ids.map((id) => entities[id]!),
|
|---|
| 36 | )
|
|---|
| 37 |
|
|---|
| 38 | const selectId = (_: unknown, id: Id) => id
|
|---|
| 39 |
|
|---|
| 40 | const selectById = (entities: Record<Id, T>, id: Id) => entities[id]
|
|---|
| 41 |
|
|---|
| 42 | const selectTotal = createSelector(selectIds, (ids) => ids.length)
|
|---|
| 43 |
|
|---|
| 44 | if (!selectState) {
|
|---|
| 45 | return {
|
|---|
| 46 | selectIds,
|
|---|
| 47 | selectEntities,
|
|---|
| 48 | selectAll,
|
|---|
| 49 | selectTotal,
|
|---|
| 50 | selectById: createSelector(selectEntities, selectId, selectById),
|
|---|
| 51 | }
|
|---|
| 52 | }
|
|---|
| 53 |
|
|---|
| 54 | const selectGlobalizedEntities = createSelector(
|
|---|
| 55 | selectState as Selector<V, EntityState<T, Id>>,
|
|---|
| 56 | selectEntities,
|
|---|
| 57 | )
|
|---|
| 58 |
|
|---|
| 59 | return {
|
|---|
| 60 | selectIds: createSelector(selectState, selectIds),
|
|---|
| 61 | selectEntities: selectGlobalizedEntities,
|
|---|
| 62 | selectAll: createSelector(selectState, selectAll),
|
|---|
| 63 | selectTotal: createSelector(selectState, selectTotal),
|
|---|
| 64 | selectById: createSelector(
|
|---|
| 65 | selectGlobalizedEntities,
|
|---|
| 66 | selectId,
|
|---|
| 67 | selectById,
|
|---|
| 68 | ),
|
|---|
| 69 | }
|
|---|
| 70 | }
|
|---|
| 71 |
|
|---|
| 72 | return { getSelectors }
|
|---|
| 73 | }
|
|---|