@onsetsoftware/automerge-patcher
v0.14.0
Published
Utility functions to apply and invert patches generated by Automerge document changes.
Downloads
1,028
Readme
Automerge Patcher
Utility functions to apply and invert patches generated by Automerge document changes.
Installation
npm install @onsetsoftware/automerge-patcher
Usage
patch(doc: Doc, patch: Patch): Patch
Used to take a single automerge patch and apply it to a document. It can also be used to apply an Automerge patch to a plain javascript object with the same shape as the relevant document
import { patch } from "@onsetsoftware/automerge-patcher";
import { from, change, type PutPatch } from "@automerge/automerge";
const doc = from({ foo: "bar" });
const toApply = {
action: "put",
path: ["foo"],
value: "baz",
};
const updated = change(doc, (d) => {
patch(d, toApply);
});
console.log(updated); // => { foo: 'baz' }
unpatch(beforeDoc: Doc, patch: Patch): Patch
Provides the inverse of a patch, given the initial document (before the change) on which the patch applies.
import { unpatch } from "@onsetsoftware/automerge-patcher";
import { from } from "@automerge/automerge";
const doc = from({ foo: "bar" });
const patch = {
action: "put",
path: ["foo"],
value: "baz",
};
const inverse = unpatch(doc, patch);
console.log(inverse); // => { action: 'put', path: ["foo"], value: "bar"}
unpatchAll(beforeDoc: Doc, patches: Patch[]): Patch[]
unpatchAll
can be used to reverse an array of patches relative to the initial (before changes) document which produced them.
It works by progressively updating a copy of the document after applying each patch, then reversing the next patch based on the new state.
[!NOTE]
The best (and fastest) way to get the reverse of a change is to use the automergediff
function, but it isn't ready quite yet. In the meantime, theunpatchAll
function is provided to acheive this.
import { patch, unpatchAll } from "@onsetsoftware/automerge-patcher";
import { from, change, type Patch } from "@automerge/automerge";
const doc = from({ foo: "bar" });
let reverse: Patch[];
const doc2 = change(
doc,
{
patchCallback: (patches, { before }) => {
// capture reverse of the patches for undo
reverse = unpatchAll(before, patches);
},
},
(doc) => {
doc.foo = "baz";
},
);
console.log(reverse); // [{action: 'put', path: ['foo'], value: 'bar'}]
console.log(doc2.foo); // baz
const doc3 = change(doc2, (doc) => {
// apply the patch to revert the change
reverse.forEach((patch) => {
applyPatch(doc, patch);
});
});
console.log(doc3.foo); // bar