Starcounter-Jack / JSON-Patch

Lean and mean Javascript implementation of the JSON-Patch standard (RFC 6902). Update JSON documents using delta patches.
MIT License
1.79k stars 215 forks source link

Way to "undo" a patch? #242

Open rszemplinski opened 4 years ago

rszemplinski commented 4 years ago

Hi,

I was just wondering if there was a way to "undo" a patch I applied? I noticed the invertible function but don't understand what the operation test is actually supposed to do.

jaylattice commented 4 years ago

@rszemplinski Hi Ryan. I played around with the observer code and it looks like you might be able to extract and apply test ops from the document observer. From the docs:

var document = { firstName: "Joachim", lastName: "Wester", contactDetails: { phoneNumbers: [ { number:"555-123" }] } };
var observer = jsonpatch.observe(document);
document.firstName = "Albert";
document.contactDetails.phoneNumbers[0].number = "123";
document.contactDetails.phoneNumbers.push({ number:"456" });
var patch = jsonpatch.generate(observer, true);
// patch  == [
//   { op: "test", path: "/firstName", value: "Joachim"},
//   { op: "replace", path: "/firstName", value: "Albert"},
//   { op: "test", path: "/contactDetails/phoneNumbers/0/number", value: "555-123" },
//   { op: "replace", path: "/contactDetails/phoneNumbers/0/number", value: "123" },
//   { op: "add", path: "/contactDetails/phoneNumbers/1", value: {number:"456"}}
// ];

That said, it looks like support for reversing array mutations is not there. Another solution would be to apply each operation individually, with mutable set to false:

// might be slightly different syntax
jsonpatch.applyOperation(document, patch, jsonpatch.validator, false).newDocument

This way, you will be able to make a programmatic decision to either keep the patch, or discard the patch and revert to the old document (since it wasn't mutated). Hope that helps!