@@ -6,7 +6,8 @@ export default class JSONDiff {
66 constructor ( oldObj , newObj ) {
77 this . oldObj = oldObj ;
88 this . newObj = newObj ;
9- this . jsonPatch = [ ] ;
9+ this . jsonPatch = [ ] ;
10+ this . deletes = { } ;
1011 }
1112
1213 isEmpty = ( obj ) => {
@@ -33,12 +34,16 @@ export default class JSONDiff {
3334 generateArrDiff ( oldArr , newArr , path ) {
3435 this . walkMiddleSnake ( oldArr , newArr , path ) ;
3536 }
36-
37- generateObjDiff ( oldObj = this . oldObj , newObj = this . newObj , path = '' ) {
37+ setDelete ( path ) {
38+ // make sure inserted to jsonPatch first else will be error
39+ this . deletes [ path ] = this . jsonPatch . length - 1 ;
40+ }
41+ generateObjDiff ( oldObj = this . oldObj , newObj = this . newObj , path = '' , pushToArr = this . jsonPatch ) {
3842 if ( this . isEmpty ( oldObj ) ) {
39- this . jsonPatch . push ( { op : "add" , path : "/" , value : newObj } ) ;
43+ pushToArr . push ( { op : "add" , path : "/" , value : newObj } ) ;
4044 } else if ( this . isEmpty ( newObj ) ) {
41- this . jsonPatch . push ( { op : "delete" , path : "/" } ) ;
45+ pushToArr . push ( { op : "delete" , path : "/" } ) ;
46+ this . setDelete ( '/' ) ;
4247 } else {
4348 const oldKeys = this . getKeys ( oldObj ) ;
4449 const newKeys = this . getKeys ( newObj ) ;
@@ -51,10 +56,12 @@ export default class JSONDiff {
5156 // 1.4. else same, then skip
5257
5358 if ( ! newObj . hasOwnProperty ( oldKeys [ t ] ) ) {
54- this . jsonPatch . push ( { op : "delete" , path : `${ path } /${ oldKeys [ t ] } ` } ) ;
59+ const _p = `${ path } /${ oldKeys [ t ] } ` ;
60+ pushToArr . push ( { op : "delete" , path : _p } ) ;
61+ this . setDelete ( _p ) ;
5562 }
5663 else if ( newObj [ oldKeys [ t ] ] != oldObj [ oldKeys [ t ] ] ) {
57- this . jsonPatch . push ( { op : "replace" , path : `${ path } /${ oldKeys [ t ] } ` , value : newObj [ oldKeys [ t ] ] } ) ;
64+ pushToArr . push ( { op : "replace" , path : `${ path } /${ oldKeys [ t ] } ` , value : newObj [ oldKeys [ t ] ] } ) ;
5865 }
5966 }
6067
@@ -64,7 +71,10 @@ export default class JSONDiff {
6471 // 2.3 else recursive call
6572
6673 if ( ! newObj . hasOwnProperty ( oldKeys [ t ] ) ) {
67- this . jsonPatch . push ( { op : "delete" , path : `${ path } /${ oldKeys [ t ] } ` } ) ;
74+ const _p = `${ path } /${ oldKeys [ t ] } ` ;
75+ pushToArr . push ( { op : "delete" , path : _p } ) ;
76+ this . setDelete ( _p ) ;
77+
6878 } else {
6979 this . generateObjDiff ( oldObj [ oldKeys [ t ] ] , newObj [ oldKeys [ t ] ] , `${ path } /${ oldKeys [ t ] } ` ) ;
7080 }
@@ -78,7 +88,7 @@ export default class JSONDiff {
7888 // 4. add all the remaining new properties to patch
7989 for ( let t = 0 ; t < newKeys . length ; t ++ ) {
8090 if ( ! this . isEmpty ( newObj [ newKeys [ t ] ] ) && ! oldObj . hasOwnProperty ( newKeys [ t ] ) ) {
81- this . jsonPatch . push ( { op : "add" , path : `${ path } /${ newKeys [ t ] } ` , value : newObj [ newKeys [ t ] ] } ) ;
91+ pushToArr . push ( { op : "add" , path : `${ path } /${ newKeys [ t ] } ` , value : newObj [ newKeys [ t ] ] } ) ;
8292 }
8393 }
8494 }
@@ -206,19 +216,16 @@ export default class JSONDiff {
206216 ] ;
207217 }
208218 callbackFunc ( x1 , y1 , x2 , y2 , oldArr , newArr , path_ ) {
209- const lastIndex = Math . max ( 0 , this . jsonPatch . length - 1 ) ;
210219 if ( x1 == x2 ) {
211- if ( typeof newArr [ y1 ] == 'object' && ! Array . isArray ( newArr [ y1 ] ) &&
212- ( this . jsonPatch [ lastIndex ] ?. path == `${ path_ } /${ y1 } `
213- && this . jsonPatch [ lastIndex ] ?. op == 'delete' ) ) {
220+ const _p = `${ path_ } /${ y1 } ` ;
221+ if ( typeof newArr [ y1 ] == 'object' && ! Array . isArray ( newArr [ y1 ] ) && this . deletes . hasOwnProperty ( _p ) ) {
214222 // if there is a delete at same index and the type is object check for partial update
215- this . jsonPatch . pop ( ) ;
216- this . generateObjDiff ( oldArr [ y1 ] , newArr [ y1 ] , `${ path_ } /${ y1 } ` ) ;
223+ const arr = [ ] ;
224+ this . generateObjDiff ( oldArr [ y1 ] , newArr [ y1 ] , `${ path_ } /${ y1 } ` , arr ) ;
225+ this . jsonPatch . splice ( this . deletes [ _p ] , 1 , ...arr ) ;
217226 } else {
218- if ( ( this . jsonPatch [ lastIndex ] ?. path == `${ path_ } /${ y1 } `
219- && this . jsonPatch [ lastIndex ] ?. op == 'delete' ) ) {
220- this . jsonPatch . pop ( ) ;
221- this . jsonPatch . push ( {
227+ if ( this . deletes . hasOwnProperty ( _p ) ) {
228+ this . jsonPatch . splice ( this . deletes [ _p ] , 1 , {
222229 op : 'replace' ,
223230 path : `${ path_ } /${ y1 } ` ,
224231 value : newArr [ y1 ]
@@ -232,10 +239,12 @@ export default class JSONDiff {
232239 }
233240 }
234241 } else if ( y1 == y2 ) {
242+ const _p = `${ path_ } /${ x1 } ` ;
235243 this . jsonPatch . push ( {
236244 op : 'delete' ,
237- path : ` ${ path_ } / ${ x1 } `
245+ path : _p
238246 } ) ;
247+ this . setDelete ( _p ) ;
239248 }
240249 }
241250 walkMiddleSnake ( oldArr , newArr , path_ ) {
0 commit comments