Skip to content

Not sure how to add a new XML fragment #126

@nyacg

Description

@nyacg

Hello!

I'm not sure how to add a new XML fragment to my array of objects.

The use case is around having multiple 'pages' in a rich text editor. I would then have a separate object in the synced store that would maintain the folder structure.

My store currently looks like this:

type Todo = { completed: boolean; title: string };
type Doc = { id: string; fragment: "xml" };

export const collaborativeStore = syncedStore({ todos: [] as Todo[], docs: [] as Doc[], exampleDoc: "xml" });

It works great for the todo list:

const state = useSyncedStore(collaborativeStore);
...
state.todos.push({ completed: false, title: target.value });
...

But if I try and add a new doc I'm not sure what I should be pushing to the array...

If I use a fragment that's created at initialization of the synced store, everything works (collaboration cursor, collaborative editing, persistence, etc.) for a single document:

// from getCollaborationExtensions() function
 const fragment = collaborativeStore.exampleDoc;
 return [
      Collaboration.configure({
          fragment: fragment,
      }),
      CollaborationCursor.configure({
          provider: provider,
          user: {
              name: username,
              color: getRandomColor(),
          },
      }),
];

I've tried to populate the array collaborativeStore.docs in various ways and each has failed. They all follow this pattern:

const docReference = collaborativeStore.docs.find((doc) => doc.id === documentId);
 
 if (!docReference) {
      const newDocReference = { id: documentId, fragment: <some way of populating the fragment> };
      collaborativeStore.docs.push(newDocReference);
}

const fragment = collaborativeStore.docs.find((doc) => doc.id === documentId).fragment;
return [ ... ];
  1.  const newDocReference = { id: documentId, fragment: "xml" };

    Gives this error:

    Uncaught TypeError: Cannot read properties of undefined (reading 'on')
    at new UndoManager (yjs.mjs:3612:1)
    at Plugin.init (undo-plugin.js:38:1)
    at EditorState.reconfigure (index.js:868:1)
    at Editor.createView (index.js:3617:1)
    at new Editor (index.js:3456:1)
    
  2.  const newDocReference = { id: documentId, fragment: new Y.XmlFragment() };

    Gives no error but the collaboration does not work (no cursor, no collaborative editing, no save)

  3.  const ydoc = getYjsDoc(collaborativeStore);
     const newDocReference = { id: documentId, fragment: ydoc.getXmlFragment(documentId) };

    Gives the following error

    Uncaught TypeError: Cannot read properties of null (reading 'forEach')
    at typeListInsertGenericsAfter (yjs.mjs:5296:1)
    at typeListInsertGenerics (yjs.mjs:5353:1)
    at eval (yjs.mjs:7676:1)
    at transact (yjs.mjs:3358:1)
    at YXmlFragment.insert (yjs.mjs:7675:1)
    at YXmlFragment._integrate (yjs.mjs:7524:1)
    at ContentType.integrate (yjs.mjs:9312:1)
    at Item.integrate (yjs.mjs:9873:1)
    at typeMapSet (yjs.mjs:5510:1)
    at eval (yjs.mjs:6072:1)
    

Note that I am doing this outside of the react lifecycle (i.e. not using useSyncedStore just operating on the store directly but from what I understand that's not likely to be the issue. Oh and we're using TipTap for the rich text editor

What should I be doing? 🙏

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions