Hey folks,
Thanks for all your lengthy replies and suggestions!
In the end, I went with the semaphore solution and it works perfectly. I'm not used to this flow paradigm (and I'm mostly using Node-RED because of its huge community and ecosystem, just like @parasaurolophus), and I still prefer writing code by hand, so most of the logic of what I'm working on is plain Javascript in function nodes.
I don't think race conditions will be common in my use case, but I prefer ensuring it can't happen at all.
As for the "project" itself, it is coming along really well, I'm using it for my own automations and I will soon publish its source code on GitHub, so you can take a look or use it for your automations!
Thanks again for your replies!