import { find } from 'lodash' ; import { Action } from 'redux-actions' ; import Normalized , { INorm , IEntity } from '../../utils/nrmlzd' ; import { createDefinition } from '../../state/createDefinition' ; import { logWarning , makeError } from '../../utils' ; const isEntity = ( arg ) : arg is IEntity => typeof arg === 'object' && arg . id ; const validateEntity = ( o ) => { if ( ! isEntity ( o ) ) { throw makeError ( 'Collection - Entity has no `id` key' ) ; } return o as IEntity ; } ; const validateEntities = ( list ) => list . map ( validateEntity ) ; type State = INorm ; export default createDefinition ( { reducers : { create : ( state , { payload : entity } ) : State => { if ( ! entity || ! validateEntity ( entity ) ) { return state ; } if ( find ( state . ids , ( id ) => id === entity . id ) ) { logWarning ( `Collection already has an entity with id: ${ entity . id }` ) ; } return Normalized . upsert ( state , entity ) ; } , remove : ( state , { payload : id } ) : State => { if ( ! id ) { return state ; } return Normalized . remove ( state , id ) ; } , reset : ( ) : State => Normalized . create ( ) , set : ( state , { payload : entities } ) : State => { if ( ! entities || ! validateEntities ( entities ) ) { return state ; } return Normalized . fromArray ( entities ) ; } , update : ( state , { payload : entity } ) : State => { if ( ! entity || ! validateEntity ( entity ) ) { return state ; } if ( ! find ( state . ids , ( id ) => id === entity . id ) ) { logWarning ( `Collection did not have an entity with id: ${ entity . id }. Entity has been added.` ) ; } return Normalized . upsert ( state , entity ) ; } , upsert : ( state , { payload : entity } ) : State => { if ( ! entity || ! validateEntity ( entity ) ) { return state ; } return Normalized . upsert ( state , entity ) ; } } , defaultState : Normalized . create ( ) , selectors : { find : ( state , params = undefined ) : IEntity | undefined => params && params . id ? state . entities [ params . id ] : undefined , get : ( state ) : State => state , ids : ( state ) : string [ ] => state . ids , all : ( state ) : IEntity [ ] => Normalized . toArray ( state ) , count : ( state ) : number => state . ids . length , } , transformInitialState : ( initialState ) : INorm => Normalized . fromArray ( validateEntities ( initialState ) ) , } ) ;