Y-prosemirror missing doc attrs

The prosemirrorJSONToYDoc function removes all doc attrs on conversion. I think this is a bug. I have created a pen to demo the issue.

Am I missing config or is this a bug? Thanks for any help.

Hi @jstleger0,

a ProseMirror document doesn’t have attributes. A document is a fragment (only containing children, no attributes). But Node inherits from Fragment, so your code does run. However, it is not expected that the doc-attributes are synced.

Any Prosemirror Node can have attrs including state.doc (See: https://prosemirror.net/docs/ref/#model.Node). We have been using state.doc.attrs in our current operational transform implementation for a few years.

I wrote a post on it here… (It requires a custom step to set)

We use it to store document-level settings that we want to be collaborative (Shared between users).

At the moment when using yjs those attributes are lost and are set back to the defaults in the schema.

Hey @jstleger0, I didn’t know that you could add properties because the functions were basically missing in ProseMirror. As a result, Yjs won’t be able to sync attributes on the doc because it is synced to a Y.XmlFragment (which doesn’t allow attributes by definition).

If you want, you can open a ticket on the y-prosemirror repository to enable syncing of doc attributes. Currently, y-prosemirror expects a Y.XmlFragment to sync to a doc. Y.XmlFragment doesn’t allow attributes by definition. We could add a feature to sync attributes when Y.XmlElement is used as a data binding target. However, I’m not sure when I can get to this.

In the meantime, you can maybe use a Y.XmlElement as a target and set the attributes on Y.XmlElemnt manually. This is really easy as you just have to do yfragment.setAttribute('prop', 'val').

We are running into a lot of complexity with this… We are currently looking at adding a leaf node within the document to contain the doc attrs… so we can maintain functionality.

See:

{
  doc: {
    content: `docattrs block+`,
    selectable: false,
  },
  docattrs: {
    atom: true,
    defining: true,
    selectable: false,
    attrs: {
      somedata: { default: 0 },
    },
  },
  parawrapper: {
    defining: true,
    group: 'block',
    content: [...],
  },
}

However, changing the schema is a very involved process within a collaborative system. Our current operational transforms will have to be remapped and reset and every service that consumes the document will need to be updated…

Is there a solution that we can work on with you? It would be great to get the doc node represented as a Y.XmlElement in the y-prosemirror implementation.

This is the last major hurdle for us taking YJS into production.

Hi @jstleger0,

you can, of course, create a PR for adding the desired functionality. I currently can’t accept more contracting work and need to scale back.

Cheers,
Kevin

Hi again.

We have tried moving in a different direction using a leaf node… However I’m running into an issue where all Node attrs are being reset to their default values when using the yDoc…

@dmonad does this look right to you:

Apologies if I have missed something. Lost trying to debug this.

In the console, you can see all the attrs are null…

Arghh!! it’s the latency of the ySyncPlugin!! That was slow of me.

There was another layer to this issue - It was to do with sending a Unit8Array over REST.

When I set string values as the attrs there was no issue sending the Unit8Array over REST.
However… as soon as I included numbers or special characters in the attrs I get an error…
TypeError: First argument to DataView constructor must be an ArrayBuffer
when sending the Unit8Array over REST.

I have disabled this temporarily. The doc now loads over WS only.

I wonder what I am missing there…

Aha… stumbled upon this on another thread…

Document updates are Uint8Array. They are not JSON-encodable. But there is help: https://docs.yjs.dev/api/document-updates#example-base64-encoding

@jstleger0 - have you progressed on this? Were you able to create a reasonable solution? We too utilize doc attrs in a different version of a ProseMirror editor (based on the old CZI code). We have been busy porting our capabilities over to TipTap, but are concerned about the doc attrs issue you faced. Have you and/or @dmonad come up with a solution to this? Many thanks!