@@ -14,21 +14,19 @@ function getLeanDiff(
14
14
showOnly : ObjectDiffOptions [ "showOnly" ] = DEFAULT_OBJECT_DIFF_OPTIONS . showOnly ,
15
15
) : ObjectDiff [ "diff" ] {
16
16
const { statuses, granularity } = showOnly ;
17
- return diff . reduce (
18
- ( acc , value ) => {
19
- if ( granularity === GRANULARITY . DEEP && value . diff ) {
20
- const leanDiff = getLeanDiff ( value . diff , showOnly ) ;
21
- if ( leanDiff . length > 0 ) {
22
- return [ ... acc , { ... value , diff : leanDiff } ] ;
23
- }
17
+ const res : ObjectDiff [ " diff" ] = [ ] ;
18
+ for ( let i = 0 ; i < diff . length ; i ++ ) {
19
+ const value = diff [ i ] ;
20
+ if ( granularity === GRANULARITY . DEEP && value . diff ) {
21
+ const leanDiff = getLeanDiff ( value . diff , showOnly ) ;
22
+ if ( leanDiff . length > 0 ) {
23
+ res . push ( { ... value , diff : leanDiff } ) ;
24
24
}
25
- if ( statuses . includes ( value . status ) ) {
26
- return [ ...acc , value ] ;
27
- }
28
- return acc ;
29
- } ,
30
- [ ] as ObjectDiff [ "diff" ] ,
31
- ) ;
25
+ } else if ( statuses . includes ( value . status ) ) {
26
+ res . push ( value ) ;
27
+ }
28
+ }
29
+ return res ;
32
30
}
33
31
34
32
function getObjectStatus ( diff : ObjectDiff [ "diff" ] ) : OBJECT_STATUS {
@@ -50,34 +48,37 @@ function formatSingleObjectDiff(
50
48
} ;
51
49
}
52
50
const diff : ObjectDiff [ "diff" ] = [ ] ;
53
- Object . entries ( data ) . forEach ( ( [ property , value ] ) => {
51
+
52
+ for ( const [ property , value ] of Object . entries ( data ) ) {
54
53
if ( isObject ( value ) ) {
55
54
const subPropertiesDiff : Diff [ ] = [ ] ;
56
- Object . entries ( value ) . forEach ( ( [ subProperty , subValue ] ) => {
55
+ for ( const [ subProperty , subValue ] of Object . entries ( value ) ) {
57
56
subPropertiesDiff . push ( {
58
57
property : subProperty ,
59
58
previousValue : status === OBJECT_STATUS . ADDED ? undefined : subValue ,
60
59
currentValue : status === OBJECT_STATUS . ADDED ? subValue : undefined ,
61
60
status,
62
61
} ) ;
63
- } ) ;
64
- return diff . push ( {
62
+ }
63
+ diff . push ( {
65
64
property,
66
65
previousValue :
67
66
status === OBJECT_STATUS . ADDED ? undefined : data [ property ] ,
68
67
currentValue : status === OBJECT_STATUS . ADDED ? value : undefined ,
69
68
status,
70
69
diff : subPropertiesDiff ,
71
70
} ) ;
71
+ } else {
72
+ diff . push ( {
73
+ property,
74
+ previousValue :
75
+ status === OBJECT_STATUS . ADDED ? undefined : data [ property ] ,
76
+ currentValue : status === OBJECT_STATUS . ADDED ? value : undefined ,
77
+ status,
78
+ } ) ;
72
79
}
73
- return diff . push ( {
74
- property,
75
- previousValue :
76
- status === OBJECT_STATUS . ADDED ? undefined : data [ property ] ,
77
- currentValue : status === OBJECT_STATUS . ADDED ? value : undefined ,
78
- status,
79
- } ) ;
80
- } ) ;
80
+ }
81
+
81
82
if ( options . showOnly && options . showOnly . statuses . length > 0 ) {
82
83
return {
83
84
type : "object" ,
@@ -92,20 +93,6 @@ function formatSingleObjectDiff(
92
93
} ;
93
94
}
94
95
95
- function getPreviousMatch (
96
- previousValue : unknown | undefined ,
97
- nextSubProperty : unknown ,
98
- options ?: ObjectDiffOptions ,
99
- ) : unknown | undefined {
100
- if ( ! previousValue ) {
101
- return undefined ;
102
- }
103
- const previousMatch = Object . entries ( previousValue ) . find ( ( [ subPreviousKey ] ) =>
104
- isEqual ( subPreviousKey , nextSubProperty , options ) ,
105
- ) ;
106
- return previousMatch ? previousMatch [ 1 ] : undefined ;
107
- }
108
-
109
96
function getValueStatus (
110
97
previousValue : unknown ,
111
98
nextValue : unknown ,
@@ -128,80 +115,70 @@ function getPropertyStatus(subPropertiesDiff: Diff[]): OBJECT_STATUS {
128
115
function getDeletedProperties (
129
116
previousValue : Record < string , unknown > | undefined ,
130
117
nextValue : Record < string , unknown > ,
131
- ) : { property : string ; value : unknown } [ ] | undefined {
132
- if ( ! previousValue ) return undefined ;
133
- const prevKeys = Object . keys ( previousValue ) ;
134
- const nextKeys = Object . keys ( nextValue ) ;
135
- const deletedKeys = prevKeys . filter ( ( prevKey ) => ! nextKeys . includes ( prevKey ) ) ;
136
- if ( deletedKeys . length > 0 ) {
137
- return deletedKeys . map ( ( deletedKey ) => ( {
138
- property : deletedKey ,
139
- value : previousValue [ deletedKey ] ,
140
- } ) ) ;
118
+ ) : { property : string ; value : unknown } [ ] {
119
+ const res : { property : string ; value : unknown } [ ] = [ ] ;
120
+ if ( ! previousValue ) return res ;
121
+ for ( const [ property , value ] of Object . entries ( previousValue ) ) {
122
+ if ( ! ( property in nextValue ) ) {
123
+ res . push ( { property, value } ) ;
124
+ }
141
125
}
142
- return undefined ;
126
+ return res ;
143
127
}
144
128
145
129
function getSubPropertiesDiff (
146
- previousValue : Record < string , unknown > | undefined ,
130
+ previousValue : Record < string , unknown > | undefined = { } ,
147
131
nextValue : Record < string , unknown > ,
148
132
options ?: ObjectDiffOptions ,
149
133
) : Diff [ ] {
150
134
const subPropertiesDiff : Diff [ ] = [ ] ;
151
- let subDiff : Diff [ ] ;
152
- const deletedMainSubProperties = getDeletedProperties (
153
- previousValue ,
154
- nextValue ,
155
- ) ;
156
- if ( deletedMainSubProperties ) {
157
- deletedMainSubProperties . forEach ( ( deletedProperty ) => {
135
+ const allKeys = new Set ( [
136
+ ...Object . keys ( previousValue ) ,
137
+ ...Object . keys ( nextValue ) ,
138
+ ] ) ;
139
+
140
+ for ( const property of allKeys ) {
141
+ const prevSubValue = previousValue [ property ] ;
142
+ const nextSubValue = nextValue [ property ] ;
143
+ if ( ! ( property in nextValue ) ) {
158
144
subPropertiesDiff . push ( {
159
- property : deletedProperty . property ,
160
- previousValue : deletedProperty . value ,
145
+ property,
146
+ previousValue : prevSubValue ,
161
147
currentValue : undefined ,
162
148
status : OBJECT_STATUS . DELETED ,
163
149
} ) ;
164
- } ) ;
165
- }
166
- Object . entries ( nextValue ) . forEach ( ( [ nextSubProperty , nextSubValue ] ) => {
167
- const previousMatch = getPreviousMatch (
168
- previousValue ,
169
- nextSubProperty ,
170
- options ,
171
- ) ;
172
- if ( ! previousMatch ) {
173
- return subPropertiesDiff . push ( {
174
- property : nextSubProperty ,
175
- previousValue : previousMatch ,
150
+ continue ;
151
+ }
152
+ if ( ! ( property in previousValue ) ) {
153
+ subPropertiesDiff . push ( {
154
+ property,
155
+ previousValue : undefined ,
176
156
currentValue : nextSubValue ,
177
- status :
178
- ! previousValue || ! ( nextSubProperty in previousValue )
179
- ? OBJECT_STATUS . ADDED
180
- : previousMatch === nextSubValue
181
- ? OBJECT_STATUS . EQUAL
182
- : OBJECT_STATUS . UPDATED ,
157
+ status : OBJECT_STATUS . ADDED ,
183
158
} ) ;
159
+ continue ;
184
160
}
185
- if ( isObject ( nextSubValue ) ) {
186
- const data : Diff [ ] = getSubPropertiesDiff (
187
- previousMatch as Record < string , unknown > ,
188
- nextSubValue ,
189
- options ,
190
- ) ;
191
- if ( data && data . length > 0 ) {
192
- subDiff = data ;
193
- }
194
- }
195
- if ( previousMatch ) {
161
+ if ( isObject ( nextSubValue ) && isObject ( prevSubValue ) ) {
162
+ const subDiff = getSubPropertiesDiff ( prevSubValue , nextSubValue , options ) ;
163
+ const status =
164
+ subDiff . length > 0 ? OBJECT_STATUS . UPDATED : OBJECT_STATUS . EQUAL ;
165
+ subPropertiesDiff . push ( {
166
+ property,
167
+ previousValue : prevSubValue ,
168
+ currentValue : nextSubValue ,
169
+ status,
170
+ ...( status !== OBJECT_STATUS . EQUAL && { diff : subDiff } ) ,
171
+ } ) ;
172
+ } else {
173
+ const status = getValueStatus ( prevSubValue , nextSubValue , options ) ;
196
174
subPropertiesDiff . push ( {
197
- property : nextSubProperty ,
198
- previousValue : previousMatch ,
175
+ property,
176
+ previousValue : prevSubValue ,
199
177
currentValue : nextSubValue ,
200
- status : getValueStatus ( previousMatch , nextSubValue , options ) ,
201
- ...( ! ! subDiff && { diff : subDiff } ) ,
178
+ status,
202
179
} ) ;
203
180
}
204
- } ) ;
181
+ }
205
182
return subPropertiesDiff ;
206
183
}
207
184
@@ -235,10 +212,10 @@ export function getObjectDiff(
235
212
return formatSingleObjectDiff ( prevData , OBJECT_STATUS . DELETED , options ) ;
236
213
}
237
214
const diff : ObjectDiff [ "diff" ] = [ ] ;
238
- Object . entries ( nextData ) . forEach ( ( [ nextProperty , nextValue ] ) => {
215
+ for ( const [ nextProperty , nextValue ] of Object . entries ( nextData ) ) {
239
216
const previousValue = prevData [ nextProperty ] ;
240
217
if ( ! previousValue ) {
241
- return diff . push ( {
218
+ diff . push ( {
242
219
property : nextProperty ,
243
220
previousValue,
244
221
currentValue : nextValue ,
@@ -248,15 +225,14 @@ export function getObjectDiff(
248
225
? OBJECT_STATUS . EQUAL
249
226
: OBJECT_STATUS . UPDATED ,
250
227
} ) ;
251
- }
252
- if ( isObject ( nextValue ) ) {
228
+ } else if ( isObject ( nextValue ) ) {
253
229
const subPropertiesDiff : Diff [ ] = getSubPropertiesDiff (
254
230
previousValue as Record < string , unknown > ,
255
231
nextValue ,
256
232
options ,
257
233
) ;
258
234
const subPropertyStatus = getPropertyStatus ( subPropertiesDiff ) ;
259
- return diff . push ( {
235
+ diff . push ( {
260
236
property : nextProperty ,
261
237
previousValue,
262
238
currentValue : nextValue ,
@@ -265,23 +241,23 @@ export function getObjectDiff(
265
241
diff : subPropertiesDiff ,
266
242
} ) ,
267
243
} ) ;
268
- }
269
- return diff . push ( {
270
- property : nextProperty ,
271
- previousValue,
272
- currentValue : nextValue ,
273
- status : getValueStatus ( previousValue , nextValue , options ) ,
274
- } ) ;
275
- } ) ;
276
- const deletedProperties = getDeletedProperties ( prevData , nextData ) ;
277
- if ( deletedProperties ) {
278
- deletedProperties . forEach ( ( deletedProperty ) => {
244
+ } else {
279
245
diff . push ( {
280
- property : deletedProperty . property ,
281
- previousValue : deletedProperty . value ,
282
- currentValue : undefined ,
283
- status : OBJECT_STATUS . DELETED ,
246
+ property : nextProperty ,
247
+ previousValue,
248
+ currentValue : nextValue ,
249
+ status : getValueStatus ( previousValue , nextValue , options ) ,
284
250
} ) ;
251
+ }
252
+ }
253
+ const deletedProperties = getDeletedProperties ( prevData , nextData ) ;
254
+ for ( let i = 0 ; i < deletedProperties . length ; i ++ ) {
255
+ const deletedProperty = deletedProperties [ i ] ;
256
+ diff . push ( {
257
+ property : deletedProperty . property ,
258
+ previousValue : deletedProperty . value ,
259
+ currentValue : undefined ,
260
+ status : OBJECT_STATUS . DELETED ,
285
261
} ) ;
286
262
}
287
263
if ( options . showOnly && options . showOnly . statuses . length > 0 ) {
0 commit comments