Skip to content

Instantly share code, notes, and snippets.

@pointofpresence
Last active March 31, 2024 20:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pointofpresence/5f9386c753995f1cf6a4fa1a91858599 to your computer and use it in GitHub Desktop.
Save pointofpresence/5f9386c753995f1cf6a4fa1a91858599 to your computer and use it in GitHub Desktop.
DeepDiffMapper
export default class DeepDiffMapper {
static VALUE_CREATED = 'created'
static VALUE_UPDATED = 'updated'
static VALUE_DELETED = 'deleted'
static VALUE_UNCHANGED = 'unchanged'
static map(obj1, obj2, changedOnly = true) {
let key
if(_.isFunction(obj1) || _.isFunction(obj2)) {
throw 'Invalid argument. Function given, object expected.'
}
if(DeepDiffMapper.isValue(obj1) || DeepDiffMapper.isValue(obj2)) {
const type = DeepDiffMapper.compareValues(obj1, obj2)
if(type === DeepDiffMapper.VALUE_UNCHANGED && changedOnly) {
return
}
return {
type,
data: _.isUndefined(obj1) ? obj2 : obj1,
...(
type === DeepDiffMapper.VALUE_UPDATED || type === DeepDiffMapper.VALUE_CREATED
? { data: obj2 }
: {}),
...(
type === DeepDiffMapper.VALUE_UPDATED || type === DeepDiffMapper.VALUE_DELETED
? { oldData: obj1 }
: {}
)
}
}
let diff = {}
let ignored = {}
for(let key in obj1) {
if(_.isFunction(obj1[key])) {
continue
}
let value2 = undefined
if(obj2[key] !== undefined) {
value2 = obj2[key]
}
const result = DeepDiffMapper.map(obj1[key], value2, changedOnly)
if(!result && changedOnly) {
ignored[key] = true
continue
}
diff[key] = result
}
for(key in obj2) {
if(ignored[key] || _.isFunction(obj2[key]) || diff[key] !== undefined) {
continue
}
const result = DeepDiffMapper.map(undefined, obj2[key], changedOnly)
if(!result && changedOnly) {
continue
}
diff[key] = result
}
return _.isEmpty(diff) ? undefined : diff
}
static compareValues(value1, value2) {
if(value1 === value2) {
return DeepDiffMapper.VALUE_UNCHANGED
}
if(DeepDiffMapper.isDate(value1) && DeepDiffMapper.isDate(value2)
&& value1.getTime() === value2.getTime()) {
return DeepDiffMapper.VALUE_UNCHANGED
}
if(value1 === undefined) {
return DeepDiffMapper.VALUE_CREATED
}
if(value2 === undefined) {
return DeepDiffMapper.VALUE_DELETED
}
return DeepDiffMapper.VALUE_UPDATED
}
static isDate = x => Object.prototype.toString.call(x) === '[object Date]'
static isValue = x => !_.isObject(x) && !_.isArray(x)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment