/** * External dependencies */ import { map, mapValues } from 'lodash'; import { EMPTY_ARRAY, EMPTY_OBJECT } from '@nelio-content/constants'; import { createIndexedSelector, isDefined } from '@nelio-content/utils'; import type { Maybe, PostId, PremiumItems, PremiumItemSummaries, PremiumItemType, } from '@nelio-content/types'; /** * Internal dependencies */ import type { State } from '../../config'; type GetPremiumItem = typeof _getPremiumItem & { CurriedSignature: < Type extends PremiumItemType >( type: Type, id?: PremiumItems[ Type ][ 'id' ] ) => Maybe< PremiumItems[ Type ] >; }; export const getPremiumItem: GetPremiumItem = _getPremiumItem as GetPremiumItem; function _getPremiumItem< Type extends PremiumItemType >( state: State, type: Type, id?: PremiumItems[ Type ][ 'id' ] ): Maybe< PremiumItems[ Type ] > { return id ? state.entities.premiumByType[ type ]?.byId[ id ] : undefined; } type GetAllPremiumItemsRelatedToPost = typeof _getAllPremiumItemsRelatedToPost & { CurriedSignature: ( postId?: PostId ) => Partial< { [ K in PremiumItemType ]: ReadonlyArray< PremiumItems[ K ] >; } >; }; const _getAllPremiumItemsRelatedToPost = createIndexedSelector( ( state: State, postId?: PostId ): Partial< { [ K in PremiumItemType ]: ReadonlyArray< PremiumItems[ K ] >; } > => { if ( ! postId ) { return EMPTY_OBJECT; } const summariesByType = mapValues( state.entities.premiumByType, ( s ) => s?.byRelatedPost[ postId ] ?? EMPTY_ARRAY ); return mapValues( summariesByType, < K extends PremiumItemType >( summaries: ReadonlyArray< PremiumItemSummaries[ K ] >, type: K ) => map( summaries, ( { id } ) => getPremiumItem( state, type, id ) ).filter( isDefined ) ) as Partial< { [ K in PremiumItemType ]: ReadonlyArray< PremiumItems[ K ] >; } >; }, ( state: State, postId?: PostId ) => ( { key: postId || 0, dependants: [ state.entities.premiumByType ], } ) ); export const getAllPremiumItemsRelatedToPost = _getAllPremiumItemsRelatedToPost as GetAllPremiumItemsRelatedToPost; type GetPremiumItemsRelatedToPost = typeof _getPremiumItemsRelatedToPost & { CurriedSignature: < Type extends PremiumItemType >( typeName: Type, postId?: PostId ) => ReadonlyArray< PremiumItems[ Type ] >; }; export const getPremiumItemsRelatedToPost = _getPremiumItemsRelatedToPost as GetPremiumItemsRelatedToPost; function _getPremiumItemsRelatedToPost< Type extends PremiumItemType >( state: State, typeName: Type, postId?: PostId ): ReadonlyArray< PremiumItems[ Type ] > { const all = getAllPremiumItemsRelatedToPost( state, postId ); return all[ typeName ] ?? EMPTY_ARRAY; }