Updating node attributes in a decoration widget plugin

I need to update node attributes within the apply function of a decoration widget plugin (in my case the node’s updated height), but I am wondering about the required process. I have the transform field from the app (apply(tr, oldDecorationSet, oldState, newState) {…}) and am cycling through the nodes with the tr.doc.descendants((node, pos) => {} loop, and have considered adding the following line:

tr.setNodeMarkup(pos, null, { …node.attrs, height: newHeight });

If I just call that in the loop, will the node get updated and then the updated node returned when the doc is updated after the plugin execution is completed?

I have seen several sample code snippets from Google searches, and they usually add a dispatch call to get PM to process the markup change, but in my case I am already in a plugin apply function that is passed a transform object in the apply function. In fact, all of the sample code snippets dispatch transactions to update the field, making me wonder if any changes I might make to nodes in my plugin might not be retained when the plugin code completes execution.

Any advice would be appreciated, my intent is that for nodes with a node attr of undefined, I recalc the height and then need to save it (to avoid future height calculations for that node), right in the code where I am cycling through all the transform doc nodes in the apply function. Seems simple, but obviously I want things to remain immutable and stable.

If you’re calling methods that change the transaction from your state field apply method, no, you really shouldn’t be doing that. That method computes a new value for your state field from a finished transaction, and should never change the transaction it is given.

If you’re building up this transaction elsewhere, yes, you have to dispatch it for it to take effect at all.

So then should the widget decoration plugin create new transactions and dispatch them? I get confused when creating a new transaction from a function that has been passed in a tr variable, figuring out what doc and state to use and wondering of the dispatched transaction will make the data unreliable or wrong.

I am cycling through the nodes in the tr.doc.descendants loop as mentioned above, any chance you can give me some specific code to take the situation in my plugin code to fire off something that will update the attribute for the desired node or nodes?

If you’re talking about the state apply method, then no, absolutely not. You could do this with a transaction appender, if you’re just reacting to transactions, or in a view plugin, if you’re responding to some separate event.