import { diff } from 'deep-diff' ; export type DiffKind = 'E' | 'N' | 'D' | 'A' ; export interface Logger { groupCollapsed : ( ... data : any [ ] ) => void ; group : ( ... data : any [ ] ) => void ; log : ( ... data : any [ ] ) => void ; groupEnd : ( ) => void ; } const dictionary = { E : { color : '#2196F3' , text : 'CHANGED:' } , N : { color : '#4CAF50' , text : 'ADDED:' } , D : { color : '#F44336' , text : 'DELETED:' } , A : { color : '#2196F3' , text : 'ARRAY:' } } ; export function style ( kind ) { return `color: ${ dictionary [ kind ] . color }; font-weight: bold` ; } export function render ( diff ) { const { kind , path , lhs , rhs , index , item } = diff ; switch ( kind ) { case 'E' : return [ path . join ( '.' ) , lhs , '→' , rhs ] ; case 'N' : return [ path . join ( '.' ) , rhs ] ; case 'D' : return [ path . join ( '.' ) ] ; case 'A' : return [ `${ path . join ( '.' ) }[${ index }]` , item ] ; default : return [ ] ; } } export default function diffLogger ( prevState , newState , logger , isCollapsed ) { const diffs = diff ( prevState , newState ) ; try { if ( isCollapsed ) { logger . groupCollapsed ( 'diff' ) ; } else { logger . group ( 'diff' ) ; } } catch ( e ) { logger . log ( 'diff' ) ; } if ( diffs ) { diffs . forEach ( ( elem ) => { const { kind } = elem ; const output = render ( elem ) ; logger . log ( `%c ${ dictionary [ kind ] . text }` , style ( kind ) , ... output ) ; } ) ; } else { logger . log ( '—— no diff ——' ) ; } try { logger . groupEnd ( ) ; } catch ( e ) { logger . log ( '—— diff end —— ' ) ; } }