How to initialize value or use existing Yjs doc stored in server
See original GitHub issueFirst off, this is an amazing project and I’m incredibly impressed with how wide a range of reactive bindings and library integrations you were able to provide. Thank you for your work on this!
If it is important to the solution, I am using the Vue3 bindings.
The problem I’m running into is being able to initialize a document using a value stored in the server. When i try to provide a document with initial values to syncedStore
like so:
const doc = syncedStore({
items: ['a', 'b', 'c'],
})
I get the error: Root Array initializer must always be empty array
.
I can technically initialize everything to an empty state and then add the data, but if there is a race condition or users have slow connections/offline mode this will cause duplication of data when they re-sync. Furthermore I want the flow of my document to be as such:
New document creation:
- User navigates to
/list/:listID
- If database has a list by that ID load and initialize syncedStore to existing list.
- If no list exists by that ID then initialize to empty list.
- Any users viewing the same list can make edits over WebRTC provider
- Document is autosaved to database periodically by the last user to make an update
- All users eventually leave but may come back periodically to make edits, sometimes collaboratively
In your opinion what is the best way to allow for a document to be persisted and picked up again allowing for initialization of a template document or an existing databased stored document?
Any help greatly appreciated!!!
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (3 by maintainers)
Top GitHub Comments
Hi @milesingrams !
Great question, and I had to wrap my head around this topic as well as you can see in that thread.
The gist is this:
You should initialize the document / store, right after you consider the object “created”. There probably is a moment where a user presses “Create List”, where you want to create a new
listID
, this is the moment where you can also initialize the document.What does this mean in your scenario? I think it should be split into two different scenarios: (A) viewing / editing an existing list (B) creating a new list. This would be what I recommend
A: Viewing / editing an existing list
(And your previous points are still valid after
2a
:B: Creating a new List
store.items.push('A')
) (this can happen on client or server)/list:listID
Does this make sense? The reason you can’t simply “create a store with initial values”, is because in a distributed, offline-first environment, you can’t know for sure whether a store “has been initialized or not”, because you don’t know yet whether you have received all updates from peers that exist “in the universe”. Maybe another peer has initialized the document already? The only way to do this is when a central authority (server or database) signals to you that the id doesn’t exist yet (or alternatively, if you rely on UUIDs you can do this client side as well), and you’re sure you’re the first one to write to the document by that id.
Happy to help! Keep me posted of your progress, great to learn how people are using the library