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,74 @@ 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 = arr1 . map ( function ( e ) { return e ; } ) ;
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+ var diff = lodash_difference_js_1 . default ( arr1 , arr2 ) ;
159+ if ( diff . length === arr1 . length ) {
160+ // this means that the the arrays are completly different
161+ // and there is no added value in this function - revert to old behaviour
162+ return [ ] ;
163+ }
164+ var removePatches = [ ] ;
165+ diff . forEach ( function ( value ) {
166+ var index = arr1 . indexOf ( value ) ;
167+ var op = 'remove' ;
168+ removePatches . push ( {
169+ op : op ,
170+ path : "/" + index
171+ } ) ;
172+ if ( invertible ) {
173+ removePatches . push ( {
174+ op : 'test' ,
175+ path : "/" + index ,
176+ value : value
177+ } ) ;
178+ }
179+ } ) ;
180+ diff = lodash_difference_js_1 . default ( arr2 , arr1 ) ;
181+ var addPatches = diff . map ( function ( value ) {
182+ var index = arr2 . indexOf ( value ) ;
183+ var op = 'add' ;
184+ return {
185+ op : op ,
186+ value : value ,
187+ path : "/" + index
188+ } ;
189+ } ) ;
190+ var finalPatches = removePatches . reverse ( ) . concat ( addPatches ) ;
191+ if ( testOrder ( arr1 , arr2 , finalPatches ) ) {
192+ return finalPatches . map ( function ( p ) { return ( __assign ( { } , p , { path : path + p . path } ) ) ; } ) ;
193+ }
194+ return [ ] ;
195+ }
116196// Dirty check if obj is different from mirror, generate patches and update mirror
117197function _generate ( mirror , obj , patches , path , invertible ) {
118198 if ( obj === mirror ) {
@@ -125,6 +205,12 @@ function _generate(mirror, obj, patches, path, invertible) {
125205 var oldKeys = helpers_js_1 . _objectKeys ( mirror ) ;
126206 var changed = false ;
127207 var deleted = false ;
208+ if ( Array . isArray ( mirror ) && Array . isArray ( obj ) ) {
209+ var newPatches = compareArrays ( mirror , obj , path , invertible ) ;
210+ if ( newPatches . length ) {
211+ return newPatches . forEach ( function ( p ) { return patches . push ( p ) ; } ) ;
212+ }
213+ }
128214 //if ever "move" operation is implemented here, make sure this test runs OK: "should not generate the same patch twice (move)"
129215 for ( var t = oldKeys . length - 1 ; t >= 0 ; t -- ) {
130216 var key = oldKeys [ t ] ;
0 commit comments