export const isServer = typeof window === "undefined" ; const hasOwn = Object . prototype . hasOwnProperty ; export const getId = ( params ) : string => { return params . id !== undefined ? params . id : stableStringify ( params ) ; } ; export function stableStringify ( value ) { return JSON . stringify ( value , stableStringifyReplacer ) . replace ( /(\r\n|\n|\r| )/gm , "" ) ; } export function equal ( objA , objB , deep = false ) { if ( is ( objA , objB ) ) return true ; if ( typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null ) { return false ; } const keysA = Object . keys ( objA ) ; const keysB = Object . keys ( objB ) ; if ( keysA . length !== keysB . length ) return false ; for ( let i = 0 ; i < keysA . length ; i ++ ) { if ( ! hasOwn . call ( objB , keysA [ i ] ) || ! compare ( objA [ keysA [ i ] ] , objB [ keysA [ i ] ] , deep ) ) { return false ; } } return true ; } function compare ( objA , objB , deep ) { return deep ? equal ( objA , objB , deep ) : is ( objA , objB ) ; } function is ( x , y ) { if ( x === y ) { return x !== 0 || y !== 0 || 1 / x === 1 / y ; } return x !== x && y !== y ; } function isPlainObject ( o ) { if ( ! hasObjectPrototype ( o ) ) { return false ; } const ctor = o . constructor ; if ( typeof ctor === "undefined" ) { return true ; } const prot = ctor . prototype ; if ( ! hasObjectPrototype ( prot ) ) { return false ; } if ( ! prot . hasOwnProperty ( "isPrototypeOf" ) ) { return false ; } return true ; } function hasObjectPrototype ( o ) { return Object . prototype . toString . call ( o ) === "[object Object]" ; } function stableStringifyReplacer ( _key , value ) { if ( typeof value === "function" ) { return "function" ; } if ( isPlainObject ( value ) ) { return Object . keys ( value ) . sort ( ) . reduce ( ( result , key ) => { result [ key ] = JSON . stringify ( value [ key ] , stableStringifyReplacer ) ; return result ; } , { } as any ) ; } return value ; }