This subtle detail confused me a good bit as well.
I ended up writing the function below for our application to get a more or less guaranteed-to-be-correct diff range for the updated document (latest state), for example in an appendTransaction context.
/**
* Get start and end diff position values for two states (old, new).
* @param {EditorState} oldState - last PM state
* @param {EditorState} newState - current PM state
* @returns {object} - { start, end }
*/
function getDiffRange (oldState, newState) {
// https://prosemirror.net/docs/ref/#model.Fragment.findDiffStart
const start = oldState.doc.content.findDiffStart(newState.doc.content)
// Important: diffEnd value is {a,b} object since end pos will differ.
// https://prosemirror.net/docs/ref/#model.Fragment.findDiffEnd
let { a, b } = oldState.doc.content.findDiffEnd(newState.doc.content)
// WARNING: diffEnd may be lower than diffStart.
// If so, add overlap to get correct range.
// https://discuss.prosemirror.net/t/overlap-handling-of-finddiffstart-and-finddiffend/2856
const overlap = start - Math.min(a, b)
if (overlap > 0) b += overlap
return { start, end: b }
}
I think this is the correct approach, please let me know if I misunderstood anything.
Hopefully this is useful to future readers too.
