Undo not working after tr with addToHistory: false

My app gives every ProseMirror block a unique ID. First the client assigns locally unique temp IDs, later the server provides globally unique IDs which are written into the document with an addToHistory: false transaction. The transaction only contains setNodeMarkup operations.

I’ve noticed that sometimes I can’t undo past this transaction. If I hit undo I just see the caret jump to an odd position, and nothing else change. If I comment out the dispatch call on that one addToHistory: false transaction, undo starts working properly again.

Any suggestions on what might be causing this?

I’m using TipTap btw.

Not sure. Can you condense it down to a simple, deterministic, stand-alone script?

As mentioned in another thread, I’m in the process of moving from TipTap to plain ProseMirror. It’ll be much easier to create a simple stand-alone script once I’ve done that, so I’ll resurrect this thread once that’s done.

I still don’t have an isolated example - it’s difficult to reproduce the bug outside of my full codebase, but I have made some progress identifying the problem. I’ve also implemented a hacky fix, by forking history.js (from prosemirror-history) into my project.

In applyTransaction in that file, there is a big if/else-if/else, the last branch of which, as I understand it, handles adding addToHistory === false transactions.

Those transactions can’t simply be discarded because they might alter document mappings. So appendTransaction returns

new HistoryState(history.done.addMaps(tr.mapping.maps),
                 history.undone.addMaps(tr.mapping.maps),
                 mapRanges(history.prevRanges, tr.mapping), history.prevTime)

I discovered that if I didn’t update history with tr.mappings, everything started working properly again. i.e. if I simply return the original history object passed in to applyTransaction.

(my hacky fix is to do this when the problematic transaction is detected, using a metadata property)

The reason this looks like a bug to me is that, as mentioned above, the transaction in question only contains setNodeMarkup operations. Can those lead to changed mappings? I would have thought not.

Is there enough here to help narrow down the bug?

thanks for the awesome information.

Have you tried recording the changes for which this goes wrong and trying to replay them outside of your full setup? As long as this can’t be reduced to a simple test case, it’s hard for me to say anything about whether it’s a problem in the library or the use.