How to set intial value from the server

Hello everyone! I’m a new user to Yjs, sorry if this is a stupid question.

I’ve been using slate-yjs binding to try adding collaboration into my slateJS project. From the example, it has snippet similar to this:

When I do this, it is setting the document in the y-websocket-server basic server to an empty initial value (when the doc is first initialized) that I set in initialValueEmpty variable in the snippet.

What I want to do is to set initial value on the server to a proper initial value (the one stored in our database). I can simply do this on the front end by fetching the initial data from our database, then start the websocket connection and sync it with server with the initial data that I fetched earlier. However, the comment said this is something very hacky to do…

I’ve spent a few hours reading and trying to understand y-websocket-server. However, I can’t seem to understand which part of the code I should modify to be able to provide this initial value from the server instead of the frontend.

Any help or resources to read would be very helpful! Thank you @dmonad for this awesome library!

1 Like

After reading a few community question,

I’ve found that I can set the initial value inside the getYDoc function.

I’ll definitely try to modify this and see if it works.

An update here,

I haven’t made any progress because I’m stuck converting SlateJS JSON state document into a YDoc that can be synced with the clients. My initial thoughts is to use Y.encodeStateAsUpdate, then apply the updates to the YDoc in the server. But I have no idea how to convert the JSON state into a YDoc.

Can anyone can point me to the right direction on how to convert a JSON structure into a YDoc?

Thank you!

hi, @albert

I used this tool to sync the new changed records of fresh json to yDoc of the server:

json0-ot-diff

step 1: Compare the yDoc.toJSON() and fresh json, get the ops (operation list)

step 2: Refer to the yjs api to make your li,ld,oi,od (these are the basic functors of json0-ot-diff)

step 3: Patch the ops to yDoc

1 Like

Hi @jarone thank you for your response, I really appreciate it!

I think I get what you’re saying, but I think I’m still not trying to solve the problem of syncing with the yDoc on the server.

I must be missing something from the yjs documentation on converting a JSON struct into a YDoc document. I feel like it should be as simple as inserting text into YDoc. I just don’t know how to do that yet on the server.

So, to be more specific:

Let’s say I have the following JSON as the initial value:

{
  type: "p",
  children: [
    { text: "Hello World" }
  ]
}

Which is just a JSON representation of “Hello World” text in SlateJS.

How do I set a YDoc initial state to “Hello World” (preferably in the server) ? We currently have slateJS binding, but I don’t know what actions I should take in order to add SlateJS’ “Hello World” text representation into new YDoc that I generated on the server.

Thank you so much!

hi, @albert

Hope this helps you:

const Y = require('yjs');

const init = {
  type: "p",
  children: [
    { text: "Hello World" }
  ]
}

const ydoc = new Y.Doc();
const children = ydoc.getArray('children');
const child = new Y.Map();
const childText = new Y.Text();

ydoc.getText('type').insert(0, 'p');
childText.insert(0, 'Hello World');
child.set('text', childText)
children.push([child]);

console.log('result:', ydoc.toJSON());
1 Like

hi,@albert

I found this topic, hope it helpes you.

1 Like

Hi @albert,

This discussion helped me figure it out:

  1. install slate-yjs in your y-websocket-server project.
  2. in utils, add import const { toSharedType } = require('slate-yjs')
  3. After docs.set(docname, doc), add toSharedType(doc.getArray('doc'), [{ type: 'p', children: [{ text: 'Hello World' }] }])
3 Likes