-
Notifications
You must be signed in to change notification settings - Fork 467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mutable state frontend API proposal #443
Comments
I would look at zustand and valtio which have similar apis.
For Vue (or React) integration, it might be better to keep the reactive object and auto merge state apart even though it’s redundant. Then create a bridge that syncs changes between the two. Example is valtio-yjs. On that subject, as an option in the bridge should be a way to mark some fields excluded or included from syncing.
const doc = Automerge.init()
doc.foo = 4 One drawback of this mutable approach is losing the ability to group mutations together semantically e.g. with a commit message. There needs to be a way to batch things together within an enclosure or a "transaction"; this would be good for undo redo operations too. |
Yes, this is the kind of API I was thinking of. Maybe transaction features could be brought into this by marking the start and end of a transaction explicitly. Something like this (just a very rough idea): const doc = Automerge.init()
doc.foo = 4 //implicit change
//explicit change
Automerge.startChange(doc)
doc.bar = 3
Automerge.commit(doc, "message") |
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.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.Vue integration
A mutable Automerge state could be made reactive using Vue 3's
reactive
or by passing it to a Vue 2 component'sdata
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: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.
The text was updated successfully, but these errors were encountered: