export const EMPTY_OBJ = Object.freeze({})
export const isEmpty = (e) => !(e && Object.keys(e).length)
export const strictEqual = (e, t) => e === t
export const objEqual = (e, t, o = strictEqual) => {
if (!e) return !t
if (!t) return !e
const r = Object.keys(e),
n = Object.keys(t)
return r.length === n.length && r.reduce((r, n) => (r ? o(e[n], t[n]) : r), !0)
}
export const defaultEqual = (e, t) =>
"object" == typeof e && "object" == typeof t ? !!objEqual(e, t) : e === t
export const getObjChange = (e, t, o) => {
if (isEmpty(t)) return null
if (isEmpty(e)) return t
const r = Object.keys(t).reduce((r, n) => {
let c = defaultEqual
return (
"function" == typeof o ? (c = o) : o && "function" == typeof o[n] && (c = o[n]),
c(e[n], t[n]) || (r[n] = t[n]),
r
)
}, {})
return isEmpty(r) ? null : r
}
export const objKeysEqual = (e, t) => {
const o = Object.keys(e),
r = Object.keys(t)
return o.length === r.length && o.reduce((e, o) => (e ? !!t[o] : e), !0)
}
export const hasObjChanges = (e, t) =>
!isEmpty(t) &&
(!e ||
Object.keys(t).reduce((o, r) => {
if (o) return o
if (t[r] && "object" == typeof t[r])
throw new Error("unable to compare nested objects: primitives only")
return e[r] !== t[r] && void 0 !== t[r]
}, !1))
export const deepDiff = (e, t) => {
const o = {},
r = (e) => e && "object" == typeof e && !Array.isArray(e),
n = (e, t, o) => {
const c = new Set([...Object.keys(e || {}), ...Object.keys(t || {})])
for (const s of c) {
const c = e?.[s],
u = t?.[s]
if (r(c) && r(u)) {
const e = {}
;(n(c, u, e), Object.keys(e).length > 0 && (o[s] = e))
} else c !== u && (o[s] = { prev: c, next: u })
}
}
return (n(e, t, o), o)
}