to be honest, I am new, too. Here is what I’ve found so far, maybe it helps a little bit:
There is a y-leveldb package (which @canadaduane funded, if I’m correct - so thank you @canadaduane ). It is an adapter for the LevelDB databse.
As far as the docs state it the adapter uses level. Level offers the ability to switch the storage medium. Their GitHub Orga has an awesome repo, where you can find some storage adapter packages for level:
You can implement an bidirectional communication between client and server via websockets. Next to the y-websockets module implementation for clients you can find an example server implementation which offers the possibility with persisting data with y-leveldb.
This might be a good starting point for further investigation.
The following answer might help by examining the right data format to store the documents:
It would only work alongside other languages or tech stacks.
You could host a nodejs server besides your current server application and only use it for realtime awareness data (like cursor positions) or expand it to store also the yjs documents. Everything else you can hold in you current server application.
This might not be ideal, but good for a first prototype or first fast integration.
As far as I can spot it, @dmonad works on a Rust implementation of YATA called Yrs.
But this port to Rust is quite new, so might now be stable right now (also no GitHub releases)
Alternatively, you could implement your own update logic by simply persisting each update message. You don’t need to care about the content of the update message. You just need to ensure that every client gets every update message (the order doesn’t matter, it also doesn’t matter if you apply updates multiple times).
Of course, this is not always ideal. I’m working on shipping “differential updates” to Yrs (an unfinished Rust port of Yjs). The idea is to port Yrs to many different languages like Java using language bindings. With differential updates, you would be able to sync clients using conventional SyncStep1/2 messages which are more efficient.
I have a follow up question. I looked at the indexeddb storage adapter. It seems to save every updates.
Initially I thought the storage would save a document’s state, not update.
If we are saving updates, isn’t recovering the current document from the updates very slow? Imagine I’m building an editor, the first time I open the editor, I need to pull all updates and reconstruct the document from scratch?
Incremental updates are written to the database to improve performance. It would be infeasible to compute and save the complete document after every keystroke. After 100 or so updates, y-indexeddb will merge the updates to a single entry. This happens asynchronously after the keystroke has been rendered.