@@ -14,21 +14,19 @@ function getLeanDiff(
1414 showOnly : ObjectDiffOptions [ "showOnly" ] = DEFAULT_OBJECT_DIFF_OPTIONS . showOnly ,
1515) : ObjectDiff [ "diff" ] {
1616 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 } ) ;
2424 }
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 ;
3230}
3331
3432function getObjectStatus ( diff : ObjectDiff [ "diff" ] ) : OBJECT_STATUS {
@@ -50,34 +48,37 @@ function formatSingleObjectDiff(
5048 } ;
5149 }
5250 const diff : ObjectDiff [ "diff" ] = [ ] ;
53- Object . entries ( data ) . forEach ( ( [ property , value ] ) => {
51+
52+ for ( const [ property , value ] of Object . entries ( data ) ) {
5453 if ( isObject ( value ) ) {
5554 const subPropertiesDiff : Diff [ ] = [ ] ;
56- Object . entries ( value ) . forEach ( ( [ subProperty , subValue ] ) => {
55+ for ( const [ subProperty , subValue ] of Object . entries ( value ) ) {
5756 subPropertiesDiff . push ( {
5857 property : subProperty ,
5958 previousValue : status === OBJECT_STATUS . ADDED ? undefined : subValue ,
6059 currentValue : status === OBJECT_STATUS . ADDED ? subValue : undefined ,
6160 status,
6261 } ) ;
63- } ) ;
64- return diff . push ( {
62+ }
63+ diff . push ( {
6564 property,
6665 previousValue :
6766 status === OBJECT_STATUS . ADDED ? undefined : data [ property ] ,
6867 currentValue : status === OBJECT_STATUS . ADDED ? value : undefined ,
6968 status,
7069 diff : subPropertiesDiff ,
7170 } ) ;
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+ } ) ;
7279 }
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+
8182 if ( options . showOnly && options . showOnly . statuses . length > 0 ) {
8283 return {
8384 type : "object" ,
@@ -92,20 +93,6 @@ function formatSingleObjectDiff(
9293 } ;
9394}
9495
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-
10996function getValueStatus (
11097 previousValue : unknown ,
11198 nextValue : unknown ,
@@ -128,80 +115,70 @@ function getPropertyStatus(subPropertiesDiff: Diff[]): OBJECT_STATUS {
128115function getDeletedProperties (
129116 previousValue : Record < string , unknown > | undefined ,
130117 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+ }
141125 }
142- return undefined ;
126+ return res ;
143127}
144128
145129function getSubPropertiesDiff (
146- previousValue : Record < string , unknown > | undefined ,
130+ previousValue : Record < string , unknown > | undefined = { } ,
147131 nextValue : Record < string , unknown > ,
148132 options ?: ObjectDiffOptions ,
149133) : Diff [ ] {
150134 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 ) ) {
158144 subPropertiesDiff . push ( {
159- property : deletedProperty . property ,
160- previousValue : deletedProperty . value ,
145+ property,
146+ previousValue : prevSubValue ,
161147 currentValue : undefined ,
162148 status : OBJECT_STATUS . DELETED ,
163149 } ) ;
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 ,
176156 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 ,
183158 } ) ;
159+ continue ;
184160 }
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 ) ;
196174 subPropertiesDiff . push ( {
197- property : nextSubProperty ,
198- previousValue : previousMatch ,
175+ property,
176+ previousValue : prevSubValue ,
199177 currentValue : nextSubValue ,
200- status : getValueStatus ( previousMatch , nextSubValue , options ) ,
201- ...( ! ! subDiff && { diff : subDiff } ) ,
178+ status,
202179 } ) ;
203180 }
204- } ) ;
181+ }
205182 return subPropertiesDiff ;
206183}
207184
@@ -235,10 +212,10 @@ export function getObjectDiff(
235212 return formatSingleObjectDiff ( prevData , OBJECT_STATUS . DELETED , options ) ;
236213 }
237214 const diff : ObjectDiff [ "diff" ] = [ ] ;
238- Object . entries ( nextData ) . forEach ( ( [ nextProperty , nextValue ] ) => {
215+ for ( const [ nextProperty , nextValue ] of Object . entries ( nextData ) ) {
239216 const previousValue = prevData [ nextProperty ] ;
240217 if ( ! previousValue ) {
241- return diff . push ( {
218+ diff . push ( {
242219 property : nextProperty ,
243220 previousValue,
244221 currentValue : nextValue ,
@@ -248,15 +225,14 @@ export function getObjectDiff(
248225 ? OBJECT_STATUS . EQUAL
249226 : OBJECT_STATUS . UPDATED ,
250227 } ) ;
251- }
252- if ( isObject ( nextValue ) ) {
228+ } else if ( isObject ( nextValue ) ) {
253229 const subPropertiesDiff : Diff [ ] = getSubPropertiesDiff (
254230 previousValue as Record < string , unknown > ,
255231 nextValue ,
256232 options ,
257233 ) ;
258234 const subPropertyStatus = getPropertyStatus ( subPropertiesDiff ) ;
259- return diff . push ( {
235+ diff . push ( {
260236 property : nextProperty ,
261237 previousValue,
262238 currentValue : nextValue ,
@@ -265,23 +241,23 @@ export function getObjectDiff(
265241 diff : subPropertiesDiff ,
266242 } ) ,
267243 } ) ;
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 {
279245 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 ) ,
284250 } ) ;
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 ,
285261 } ) ;
286262 }
287263 if ( options . showOnly && options . showOnly . statuses . length > 0 ) {
0 commit comments