Skip to content

Instantly share code, notes, and snippets.

@pvh
Created August 6, 2024 20:47
Show Gist options
  • Save pvh/88eddae4c09129528c27939626211e0b to your computer and use it in GitHub Desktop.
Save pvh/88eddae4c09129528c27939626211e0b to your computer and use it in GitHub Desktop.
A POC of a JS patch applier for Automerge.
const putPatch = (obj: any, p: A.PutPatch) => {
const { path, value } = p
const tail = path.pop()
const local = path.reduce((acc, next) => acc[next], obj)
local[tail] = value
return obj
}
const splicePatch = (obj: any, p: A.SpliceTextPatch) => {
const { path, value } = p
const pos = path.pop() as number
const tail = path.pop()
const local = path.reduce((acc, next) => acc[next], obj)
const prefix = local[tail].substring(0, pos)
const suffix = local[tail].slice(pos)
local[tail] = prefix + value + suffix
return obj
}
const delPatch = (obj: any, p: A.DelPatch) => {
const { path, length } = p
const tail = path.pop()
const local = path.reduce((acc, next) => acc[next], obj)
// TODO: support length
delete local[tail]
return obj
}
const insertPatch = (obj: any, p: A.InsertPatch) => {
const { path, values } = p
const pos = path.pop()
const tail = path.pop()
const local = path.reduce((acc, next) => acc[next], obj)
local[tail].splice(pos, 0, ...values)
return obj
}
const applyPatches = (obj: any, ps: A.Patch[]) => {
return ps.reduce((acc, p) => applyPatch(acc, p), obj)
}
const applyPatch = (obj: any, p: A.Patch) => {
console.log('ptch', obj, p)
switch (p.action) {
case "put":
return putPatch(obj, p);
case "splice":
return splicePatch(obj, p);
case "del":
return delPatch(obj, p);
case "insert":
return insertPatch(obj, p);
case "inc":
case "mark":
case "unmark":
case "conflict":
throw new Error(`Patch action not implemented.\n${JSON.stringify(p, undefined, 2)}`)
}
}
const pojo = {}
handle.on("change", ({ handle, doc, patches }) => {
applyPatches(pojo, patches)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment