Out of frustration I rewrote the whole thing and now it works. I'm sure I'd overlooked something basic, trying to fix a fix etc.
In case others come across this thread in the future I'm posting my solution here. It's tested and works after exporting the project as an nw.js project.