import { INCREMENT , ADD_CHILD , REMOVE_CHILD , CREATE_NODE , DELETE_NODE } from '../actions' ; const childIds = ( state , action ) => { switch ( action . type ) { case ADD_CHILD : return [ ... state , action . childId ] ; case REMOVE_CHILD : return state . filter ( id => id !== action . childId ) ; default : return state ; } } ; const node = ( state , action ) => { switch ( action . type ) { case CREATE_NODE : return { id : action . nodeId , counter : 0 , childIds : [ ] } ; case INCREMENT : return { ... state , counter : state . counter + 1 } ; case ADD_CHILD : case REMOVE_CHILD : return { ... state , childIds : childIds ( state . childIds , action ) } ; default : return state ; } } ; const getAllDescendantIds = ( state , nodeId ) => ( state [ nodeId ] . childIds . reduce ( ( acc , childId ) => ( [ ... acc , childId , ... getAllDescendantIds ( state , childId ) ] ) , [ ] ) ) ; const deleteMany = ( state , ids ) => { state = { ... state } ; ids . forEach ( id => delete state [ id ] ) ; return state ; } ; export default ( state = { } , action ) => { const { nodeId } = action ; if ( typeof nodeId === 'undefined' ) { return state ; } if ( action . type === DELETE_NODE ) { const descendantIds = getAllDescendantIds ( state , nodeId ) ; return deleteMany ( state , [ nodeId , ... descendantIds ] ) ; } return { ... state , [ nodeId ] : node ( state [ nodeId ] , action ) } ; } ;