Skipping some transactions in prosemirror-collab

I’m using prosemirror-collab plugin to enable collaborative mode. In my setup every transaction is aggregated in collab plugin state and pushed to collaboration server. Setup is similar to example from prosemirror docs.

I have functionality, that allows user to visually decorate some pieces of text with marks. User can change range of that selection via dragging by one of the decoration ends. When dragging, I want user to immediately see changes, thus I dispatch transaction with removeMark/addMark steps. But I want those changes to be send to the collaboration server only when user releases mouse button. Because I have some server logic for post-processing changes in doc and don’t want it to work on intermediate steps.

What can be a correct approach for solving this task?

So far I came up with the following:

1.) During dragging, dispatch usual transaction, but add “collab$” plugin meta, so that prosemirror-collab plugin won’t aggregate transaction’s steps (just checked source-code of prosemirror-collab for potential hacks)

2.) During mouse up, dispatch transaction with manually created RemoveMarkStep/AddMarkStep. Where in RemoveMarkStep I’ll set mark positions before drag, and in AddMarkStep I’ll set final positions. I can’t use tr.removeMark api, as it operates on current local doc state, in which mark is already changed to latest dragging position. It simply results to incorrect positions then.

But this approach seems very subtle and I wonder what can go wrong. As I’m basically applying transactions locally, and in the end dispatching another transaction, which will hopefully do nothing locally but will be correct from server perspective (mark position changed from initial to final).

Thanks in advance for help!

Since you’re using non-public internals (and relying on a generated plugin key to stay stable), this is indeed not a very robust approach.

Have you looked into using decorations, rather than document modification, to show the range during dragging, and only generating an update step when the drag is finished?

1 Like

I see. That should be the way, agree. I can create inline Decoration during dnd, that will overlap styles from existing marks. Or make existing mark to render empty styles after dnd start, so only new Decoration in shown. And in the end of dnd actually change marks in document.

Thanks for suggestion!