import { OBJECT , isUndefined } from './helper' ; const table = new WeakMap < object , number | string > ( ) ; let counter = 0 ; export const stableHash = ( arg ) : string => { const type = typeof arg ; const constructor = arg && arg . constructor ; const isDate = constructor == Date ; let result ; let index ; if ( OBJECT ( arg ) === arg && ! isDate && constructor != RegExp ) { result = table . get ( arg ) ; if ( result ) return result ; result = ++ counter + '~' ; table . set ( arg , result ) ; if ( constructor == Array ) { result = '@' ; for ( index = 0 ; index < arg . length ; index ++ ) { result += stableHash ( arg [ index ] ) + ',' ; } table . set ( arg , result ) ; } if ( constructor == OBJECT ) { result = '#' ; const keys = OBJECT . keys ( arg ) . sort ( ) ; while ( ! isUndefined ( ( index = keys . pop ( ) as string ) ) ) { if ( ! isUndefined ( arg [ index ] ) ) { result += index + ':' + stableHash ( arg [ index ] ) + ',' ; } } table . set ( arg , result ) ; } } else { result = isDate ? arg . toJSON ( ) : type == 'symbol' ? arg . toString ( ) : type == 'string' ? JSON . stringify ( arg ) : '' + arg ; } return result ; } ;