A replicated key-value store that magically synchronizes with peers in the background.
Automerge is a CRDT that ...
The original Automerge API leaves a number of difficult problems to be solved in userland: Storage, network communication, and synchronization are all left as an exercise for the developer.
The repository API is a higher-level, batteries-included, extensible interface to Automerge. The underlying storage and networking technologies are pluggable. Other features — access control, authorization, authentication, etc. can be added using middleware.
- automerge/indexeddb
- automerge/sqlite
- automerge/postgres
- automerge/mongodb
- automerge/file-system
- automerge/websocket
- automerge/webrtc
- automerge/broadcast-channel
- automerge/access-control
- automerge/migrations
- local-first-web/automerge-auth
const storage = new StorageThing()
const network = new NetworkThing()
const idGenerator = uuid
const id = uuid()
const repo = AutomergeRepo.createRepo({ id, storage, network, idGenerator })
const [id, wrappedDoc] = AutomergeRepo.create(repo) // [id, {}]
const wrappedDoc = AutomergeRepo.load(repo, id) // a wrappedDoc is kind of like an automerge document - contains the JSON, has some additional features
// things a wrapped doc can do
const id = wrappedDoc.id // ??? maybe not because what if the same document can have different ids
const jsonDoc = wrappedDoc.toJson()
AutomergeRepo.unload(wrappedDoc)
const myDocumentV2 = AutomergeRepo.change(wrappedDoc, state => (state.firstName = 'Herb'))
const changeListener = doc => {}
wrappedDoc.addListener('change', changeListener)
// OR
const patchListener = patch => {}
const handle = wrappedDoc.addListener('patch', patch => {})
// to stop listening
wrappedDoc.removeListener('change', changeListener)
wrappedDoc.removeListener('patch', patchListener)
storage.set(documentId, bytes)
storage.appendChange(documentId, bytes)
storage.load(documentId)
network.send(message)
network.send(message, clientId)
network.addListener('message', (message, clientId) => {
// ...
})