I may need to update my knowledge (I
hope I do if you’re right), but from my understanding USB is a CPU-emulated protocol, which is to say there are no pins for “mouse button”, and the CPU has to do some “figuring out what this data means” work for each input event. Then, all this is done on a multitasking CPU that may or may not prioritize the interpretation and processing of that input.
That all being true, having a publish/subscribe model is still not the same as having a true interrupt (and I’d have to do some digging to figure out whether there wasn’t still polling somewhere in the pub/sub pipeline)