Find (new) node instances and track them

The concept of ‘new content entering the document’ is kind of vague, since nodes in replaced content might be joined to other, adjacent nodes if the replace edges cut through them. Also, going from nodes inside the content in a replace step to positions in the final document is rather painful, since there’s no reliable way to map positions pointing into step.param.content to actual result document positions.

What you can do is find the replaced ranges created by a transform, map them all to the final document, and scan them (possibly merging overlapping ranges). Something like this:

function replacedRanges(transform) {
  var ranges = []
  for (var i = 0; i < transform.steps.length; i++) {
    var step = transform.steps[i], map = transform.maps[i]
    if (step.type == "replace") {
      // Could write a more complicated algorithm to insert it in
      // sorted order and join with overlapping ranges here. That way,
      // you wouldn't have to worry about scanning nodes multiple
      // times.
      ranges.push({from: step.from, to: step.to})
    }
    for (var j = 0; j < ranges.length; j++) {
      var range = ranges[j]
      range.from = map.map(range.from, -1).pos
      range.to = map.map(range.from, 1).pos
    }
  }
  return ranges
}

And then iterate over the nodes between those positions.