Skip to content

Utility functions to apply and invert patches generated by Automerge document changes.

License

Notifications You must be signed in to change notification settings

onsetsoftware/automerge-patcher

Repository files navigation

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 automerge diff function, but it isn't ready quite yet. In the meantime, the unpatchAll 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

About

Utility functions to apply and invert patches generated by Automerge document changes.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •