Simplify patch

This commit is contained in:
jos 2016-09-18 15:40:40 +02:00
parent ad36723618
commit 0a857aaad6
2 changed files with 36 additions and 4 deletions

View File

@ -190,9 +190,12 @@ export function patchData (data, patch) {
} }
}) })
// TODO: Simplify revert when possible:
// when a previous action takes place on the same path, remove the first
return { return {
data: updatedData, data: updatedData,
revert, revert: simplifyPatch(revert),
error: null error: null
} }
} }
@ -276,6 +279,38 @@ export function remove (data, path) {
} }
} }
/**
* Remove redundant actions from a JSONPatch array.
* Actions are redundant when they are followed by an action
* acting on the same path.
* @param {JSONPatch} patch
* @return {Array}
*/
export function simplifyPatch(patch) {
const simplifiedPatch = []
const paths = {}
// loop over the patch from last to first
for (var i = patch.length - 1; i >= 0; i--) {
const action = patch[i]
if (action.op === 'test') {
// ignore test actions
simplifiedPatch.unshift(action)
}
else {
// test whether this path was already used
// if not, add this action to the simplified patch
if (paths[action.path] === undefined) {
paths[action.path] = true
simplifiedPatch.unshift(action)
}
}
}
return simplifiedPatch
}
/** /**
* @param {JSONData} data * @param {JSONData} data
* @param {string} path * @param {string} path

View File

@ -525,11 +525,8 @@ test('jsonpatch move and replace', t => {
t.deepEqual(patchedJson2, json) t.deepEqual(patchedJson2, json)
t.deepEqual(revert2, [ t.deepEqual(revert2, [
{op: 'remove', path: '/arr'},
{op: 'move', from: '/obj', path: '/arr'} {op: 'move', from: '/obj', path: '/arr'}
]) ])
// TODO: would be nice when dataPatch could simplify revert2: see that the 'remove' action is redundant
}) })
test('jsonpatch test (ok)', t => { test('jsonpatch test (ok)', t => {