Is it possible to using http to do some initial job

I am using the yjs to edit the online tex file(the provider is y-websocket), now I am facing a problem that some tex file was created from template. when I create the user collarboarate project, I just want to do some initial job. Initial the
project files into yjs persistant storage by template files. then the user will see the template content when open the collarboarate files the first time. My backend was using rust, is there any way to push the initial content into yjs storage? Now I am using y-websocket as the provider.

If I understand what you’re asking, you want the Yjs document to be populated with some initial content before the client connects to it?

One approach would be for your client to first send a fetch request to the server indicating that it would like to connect to a new document. The server would then create a new document, fill it with the template, and save it to persistent storage. When the client then connected to the same document, the server would load it from persistent storage and send it down to the client.

If you do not have persistent storage set up, you will need to do that first for this approach to work.

your understand are correct. But the issue is that I did not know how to save the template code into y-websocket storage, the y-websocet using leveldb, there is no api. My program language using rust that could not use the yjs nodejs client. the legacy way to initial the document when the user first time open the doucment and read the fisrt time iniial flag to insert the initial content after connect to y-websocket, the work chain are so long and complex and easy to facing error. now I am added a nodejs client in the server side and invoke http to initial it the fisrt time. This is the http code:


const express = require('express')
const bodyParser = require('body-parser')
const Y = require('yjs')
const { WebsocketProvider } = require('y-websocket')
const app = express()
app.use(bodyParser.json())

app.post('/y-websocket/file/initial', (req, res) => {
  const docId = req.body.doc_id
  const projectId = req.body.project_id
  const initContext = req.body.file_content
  console.log(docId, projectId, initContext)
  initTpl(docId, projectId, initContext)
  res.send('success')
})

app.listen(3000, () => {
  console.log('started')
})

const initTpl = (docId, projectId, initContext) => {
  let docOpt = {
    guid: docId,
    collectionid: projectId
  }
  const ydoc = new Y.Doc(docOpt)
  const ytext = ydoc.getText(docId)
  const wsProvider = new WebsocketProvider('ws://localhost:1234', docId, ydoc, { WebSocketPolyfill: require('ws') })
  wsProvider.on('status', (event) => {
    if (event.status === 'connected') {
      if (wsProvider.ws) {
        if (initContext && initContext.length > 0) {
          console.log('write: {}', initContext)
          ytext.insert(0, initContext)
        }
      }
    }
  })
}

invoke the api on the server side to initial, and do not need to change any code with client.

Here’s how you use templates:

  1. Your client connects normally

  2. In your server, you check if you are fetching a new doc that uses a template

  3. You have a default doc encoded as JSON or binary

  4. You load that doc and turn into an update

  5. You apply it to the doc

  6. Now you can proceed normally with the doc and send it back to the client

1 Like

I would like to clarify one thing: Is it correct that every time when I want to create a shared type field with initial data, I have to open websocket to yjs server? Wouldn’t it be better to open socket when server app is initialized and do things with existing ws provider? Or this is bad approach?

@seleckis The suggestion from @TeemuKoivisto was to instantiate the template server-side I believe. The client connects normally (i.e. whenever WebsocketProvider gets instantiated).

That is why I’m asking. I have similar situation: User creates a record with content provided, I need to push that data not only to my regular db, but also create an yjs data right on the server.