From 85dbdf21ba291ad441e6731c5268e30593c8a685 Mon Sep 17 00:00:00 2001 From: Vladimir Barbaros Date: Sat, 14 Sep 2024 08:11:46 +0300 Subject: [PATCH 1/2] fix #295 --- packages/jsondiffpatch/src/filters/arrays.ts | 55 ++++----- .../jsondiffpatch/test/examples/diffpatch.ts | 116 ++++++++++++++++++ 2 files changed, 142 insertions(+), 29 deletions(-) diff --git a/packages/jsondiffpatch/src/filters/arrays.ts b/packages/jsondiffpatch/src/filters/arrays.ts index e891c18e..a118fdc1 100644 --- a/packages/jsondiffpatch/src/filters/arrays.ts +++ b/packages/jsondiffpatch/src/filters/arrays.ts @@ -455,39 +455,36 @@ const reverseArrayDeltaIndex = ( return `_${index as number}` as const; } - let reverseIndex = +index; - for (const deltaIndex in delta) { - const deltaItem = delta[deltaIndex as `${number}` | `_${number}`]; - if (Array.isArray(deltaItem)) { - if (deltaItem[2] === ARRAY_MOVE) { - const moveFromIndex = parseInt(deltaIndex.substring(1), 10); - const moveToIndex = (deltaItem as MovedDelta)[1]; - if (moveToIndex === +index) { - return moveFromIndex; - } - if (moveFromIndex <= reverseIndex && moveToIndex > reverseIndex) { - reverseIndex++; - } else if ( - moveFromIndex >= reverseIndex && - moveToIndex < reverseIndex - ) { - reverseIndex--; - } - } else if (deltaItem[2] === 0) { - const deleteIndex = parseInt(deltaIndex.substring(1), 10); - if (deleteIndex <= reverseIndex) { - reverseIndex++; - } - } else if ( - deltaItem.length === 1 && - parseInt(deltaIndex, 10) <= reverseIndex - ) { - reverseIndex--; + index = parseInt(index as string); + + const remove = [] as Array; + const insert = [] as Array; + for (const key in delta) { + if (key === '_t') { + continue; + } + const value = delta[key as `${number}` | `_${number}`]; + if (!Array.isArray(value)) { + continue; + } + if (key[0] === '_') { + if (value[1] === index) { // "_555": [old,x,3] + return parseInt(key.substring(1)); } + insert.push(parseInt(key.substring(1))); + if (value[2] === ARRAY_MOVE) { // "_555": [old,x,3] + remove.push((value as MovedDelta)[1]); + } + continue; + } + if (value.length === 1) { // "555": [new] + remove.push(parseInt(key)); } } - return reverseIndex; + let out = index - remove.reduce((a,v) => a + (v < (index as number) ? 1 : 0), 0); + insert.sort((a,b) => a - b).forEach(v => out += (v <= out ? 1 : 0)); + return out; }; export const collectChildrenReverseFilter: Filter = ( diff --git a/packages/jsondiffpatch/test/examples/diffpatch.ts b/packages/jsondiffpatch/test/examples/diffpatch.ts index 8b805ac2..e918c87c 100644 --- a/packages/jsondiffpatch/test/examples/diffpatch.ts +++ b/packages/jsondiffpatch/test/examples/diffpatch.ts @@ -881,6 +881,122 @@ const arrays: ExampleGroup = [ }, exactReverse: false, }, + { + name: 'issue 295 • case 1 | https://github.com/benjamine/jsondiffpatch/issues/295', + exactReverse: false, + options: { + objectHash(obj: { id?: string }, index?: number) { + return obj.id || `$$index:${index}`; + }, + }, + left: [ + {id: 1, style: {zIndex: 1}}, + {id: 2, style: {zIndex: 2}}, + {id: 3, style: {zIndex: 3}}, + {id: 4, style: {zIndex: 4}}, + {id: 5, style: {zIndex: 5}}, + {id: 6, style: {zIndex: 6}}, + {id: 7, style: {zIndex: 7}}, + {id: 8, style: {zIndex: 8}}, + {id: 9, style: {zIndex: 9}}, + ], + right: [ + {id: 7, style: {zIndex: 1}}, + {id: 8, style: {zIndex: 2}}, + {id: 9, style: {zIndex: 3}}, + {id: 1, style: {zIndex: 4}}, + {id: 2, style: {zIndex: 5}}, + {id: 3, style: {zIndex: 6}}, + {id: 4, style: {zIndex: 7}}, + {id: 5, style: {zIndex: 8}}, + {id: 6, style: {zIndex: 9}}, + ], + delta: { + 0: {style: {zIndex: [7, 1]}}, + 1: {style: {zIndex: [8, 2]}}, + 2: {style: {zIndex: [9, 3]}}, + 3: {style: {zIndex: [1, 4]}}, + 4: {style: {zIndex: [2, 5]}}, + 5: {style: {zIndex: [3, 6]}}, + 6: {style: {zIndex: [4, 7]}}, + 7: {style: {zIndex: [5, 8]}}, + 8: {style: {zIndex: [6, 9]}}, + _t: 'a', + _6: ['', 0, 3], + _7: ['', 1, 3], + _8: ['', 2, 3] + } + , + reverse: { + 0: {style: {zIndex: [4, 1]}}, + 1: {style: {zIndex: [5, 2]}}, + 2: {style: {zIndex: [6, 3]}}, + 3: {style: {zIndex: [7, 4]}}, + 4: {style: {zIndex: [8, 5]}}, + 5: {style: {zIndex: [9, 6]}}, + 6: {style: {zIndex: [1, 7]}}, + 7: {style: {zIndex: [2, 8]}}, + 8: {style: {zIndex: [3, 9]}}, + _t: 'a', + _0: ['', 6, 3], + _1: ['', 7, 3], + _2: ['', 8, 3] + }, + }, + { + name: 'issue 295 • case 2 | https://github.com/benjamine/jsondiffpatch/issues/295', + exactReverse: false, + options: { + objectHash(obj: { uid?: string }, index?: number) { + return obj.uid || `$$index:${index}`; + }, + }, + left: [ + {uid: 'scene', parent_uid: null}, + {uid: 'txt_clztu14dm00042v6j71u1c9k3', parent_uid: 'scene'}, + {uid: 'grp_cm0vzowcd00022v6izleecn6c', parent_uid: 'scene'}, + {uid: 'txt_cm01a5cpi00012v6inbaunav1', parent_uid: 'grp_cm0vzowcd00022v6izleecn6c'}, + {uid: 'txt_cm097vd9000012v6i9tsfrff2', parent_uid: 'grp_cm0vzowcd00022v6izleecn6c'}, + {uid: 'txt_cm097w3zp00022v6iek5pr7id', parent_uid: 'grp_cm0vzowcd00022v6izleecn6c'}, + {uid: 'fdr_cm0ukrqom00002v6ixqokqydk', parent_uid: 'scene'}, + {uid: 'fdr_cm0umi0e000002v6ivbkyzpwf', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, + {uid: 'txt_cm0bc6t0900022v6ij7baxq2d', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, + {uid: 'txt_cm0bc70dh00032v6im4wawi5v', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, + {uid: 'fdr_cm0vznwt800012v6ial614xz1', parent_uid: 'scene'}, + {uid: 'txt_cm0bc5aid00002v6iu6e4a0m5', parent_uid: 'scene'}, + ], + right: [ + {uid: 'scene', parent_uid: null}, + {uid: 'txt_clztu14dm00042v6j71u1c9k3', parent_uid: 'scene'}, + {uid: 'txt_cm01a5cpi00012v6inbaunav1', parent_uid: 'scene'}, + {uid: 'fdr_cm0ukrqom00002v6ixqokqydk', parent_uid: 'scene'}, + {uid: 'fdr_cm0umi0e000002v6ivbkyzpwf', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, + {uid: 'txt_cm097vd9000012v6i9tsfrff2', parent_uid: 'fdr_cm0umi0e000002v6ivbkyzpwf'}, + {uid: 'txt_cm097w3zp00022v6iek5pr7id', parent_uid: 'fdr_cm0umi0e000002v6ivbkyzpwf'}, + {uid: 'txt_cm0bc6t0900022v6ij7baxq2d', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, + {uid: 'txt_cm0bc70dh00032v6im4wawi5v', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, + {uid: 'fdr_cm0vznwt800012v6ial614xz1', parent_uid: 'scene'}, + {uid: 'txt_cm0bc5aid00002v6iu6e4a0m5', parent_uid: 'scene'} + ], + delta: { + 2: {parent_uid: ['grp_cm0vzowcd00022v6izleecn6c', 'scene']}, + 5: {parent_uid: ['grp_cm0vzowcd00022v6izleecn6c', 'fdr_cm0umi0e000002v6ivbkyzpwf']}, + 6: {parent_uid: ['grp_cm0vzowcd00022v6izleecn6c', 'fdr_cm0umi0e000002v6ivbkyzpwf']}, + _t: 'a', + _2: [{uid: 'grp_cm0vzowcd00022v6izleecn6c', parent_uid: 'scene'}, 0, 0], + _6: ['', 3, 3], + _7: ['', 4, 3], + }, + reverse: { + 2: [{uid: 'grp_cm0vzowcd00022v6izleecn6c', parent_uid: 'scene'}], + 3: {parent_uid: ['scene', 'grp_cm0vzowcd00022v6izleecn6c']}, + 4: {parent_uid: ['fdr_cm0umi0e000002v6ivbkyzpwf', 'grp_cm0vzowcd00022v6izleecn6c']}, + 5: {parent_uid: ['fdr_cm0umi0e000002v6ivbkyzpwf', 'grp_cm0vzowcd00022v6izleecn6c']}, + _t: 'a', + _5: ['', 4, 3], + _6: ['', 5, 3], + }, + }, { name: 'nested', options: { From af75609bc8720cdf84283fef044f97369562c2d4 Mon Sep 17 00:00:00 2001 From: Vladimir Barbaros Date: Sat, 14 Sep 2024 15:43:08 +0300 Subject: [PATCH 2/2] fix code style | npx prettier . --write --- packages/jsondiffpatch/src/filters/arrays.ts | 14 +- .../jsondiffpatch/test/examples/diffpatch.ts | 194 +++++++++++------- 2 files changed, 132 insertions(+), 76 deletions(-) diff --git a/packages/jsondiffpatch/src/filters/arrays.ts b/packages/jsondiffpatch/src/filters/arrays.ts index a118fdc1..ef9e946d 100644 --- a/packages/jsondiffpatch/src/filters/arrays.ts +++ b/packages/jsondiffpatch/src/filters/arrays.ts @@ -468,22 +468,26 @@ const reverseArrayDeltaIndex = ( continue; } if (key[0] === '_') { - if (value[1] === index) { // "_555": [old,x,3] + if (value[1] === index) { + // "_555": [old,x,3] return parseInt(key.substring(1)); } insert.push(parseInt(key.substring(1))); - if (value[2] === ARRAY_MOVE) { // "_555": [old,x,3] + if (value[2] === ARRAY_MOVE) { + // "_555": [old,x,3] remove.push((value as MovedDelta)[1]); } continue; } - if (value.length === 1) { // "555": [new] + if (value.length === 1) { + // "555": [new] remove.push(parseInt(key)); } } - let out = index - remove.reduce((a,v) => a + (v < (index as number) ? 1 : 0), 0); - insert.sort((a,b) => a - b).forEach(v => out += (v <= out ? 1 : 0)); + let out = + index - remove.reduce((a, v) => a + (v < (index as number) ? 1 : 0), 0); + insert.sort((a, b) => a - b).forEach((v) => (out += v <= out ? 1 : 0)); return out; }; diff --git a/packages/jsondiffpatch/test/examples/diffpatch.ts b/packages/jsondiffpatch/test/examples/diffpatch.ts index e918c87c..3f6636b8 100644 --- a/packages/jsondiffpatch/test/examples/diffpatch.ts +++ b/packages/jsondiffpatch/test/examples/diffpatch.ts @@ -890,57 +890,56 @@ const arrays: ExampleGroup = [ }, }, left: [ - {id: 1, style: {zIndex: 1}}, - {id: 2, style: {zIndex: 2}}, - {id: 3, style: {zIndex: 3}}, - {id: 4, style: {zIndex: 4}}, - {id: 5, style: {zIndex: 5}}, - {id: 6, style: {zIndex: 6}}, - {id: 7, style: {zIndex: 7}}, - {id: 8, style: {zIndex: 8}}, - {id: 9, style: {zIndex: 9}}, + { id: 1, style: { zIndex: 1 } }, + { id: 2, style: { zIndex: 2 } }, + { id: 3, style: { zIndex: 3 } }, + { id: 4, style: { zIndex: 4 } }, + { id: 5, style: { zIndex: 5 } }, + { id: 6, style: { zIndex: 6 } }, + { id: 7, style: { zIndex: 7 } }, + { id: 8, style: { zIndex: 8 } }, + { id: 9, style: { zIndex: 9 } }, ], right: [ - {id: 7, style: {zIndex: 1}}, - {id: 8, style: {zIndex: 2}}, - {id: 9, style: {zIndex: 3}}, - {id: 1, style: {zIndex: 4}}, - {id: 2, style: {zIndex: 5}}, - {id: 3, style: {zIndex: 6}}, - {id: 4, style: {zIndex: 7}}, - {id: 5, style: {zIndex: 8}}, - {id: 6, style: {zIndex: 9}}, + { id: 7, style: { zIndex: 1 } }, + { id: 8, style: { zIndex: 2 } }, + { id: 9, style: { zIndex: 3 } }, + { id: 1, style: { zIndex: 4 } }, + { id: 2, style: { zIndex: 5 } }, + { id: 3, style: { zIndex: 6 } }, + { id: 4, style: { zIndex: 7 } }, + { id: 5, style: { zIndex: 8 } }, + { id: 6, style: { zIndex: 9 } }, ], delta: { - 0: {style: {zIndex: [7, 1]}}, - 1: {style: {zIndex: [8, 2]}}, - 2: {style: {zIndex: [9, 3]}}, - 3: {style: {zIndex: [1, 4]}}, - 4: {style: {zIndex: [2, 5]}}, - 5: {style: {zIndex: [3, 6]}}, - 6: {style: {zIndex: [4, 7]}}, - 7: {style: {zIndex: [5, 8]}}, - 8: {style: {zIndex: [6, 9]}}, + 0: { style: { zIndex: [7, 1] } }, + 1: { style: { zIndex: [8, 2] } }, + 2: { style: { zIndex: [9, 3] } }, + 3: { style: { zIndex: [1, 4] } }, + 4: { style: { zIndex: [2, 5] } }, + 5: { style: { zIndex: [3, 6] } }, + 6: { style: { zIndex: [4, 7] } }, + 7: { style: { zIndex: [5, 8] } }, + 8: { style: { zIndex: [6, 9] } }, _t: 'a', _6: ['', 0, 3], _7: ['', 1, 3], - _8: ['', 2, 3] - } - , + _8: ['', 2, 3], + }, reverse: { - 0: {style: {zIndex: [4, 1]}}, - 1: {style: {zIndex: [5, 2]}}, - 2: {style: {zIndex: [6, 3]}}, - 3: {style: {zIndex: [7, 4]}}, - 4: {style: {zIndex: [8, 5]}}, - 5: {style: {zIndex: [9, 6]}}, - 6: {style: {zIndex: [1, 7]}}, - 7: {style: {zIndex: [2, 8]}}, - 8: {style: {zIndex: [3, 9]}}, + 0: { style: { zIndex: [4, 1] } }, + 1: { style: { zIndex: [5, 2] } }, + 2: { style: { zIndex: [6, 3] } }, + 3: { style: { zIndex: [7, 4] } }, + 4: { style: { zIndex: [8, 5] } }, + 5: { style: { zIndex: [9, 6] } }, + 6: { style: { zIndex: [1, 7] } }, + 7: { style: { zIndex: [2, 8] } }, + 8: { style: { zIndex: [3, 9] } }, _t: 'a', _0: ['', 6, 3], _1: ['', 7, 3], - _2: ['', 8, 3] + _2: ['', 8, 3], }, }, { @@ -952,46 +951,99 @@ const arrays: ExampleGroup = [ }, }, left: [ - {uid: 'scene', parent_uid: null}, - {uid: 'txt_clztu14dm00042v6j71u1c9k3', parent_uid: 'scene'}, - {uid: 'grp_cm0vzowcd00022v6izleecn6c', parent_uid: 'scene'}, - {uid: 'txt_cm01a5cpi00012v6inbaunav1', parent_uid: 'grp_cm0vzowcd00022v6izleecn6c'}, - {uid: 'txt_cm097vd9000012v6i9tsfrff2', parent_uid: 'grp_cm0vzowcd00022v6izleecn6c'}, - {uid: 'txt_cm097w3zp00022v6iek5pr7id', parent_uid: 'grp_cm0vzowcd00022v6izleecn6c'}, - {uid: 'fdr_cm0ukrqom00002v6ixqokqydk', parent_uid: 'scene'}, - {uid: 'fdr_cm0umi0e000002v6ivbkyzpwf', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, - {uid: 'txt_cm0bc6t0900022v6ij7baxq2d', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, - {uid: 'txt_cm0bc70dh00032v6im4wawi5v', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, - {uid: 'fdr_cm0vznwt800012v6ial614xz1', parent_uid: 'scene'}, - {uid: 'txt_cm0bc5aid00002v6iu6e4a0m5', parent_uid: 'scene'}, + { uid: 'scene', parent_uid: null }, + { uid: 'txt_clztu14dm00042v6j71u1c9k3', parent_uid: 'scene' }, + { uid: 'grp_cm0vzowcd00022v6izleecn6c', parent_uid: 'scene' }, + { + uid: 'txt_cm01a5cpi00012v6inbaunav1', + parent_uid: 'grp_cm0vzowcd00022v6izleecn6c', + }, + { + uid: 'txt_cm097vd9000012v6i9tsfrff2', + parent_uid: 'grp_cm0vzowcd00022v6izleecn6c', + }, + { + uid: 'txt_cm097w3zp00022v6iek5pr7id', + parent_uid: 'grp_cm0vzowcd00022v6izleecn6c', + }, + { uid: 'fdr_cm0ukrqom00002v6ixqokqydk', parent_uid: 'scene' }, + { + uid: 'fdr_cm0umi0e000002v6ivbkyzpwf', + parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk', + }, + { + uid: 'txt_cm0bc6t0900022v6ij7baxq2d', + parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk', + }, + { + uid: 'txt_cm0bc70dh00032v6im4wawi5v', + parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk', + }, + { uid: 'fdr_cm0vznwt800012v6ial614xz1', parent_uid: 'scene' }, + { uid: 'txt_cm0bc5aid00002v6iu6e4a0m5', parent_uid: 'scene' }, ], right: [ - {uid: 'scene', parent_uid: null}, - {uid: 'txt_clztu14dm00042v6j71u1c9k3', parent_uid: 'scene'}, - {uid: 'txt_cm01a5cpi00012v6inbaunav1', parent_uid: 'scene'}, - {uid: 'fdr_cm0ukrqom00002v6ixqokqydk', parent_uid: 'scene'}, - {uid: 'fdr_cm0umi0e000002v6ivbkyzpwf', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, - {uid: 'txt_cm097vd9000012v6i9tsfrff2', parent_uid: 'fdr_cm0umi0e000002v6ivbkyzpwf'}, - {uid: 'txt_cm097w3zp00022v6iek5pr7id', parent_uid: 'fdr_cm0umi0e000002v6ivbkyzpwf'}, - {uid: 'txt_cm0bc6t0900022v6ij7baxq2d', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, - {uid: 'txt_cm0bc70dh00032v6im4wawi5v', parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk'}, - {uid: 'fdr_cm0vznwt800012v6ial614xz1', parent_uid: 'scene'}, - {uid: 'txt_cm0bc5aid00002v6iu6e4a0m5', parent_uid: 'scene'} + { uid: 'scene', parent_uid: null }, + { uid: 'txt_clztu14dm00042v6j71u1c9k3', parent_uid: 'scene' }, + { uid: 'txt_cm01a5cpi00012v6inbaunav1', parent_uid: 'scene' }, + { uid: 'fdr_cm0ukrqom00002v6ixqokqydk', parent_uid: 'scene' }, + { + uid: 'fdr_cm0umi0e000002v6ivbkyzpwf', + parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk', + }, + { + uid: 'txt_cm097vd9000012v6i9tsfrff2', + parent_uid: 'fdr_cm0umi0e000002v6ivbkyzpwf', + }, + { + uid: 'txt_cm097w3zp00022v6iek5pr7id', + parent_uid: 'fdr_cm0umi0e000002v6ivbkyzpwf', + }, + { + uid: 'txt_cm0bc6t0900022v6ij7baxq2d', + parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk', + }, + { + uid: 'txt_cm0bc70dh00032v6im4wawi5v', + parent_uid: 'fdr_cm0ukrqom00002v6ixqokqydk', + }, + { uid: 'fdr_cm0vznwt800012v6ial614xz1', parent_uid: 'scene' }, + { uid: 'txt_cm0bc5aid00002v6iu6e4a0m5', parent_uid: 'scene' }, ], delta: { - 2: {parent_uid: ['grp_cm0vzowcd00022v6izleecn6c', 'scene']}, - 5: {parent_uid: ['grp_cm0vzowcd00022v6izleecn6c', 'fdr_cm0umi0e000002v6ivbkyzpwf']}, - 6: {parent_uid: ['grp_cm0vzowcd00022v6izleecn6c', 'fdr_cm0umi0e000002v6ivbkyzpwf']}, + 2: { parent_uid: ['grp_cm0vzowcd00022v6izleecn6c', 'scene'] }, + 5: { + parent_uid: [ + 'grp_cm0vzowcd00022v6izleecn6c', + 'fdr_cm0umi0e000002v6ivbkyzpwf', + ], + }, + 6: { + parent_uid: [ + 'grp_cm0vzowcd00022v6izleecn6c', + 'fdr_cm0umi0e000002v6ivbkyzpwf', + ], + }, _t: 'a', - _2: [{uid: 'grp_cm0vzowcd00022v6izleecn6c', parent_uid: 'scene'}, 0, 0], + _2: [{ uid: 'grp_cm0vzowcd00022v6izleecn6c', parent_uid: 'scene' }, 0, 0], _6: ['', 3, 3], _7: ['', 4, 3], }, reverse: { - 2: [{uid: 'grp_cm0vzowcd00022v6izleecn6c', parent_uid: 'scene'}], - 3: {parent_uid: ['scene', 'grp_cm0vzowcd00022v6izleecn6c']}, - 4: {parent_uid: ['fdr_cm0umi0e000002v6ivbkyzpwf', 'grp_cm0vzowcd00022v6izleecn6c']}, - 5: {parent_uid: ['fdr_cm0umi0e000002v6ivbkyzpwf', 'grp_cm0vzowcd00022v6izleecn6c']}, + 2: [{ uid: 'grp_cm0vzowcd00022v6izleecn6c', parent_uid: 'scene' }], + 3: { parent_uid: ['scene', 'grp_cm0vzowcd00022v6izleecn6c'] }, + 4: { + parent_uid: [ + 'fdr_cm0umi0e000002v6ivbkyzpwf', + 'grp_cm0vzowcd00022v6izleecn6c', + ], + }, + 5: { + parent_uid: [ + 'fdr_cm0umi0e000002v6ivbkyzpwf', + 'grp_cm0vzowcd00022v6izleecn6c', + ], + }, _t: 'a', _5: ['', 4, 3], _6: ['', 5, 3],