question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to initialize value or use existing Yjs doc stored in server

See original GitHub issue

First 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:

  1. User navigates to /list/:listID
  2. If database has a list by that ID load and initialize syncedStore to existing list.
  3. If no list exists by that ID then initialize to empty list.
  4. Any users viewing the same list can make edits over WebRTC provider
  5. Document is autosaved to database periodically by the last user to make an update
  6. 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:closed
  • Created 2 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
YousefEDcommented, Nov 26, 2021

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

  1. User navigates to /list/:listID 2a. If database has a list by that ID load and initialize syncedStore to existing list. 2b. If database doesn’t have a list by that ID, show a 404

(And your previous points are still valid after 2a:

  • 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 )

B: Creating a new List

  1. User clicks “Create new List”
  2. Server or client generates a new ID
  3. Initialise syncedStore to that ID
  4. Write the initial values (e.g.: store.items.push('A')) (this can happen on client or server)
  5. Redirect (or change URL dynamically) to /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.

0reactions
YousefEDcommented, Dec 6, 2021

Happy to help! Keep me posted of your progress, great to learn how people are using the library

Read more comments on GitHub >

github_iconTop Results From Across the Web

Initial offline value of a shared document - Yjs Community
New users can create a new notebook by specifying a title. As soon as the notebook is created, it should be initialized with...
Read more >
Yjs/community - Gitter
The auth protocol is an attempt to standardize how to tell the y-websocket client that it has no permission to view the source...
Read more >
Building a Collaborative Editor Using Quill and Yjs - Velotio
To keep it simple, we'll set up a client and server both in the same code base. Initialize a project with npm init...
Read more >
How to initialize value of CodeMirror binding to yjs?
Another note: There is nothing like a default value in Yjs. Initially, the Yjs document is empty until it synced with the server....
Read more >
Library issue: yJs synchronisation and client (state) being ...
As detailed elsewhere, I am running into issues syncing a slider between notebooks. While my Stackblitz example demonstrates how a shared slider using...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found