This library provides the core automerge data structure and sync algorithms.
Other libraries can be built on top of this one which provide IO and
persistence.
An automerge document can be though of an immutable POJO (plain old javascript
object) which automerge tracks the history of, allowing it to be merged with
any other automerge document.
letdoc2 = automerge.init<DocType>() doc2 = automerge.merge(doc2, automerge.clone(doc1)) doc2 = automerge.change<DocType>(doc2, d=> { d.ideas.push(newautomerge.Text("which records its history")) })
// Note the `automerge.clone` call, see the "cloning" section of this readme for // more detail doc1 = automerge.merge(doc1, automerge.clone(doc2)) doc1 = automerge.change(doc1, d=> { d.ideas[0].deleteAt(13, 8) d.ideas[0].insertAt(13, "object") })
letdoc3 = automerge.merge(doc1, doc2) // doc3 is now {ideas: ["an immutable object", "which records its history"]}
You can get a representation of the result of the last change you made
to a document with getLastLocalChange and you can apply that change to
another document using applyChanges.
If you need to get just the changes which are in one document but not in another
you can use getHeads to get the heads of the document without the
changes and then getMissingDeps, passing the result of getHeads
on the document with the changes.
You can save a document to generate a compresed binary representation of
the document which can be loaded with load. If you have a document which
you have recently made changes to you can generate recent changes with saveIncremental, this will generate all the changes since you last called
saveIncremental, the changes generated can be applied to another document with
loadIncremental.
Occasionally you may wish to explicitly step to a different point in a document
history. One common reason to do this is if you need to obtain a set of changes
which take the document from one state to another in order to send those changes
to another peer (or to save them somewhere). You can use view to do this.
The sync protocol is stateful. This means that we start by creating a SyncState for each peer we are communicating with using initSyncState.
Then we generate a message to send to the peer by calling generateSyncMessage. When we receive a message from the peer we call receiveSyncMessage. Here's a simple example of a loop which just keeps two
peers in sync.
The only time conflicts occur in automerge documents is in concurrent
assignments to the same key in an object. In this case automerge
deterministically chooses an arbitrary value to present to the application but
you can examine the conflicts using getConflicts.
By default automerge will generate a random actor ID for you, but most methods
for creating a document allow you to set the actor ID. You can get the actor ID
associated with the document by calling getActorId. Actor IDs must not
be used in concurrent threads of executiong - all changes by a given actor ID
are expected to be sequential.
Sometimes you want to respond to changes made to an automerge document. In this
case you can use the PatchCallback type to receive notifications when
changes have been made.
There have been several additions and changes to the automerge API which
are not backwards compatible. This API will become the API of the next major
release of automerge. New applications should use the next module.
Automerge
This library provides the core automerge data structure and sync algorithms. Other libraries can be built on top of this one which provide IO and persistence.
An automerge document can be though of an immutable POJO (plain old javascript object) which
automerge
tracks the history of, allowing it to be merged with any other automerge document.Creating and modifying a document
You can create a document with init or from and then make changes to it with change, you can merge two documents with merge.
Applying changes from another document
You can get a representation of the result of the last change you made to a document with getLastLocalChange and you can apply that change to another document using applyChanges.
If you need to get just the changes which are in one document but not in another you can use getHeads to get the heads of the document without the changes and then getMissingDeps, passing the result of getHeads on the document with the changes.
Saving and loading documents
You can save a document to generate a compresed binary representation of the document which can be loaded with load. If you have a document which you have recently made changes to you can generate recent changes with saveIncremental, this will generate all the changes since you last called
saveIncremental
, the changes generated can be applied to another document with loadIncremental.Viewing different versions of a document
Occasionally you may wish to explicitly step to a different point in a document history. One common reason to do this is if you need to obtain a set of changes which take the document from one state to another in order to send those changes to another peer (or to save them somewhere). You can use view to do this.
If you have a view of a document which you want to make changes to you can clone the viewed document.
Syncing
The sync protocol is stateful. This means that we start by creating a SyncState for each peer we are communicating with using initSyncState. Then we generate a message to send to the peer by calling generateSyncMessage. When we receive a message from the peer we call receiveSyncMessage. Here's a simple example of a loop which just keeps two peers in sync.
Conflicts
The only time conflicts occur in automerge documents is in concurrent assignments to the same key in an object. In this case automerge deterministically chooses an arbitrary value to present to the application but you can examine the conflicts using getConflicts.
Actor IDs
By default automerge will generate a random actor ID for you, but most methods for creating a document allow you to set the actor ID. You can get the actor ID associated with the document by calling getActorId. Actor IDs must not be used in concurrent threads of executiong - all changes by a given actor ID are expected to be sequential.
Listening to patches
Sometimes you want to respond to changes made to an automerge document. In this case you can use the PatchCallback type to receive notifications when changes have been made.
Cloning
Currently you cannot make mutating changes (i.e. call change) to a document which you have two pointers to. For example, in this code:
doc1
anddoc2
are both pointers to the same state. Any attempt to call mutating methods ondoc1
will now result in an error likeIf you encounter this you need to clone the original document, the above sample would work as:
The next module
There have been several additions and changes to the automerge API which are not backwards compatible. This API will become the API of the next major release of automerge. New applications should use the next module.