Hacker News new | past | comments | ask | show | jobs | submit login

When I learned one thing about collaborative apps, it's that there is no automerge that works for all use-cases.

Couchdb does it the right way, it simply keeps all versions and lets the application logic decide which is the "one true state".

Automerge is very similar.

If there are conflicts, it returns a _conflicts property on the object so you can retrieve the other conflicting alternatives so the application logic can write another change if it wants to use a different alternative than the one that was automatically chosen.

I'm confused. What's the point of `_conflicts` property if conflicts are automatically merged?

The linked project README, and even the CRDT Wikipedia page, seem to claim that conflicts are avoided, whereas, at least in my mind, these are more like strategies to automatically privilege one version in the event of a conflict.

From my reading of the docs, Automerge will arbitrarily pick a "winning" document in the case of a conflict, but guarantees that the same winner will be chosen if the merge were to occur, for instance, in a different order:

    // Pretend doc1 and doc2 are already Automerge objects
    let doc1 = { x: 1 }
    let doc2 = { x: 2 }

    // x will be either 1 or 2 (arbitrarily chosen), but
    // res1 will always == res2 regardless of choice
    let res1 = Automerge.merge(doc1, doc2)
    let res2 = Automerge.merge(doc2, doc1)
    res1 == res2 // true
However, there may be cases where you want to manually resolve conflicts, and if that is the case, the `_conflicts` property is there so that you can undo whatever merge occurred automatically and set the "winner" yourself.

The more interesting case is when you have the following:

doc1 = { 'a': {'b': {'c': ... }}}

doc2 = {}

So one has been deleted entirely and the other has modified some attribute deep down inside of it.

If you always have to check and resolve conflicts yourself, then it's not really useful.

If it's "arbitrarily chosen", but the result is always the same regardless of order, what is the algorithm that decides?

There's different ways you could do it, like calculating some hash of the value and picking the one with the greater value. If the hash function is good, then you get an "arbitrary" result that would still be consistent regardless of order.

Take a look at operational transforms as another great solution to this sort of problem. Many collaborative editors rely on them (Google docs, etc)


Keep in mind that OT relies on a centralized server where as CRDTs do not.

OT does not depend on a central server. The particular implementation in Google Docs does. Take a look at the GOTO algorithm and TP2 property.

Some users also "select all" + "paste"

Well, it depends on what you define as 'works'. As long as you have an accurate clock (which most devices have nowadays), it works many times to take the latest state. Combine that with merging on an attribute level and you will have something most humans will accept as 'works'.

If you want to build an editor you probably have to ask yourself what your 'attributes' are, but probably the individual letters.

Last year I built something fairly similar to automerge but with a focus on offline clients. I use it to sync my app's data from different clients to an WebDAV server. As some Clients are sometimes offline when changes occur the, resolving conflicts can occur easily but resolving them in an expected way isn't that hard if you do the time trick.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact