@@ -29,9 +29,6 @@ export function jsonDiff(lhs: any, rhs: any): JsonChange[] {
29
29
30
30
walkJsonTree ( lhs , [ ] , ( path , lhsValue ) => {
31
31
seenInLhs . add ( hashArray ( path ) ) ;
32
- if ( typeof lhsValue === 'object' ) {
33
- return true ;
34
- }
35
32
const rhsValue = getJsonValue ( path , rhs ) ;
36
33
if ( rhsValue === undefined ) {
37
34
result . push ( {
@@ -42,7 +39,7 @@ export function jsonDiff(lhs: any, rhs: any): JsonChange[] {
42
39
rhs : undefined
43
40
}
44
41
} ) ;
45
- } else if ( lhsValue !== rhsValue ) {
42
+ } else if ( ! deepEquals ( lhsValue , rhsValue ) ) {
46
43
result . push ( {
47
44
type : DiffType . Modified ,
48
45
path,
@@ -52,13 +49,10 @@ export function jsonDiff(lhs: any, rhs: any): JsonChange[] {
52
49
}
53
50
} ) ;
54
51
}
55
- return false ;
52
+ return typeof lhsValue === 'object' ;
56
53
} ) ;
57
54
58
55
walkJsonTree ( rhs , [ ] , ( path , rhsValue ) => {
59
- if ( typeof rhsValue === 'object' ) {
60
- return true ;
61
- }
62
56
const addedInRhs = ! seenInLhs . has ( hashArray ( path ) ) ;
63
57
if ( addedInRhs ) {
64
58
result . push ( {
@@ -71,6 +65,7 @@ export function jsonDiff(lhs: any, rhs: any): JsonChange[] {
71
65
} ) ;
72
66
return false ;
73
67
}
68
+ return typeof rhsValue === 'object' ;
74
69
} ) ;
75
70
76
71
return result ;
@@ -85,7 +80,6 @@ export function walkJsonTree(
85
80
if ( ! json || typeof json !== 'object' ) {
86
81
return ;
87
82
}
88
-
89
83
Object . keys ( json ) . forEach ( key => {
90
84
const path = currPath . concat ( [ key ] ) ;
91
85
const shouldContinue = visitor ( path , json [ key ] ) ;
@@ -109,3 +103,32 @@ function getJsonValue(path: string[], json: any): void | any {
109
103
}
110
104
return curr ;
111
105
}
106
+
107
+ function deepEquals ( a : any , b : any ) : boolean {
108
+ if ( a === b ) {
109
+ return true ;
110
+ }
111
+
112
+ // Values do not need to be checked for deep equality and the above is false
113
+ if (
114
+ // Values are different types
115
+ typeof a !== typeof b ||
116
+ // Values are the same type but not an object or array
117
+ ( typeof a !== 'object' && ! Array . isArray ( a ) ) ||
118
+ // Objects are the same type, objects or arrays, but do not have the same number of keys
119
+ Object . keys ( a ) . length !== Object . keys ( b ) . length
120
+ ) {
121
+ return false ;
122
+ }
123
+
124
+ // Values need to be checked for deep equality
125
+ return Object . entries ( a ) . reduce ( ( equal , [ key , aValue ] ) => {
126
+ // Skip other keys if it is already not equal.
127
+ if ( ! equal ) {
128
+ return equal ;
129
+ }
130
+
131
+ // Traverse the object
132
+ return deepEquals ( aValue , b [ key ] ) ;
133
+ } , true ) ;
134
+ }
0 commit comments