TypeCellOS / BlockNote

A React Rich Text Editor that's block-based (Notion style) and extensible. Built on top of Prosemirror and Tiptap.

Home Page:https://www.blocknotejs.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: Retrieving blocks as JSON from collaboration provider

odufuwa-segun opened this issue · comments

Hi, I am integrating BlockNote with y-socketio as a collaboration provider, I want to implement two things:

  1. Initializing the blocks from the server when the document is first loaded
  2. Save the blocks as JSON into database when an update is pushed.

Here's my code y-socketio implementation on the server side:

`
export const initializeYJS = (io) => {
const ysocketio = new YSocketIO(io, {
authenticate: (handshake) => {
// console.log({handshake})
return true;
}
})

ysocketio.on('document-loaded', (doc: Document) => {
    const fragment = doc.getXmlFragment("document-store")
    // console.log(`The document ${doc.name} was loaded`, {rest, fragment})
})
ysocketio.on('document-update', (doc: Document, update: Uint8Array) => {
    const fragment = doc.getXmlFragment("document-store")

    const blockNoteDoc = fragment.doc
    // console.log(`The document ${doc.name} is updated; with params:`, {blockNoteDoc})
  
})

// ysocketio.on('awareness-update', (doc: Document, update: Uint8Array) => console.log(The awareness of the document ${doc.name} is updated))
// ysocketio.on('document-destroy', async (doc: Document) => console.log(The document ${doc.name} is being destroyed))
// ysocketio.on('all-document-connections-closed', async (doc: Document) => console.log(All clients of document ${doc.name} are disconected))

// Execute initialize method
ysocketio.initialize()

}`

The challenge I'm having is that on the client side, the collaboration is initialized with fragment: yDoc.getXmlFragment("document-store") however when I retrieve the document from ysocketio in the document-update event, I get it as XML looking like

<blockgroup><blockcontainer backgroundColor="default" id="initialBlockId" textColor="default"><paragraph textAlignment="left">Doc researching, are you saving now. which is very good bruh</paragraph></blockcontainer><blockcontainer backgroundColor="default" id="3043d71e-04e7-4dc6-9fb0-e5e291db4bc9" textColor="default"><paragraph textAlignment="left"></paragraph></blockcontainer><blockcontainer backgroundColor="default" id="dafb6570-c783-4547-a53b-05a9c661addd" textColor="default"><paragraph textAlignment="left">This is a bruhs shadn and is good </paragraph></blockcontainer><blockcontainer backgroundColor="default" id="77809ace-73d0-4675-b0cb-df7b8c5e8d3c" textColor="default"><paragraph textAlignment="left">this is a collab</paragraph></blockcontainer><blockcontainer backgroundColor="default" id="7473c404-edfb-4bb9-8e0a-b3932786b2fe" textColor="default"><paragraph textAlignment="left">this is a collab and i find it amazing that it works </paragraph></blockcontainer><blockcontainer backgroundColor="default" id="2ed3ff42-0f42-46cf-b736-6f8ab9a47ec9" textColor="default"><paragraph textAlignment="left">Oh my word, look at that. and I find it amazing to be amazed and cool ad</paragraph></blockcontainer><blockcontainer backgroundColor="default" id="f4e227c6-60ae-4561-b9e3-c6d4de7538ea" textColor="default"><paragraph textAlignment="left"></paragraph></blockcontainer><blockcontainer backgroundColor="default" id="d3ee091f-5098-422b-995a-9ba151df2f61" textColor="default"><paragraph textAlignment="left">Oh, that's interstint are you back now? I typed inside. should be cool. Another update</paragraph></blockcontainer><blockcontainer backgroundColor="default" id="815f91cd-a450-44a1-bba1-f9354b11abb5" textColor="default"><paragraph textAlignment="left"></paragraph></blockcontainer><blockcontainer backgroundColor="default" id="49892972-d02a-4787-acf5-c30b477066d1" textColor="default"><paragraph textAlignment="left">Oh my I am just typing here ooo; good bruh</paragraph></blockcontainer><blockcontainer backgroundColor="default" id="3794c2ad-6f1e-495c-b20c-7ba9114de149" textColor="default"><paragraph textAlignment="left"></paragraph></blockcontainer><blockcontainer backgroundColor="default" id="eeb634c0-1165-45aa-bc1a-3a3bbc853634" textColor="default"><paragraph textAlignment="left"></paragraph></blockcontainer><blockcontainer backgroundColor="default" id="68521c9f-aba5-4903-9342-3bcc75bf4b58" textColor="default"><paragraph textAlignment="left"></paragraph></blockcontainer><blockcontainer backgroundColor="default" id="e0f6bcad-7f6e-40f2-a159-57294cc570be" textColor="default"><paragraph textAlignment="left">And I love this man</paragraph></blockcontainer><blockcontainer backgroundColor="default" id="8b8685b4-b8c9-441e-a565-17be2957d6e8" textColor="default"><paragraph textAlignment="left"></paragraph></blockcontainer></blockgroup>

I initially was storing the blocks as JSON in my database, getting it from onChange in the editor, but this was in efficient as every client is triggering that event but as I'm not able to get the JSON data from the server, I'm considering switching to XML instead and save the XML data.

My questions:

  1. Does anyone know how to convert the XML data provided into the JSON format usable in the initial state?
  2. Does it make sense to switch to saving XML instead, any drawbacks to it?
  3. For people who have implemented a collaborative editor, what was your flow for meeting loading & saving changes to your database? I would appreciate pointers.

There's a beginning of a PR for this here: #451, but it needs additional work for which we're looking for sponsors. For now, I'm closing this as a duplicate