Description
This is my idea of an API that uses mutable state for compatibility with frameworks such as Vue.js that use mutable state. @ept suggested I write a brief proposal of how I think a mutable state API could work.
Mutable State
One idea would be to use a similar .change
as for the immutable API but with no new document being returned. No mutable document needs to be passed into the callback since the document itself is mutable. If, for some reason, this is necessary because of implementation details that would also be ok. I like the callback idea because it delineates where a change starts and where it ends.
const doc = Automerge.init()
Automerge.change(doc, () => {
doc.foo = 4
})
An even more extreme API might not have a .change
at all with change tracking happening entirely through Proxies observing changes. Again, as I'm not at all familiar with the internals of Automerge, I don't know if this is feasible.
const doc = Automerge.init()
doc.foo = 4
Vue integration
A mutable Automerge state could be made reactive using Vue 3's reactive
or by passing it to a Vue 2 component's data
property. It's a little easier with Vue 3 than with Vue 2 due to how the new Vue's reactivity system is decoupled from the component system. Because Vue 2 doesn't use Proxies but rather getters and setters on objects, a state object present on the component will be the same as the original Automerge state. Vue 2 making the given object reactive might break Automerge because it adds a (hidden) property and replaces all original properties with getters/setters.
Vue 3 creates reactive objects with reactive
and returns the object wrapped in a proxy. An integration with Vue 3 could work like this:
import { reactive } from 'vue'
const doc = Automerge.init()
const reactiveDoc = reactive(doc)
Automerge.change(reactiveDoc, () => {
reactiveDoc.foo = 4
})
//reactiveDoc used and further modified by a Vue component
Automerge might not like that a proxy has been wrapped around the original state. Maybe the mutable state frontend could be built to be ok with this. I'm not sure how initializing a vue-reactive Automerge state synchronized from a server would work.
Activity