aklinker1 / webext-core

Collection of essential libraries and tools for building web extensions
https://webext-core.aklinker1.io
MIT License
96 stars 11 forks source link

Multiple Listeners in Single Context #19

Closed NoamLoewenstern closed 1 year ago

NoamLoewenstern commented 1 year ago

Current code doesn't allow multiple listeners in a single context: here.

if (keyListeners[type] != null) {
  const err = Error(
    `[messaging] In this JS context, only one listener can be setup for ${type as string}`,
  );
  config?.logger?.error(err);
  throw err;
}

The reason is understandable: If there's multiple context listening and returning a response then the invoker/sender will receive just the first result. Plus, will confuse the listeres, not realizing that multiple responses is not an accurate way of data flow...

But, I would add that sometimes what is intended in the listeners' side is solely to listen to incoming event in multiple parts in the context, without returning response. In that sense, I wouldn't understand why it shouldn't be possible.

I'd like to ask if there's something else I'm missing for the reason?

aklinker1 commented 1 year ago

You're correct, it's just to prevent race conditions between listeners that return responses.

While the messaging APIs technically support these sorts of listeners, it's not well documented and easy to mess up and cause these race conditions, especially when there are multiple people working on an extension.webextension-polyfill makes it even harder to figure out, and is even less documented. For that reason, I wouldn't recommend doing this with @webext-core/messaging, webextension-polyfill, or the chrome APIs directly.

It seems like you want an event-based messaging framework, rather than the request-response model this library provides. I do not plan on supporting these types of listeners in @webext-core/messaging, so you have a couple options:

aklinker1 commented 1 year ago

I would consider adding an event based messaging framework to @webext-core, but webext-bridge already exists and works on all browsers, so I'd just recommend using it instead.

NoamLoewenstern commented 1 year ago

Thanks so much! I'll have a look.