1+ var __assign = ( this && this . __assign ) || function ( ) {
2+ __assign = Object . assign || function ( t ) {
3+ for ( var s , i = 1 , n = arguments . length ; i < n ; i ++ ) {
4+ s = arguments [ i ] ;
5+ for ( var p in s ) if ( Object . prototype . hasOwnProperty . call ( s , p ) )
6+ t [ p ] = s [ p ] ;
7+ }
8+ return t ;
9+ } ;
10+ return __assign . apply ( this , arguments ) ;
11+ } ;
112Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
213/*!
314 * https://github.com/Starcounter-Jack/JSON-Patch
415 * (c) 2017 Joachim Wester
516 * MIT license
617 */
718var helpers_js_1 = require ( "./helpers.js" ) ;
19+ var lodash_difference_js_1 = require ( "./lodash-difference.js" ) ;
820var core_js_1 = require ( "./core.js" ) ;
921var beforeDict = new WeakMap ( ) ;
1022var Mirror = /** @class */ ( function ( ) {
@@ -113,6 +125,77 @@ function generate(observer, invertible) {
113125 return temp ;
114126}
115127exports . generate = generate ;
128+ /*
129+ * 'compareArrays' doesnt do a good job with ordering,
130+ * if bad ordering was detected, or bad job, return false, and revert
131+ * to old code. its most likely that there isnt much added value anyway
132+ *
133+ */
134+ function testOrder ( arr1 , arr2 , patches ) {
135+ // we dont want to mess up with arr1
136+ // the patches are just remove / add so need to clone deep
137+ var clonedArr1 = Array . from ( arr1 ) ;
138+ core_js_1 . applyPatch ( clonedArr1 , patches ) ;
139+ if ( clonedArr1 . length !== arr2 . length ) {
140+ return false ;
141+ }
142+ for ( var index = 0 ; index < arr2 . length ; index ++ ) {
143+ if ( clonedArr1 [ index ] !== arr2 [ index ] ) {
144+ return false ;
145+ }
146+ }
147+ return true ;
148+ }
149+ /*
150+ * return array efficient array patches when possible.
151+ * in frequenct cases of arrays additions or removals, where an element was removed, or added.
152+ * and thats the only difference between the arrays, and all other elements are the exact same (===)
153+ * then the code bellow can do a great job and having a very small number of patches.
154+ * in some cases it will revert back to the old behaviour.
155+ *
156+ */
157+ function compareArrays ( arr1 , arr2 , path , invertible ) {
158+ if ( arr1 . length === arr2 . length ) {
159+ return [ ] ;
160+ }
161+ var diff = lodash_difference_js_1 . default ( arr1 , arr2 ) ;
162+ if ( diff . length === arr1 . length ) {
163+ // this means that the the arrays are completly different
164+ // and there is no added value in this function - revert to old behaviour
165+ return [ ] ;
166+ }
167+ var removePatches = [ ] ;
168+ diff . forEach ( function ( value ) {
169+ var index = arr1 . indexOf ( value ) ;
170+ var op = 'remove' ;
171+ removePatches . push ( {
172+ op : op ,
173+ path : "/" + index
174+ } ) ;
175+ if ( invertible ) {
176+ removePatches . push ( {
177+ op : 'test' ,
178+ path : "/" + index ,
179+ value : value
180+ } ) ;
181+ }
182+ } ) ;
183+ diff = lodash_difference_js_1 . default ( arr2 , arr1 ) ;
184+ var addPatches = diff . map ( function ( value ) {
185+ var index = arr2 . indexOf ( value ) ;
186+ var op = 'add' ;
187+ return {
188+ op : op ,
189+ value : value ,
190+ path : "/" + index
191+ } ;
192+ } ) ;
193+ var finalPatches = removePatches . reverse ( ) . concat ( addPatches ) ;
194+ if ( testOrder ( arr1 , arr2 , finalPatches ) ) {
195+ return finalPatches . map ( function ( p ) { return ( __assign ( { } , p , { path : path + p . path } ) ) ; } ) ;
196+ }
197+ return [ ] ;
198+ }
116199// Dirty check if obj is different from mirror, generate patches and update mirror
117200function _generate ( mirror , obj , patches , path , invertible ) {
118201 if ( obj === mirror ) {
@@ -125,6 +208,12 @@ function _generate(mirror, obj, patches, path, invertible) {
125208 var oldKeys = helpers_js_1 . _objectKeys ( mirror ) ;
126209 var changed = false ;
127210 var deleted = false ;
211+ if ( Array . isArray ( mirror ) && Array . isArray ( obj ) ) {
212+ var newPatches = compareArrays ( mirror , obj , path , invertible ) ;
213+ if ( newPatches . length ) {
214+ return newPatches . forEach ( function ( p ) { return patches . push ( p ) ; } ) ;
215+ }
216+ }
128217 //if ever "move" operation is implemented here, make sure this test runs OK: "should not generate the same patch twice (move)"
129218 for ( var t = oldKeys . length - 1 ; t >= 0 ; t -- ) {
130219 var key = oldKeys [ t ] ;
0 commit comments