Palindrom / JSONPatcherProxy

ES6 proxy powered JSON Object observer that emits JSON patches when changes occur to your object tree.
94 stars 14 forks source link

Make sure collected patches are not mutated. #46

Closed eriksunsol closed 5 years ago

eriksunsol commented 5 years ago

Extending the example in README.md like this:

var myObj = { firstName:"Joachim", lastName:"Wester", contactDetails: { phoneNumbers: [ { number:"555-123" }] } };
var jsonPatcherProxy = new JSONPatcherProxy( myObj );
var observedObject = jsonPatcherProxy.observe(true);
observedObject.firstName = "Albert";
observedObject.contactDetails.phoneNumbers[0].number = "123";
observedObject.contactDetails.phoneNumbers.push({number:"456"});
observedObject.contactDetails.phoneNumbers[1].number = "789";
var patches = jsonPatcherProxy.generate();

results in the following patch:

[
  {"op":"replace","path":"/firstName","value":"Albert"},
  {"op":"replace","path":"/contactDetails/phoneNumbers/0/number","value":"123"},
  {"op":"add","path":"/contactDetails/phoneNumbers/1","value":{"number":"789"}}
  {"op":"replace","path":"/contactDetails/phoneNumbers/1/number","value":"789"},
]

Note that the last change mutates the already collected patch corresponding to the push operation. The proposed change prevents this by deep-cloning the value placed in the patch so that the result is as expected instead:

[
  {"op":"replace","path":"/firstName","value":"Albert"},
  {"op":"replace","path":"/contactDetails/phoneNumbers/0/number","value":"123"},
  {"op":"add","path":"/contactDetails/phoneNumbers/1","value":{"number":"456"}}
  {"op":"replace","path":"/contactDetails/phoneNumbers/1/number","value":"789"},
]
warpech commented 5 years ago

I am working on adding a test

warpech commented 5 years ago

Thanks for your contribution. This PR continues in https://github.com/Palindrom/JSONPatcherProxy/pull/48