New nodes from split are clones or existing ones

I defined a schema which is almost the same as prosemirror’s schema-list :

- note
  - children (ul)
    - bullet+ (li)
      - paragraph children?

where paragraph (p) is inline*

To split bullets/paragraph I also have reused the splitListItem from the list-schema package. However I also need to assign a new unique ID to every new bullet node that is created by the split.

The split works but new nodes are created as node copies: transform.split() does a node.copy() which copies also the ID of the cloned node. I saw a descendants() technique to scan nodes for one without ID (and so assign a new one) but is is useless as soon as a cloned already have an ID (unless we try to detect two equals IDs).

Isn’t there another technique to initialize a new node? transform.split() is able to invoke NodeType.create() but I never get the required typeAfter to do so.

You can’t, as a rule, maintain unique IDs at the transform/step level, but what people tend to do here is register a plugin with an appendTransaction hook that checks and, if necessary, updates the document to enforce unique IDs whenever new ID-bearning nodes are created.

Yes I saw the plugin technique, described as the « descendants() » in my initial post. However this technique detects new nodes when they miss some attribute (id) to initialize, whereas nodes created through copy already have that field cloned from the previous node.

nodes created through copy already have that field cloned from the previous node.

Right. I have a uniqueIDs plugin and it does have to deal with this issue, which complicates the code significantly. I’ve seen a bunch of example code posted that ignores this. I would share but the plugin is doing a couple of other things so it’s not a good example of how to achieve just this.

Essentially I have to scan the document for duplicates. I avoid having to do a deep scan of the entire node tree by keeping track of the entire set of nested IDs on each node. You can do this either a hacky way, by adding a new property to the node (which are supposed to be immutable), or a clean way, using a WeakMap.

1 Like

Yes @tslocke that’s what I did: when using descendants I initialize a set of “know ids” and look for duplicates: I then assume the latest duplicate is the new id. That’s kind of frustrating (and a bit scary for performance if you have a big doc) when you know that there is a create() method on your NodeType (which can be called by the split, but only when splitting at Node’s edge apparently, and I don’t understand why yet).