serversideup / webext-bridge

💬 Messaging in Web Extensions made easy. Batteries included.
https://serversideup.net/open-source/webext-bridge
MIT License
547 stars 50 forks source link

Sending a message to * should broadcast it to all listeners #29

Closed altryne closed 2 years ago

altryne commented 2 years ago

Clear and concise description of the problem

I want to send a message to all contexts that listen to a message. Right now it seems I need to specify each context individually, and I would like to broadcast a message to all contexts with *

Suggested solution

sendMessage("message", newValue, '*');

Alternative

No response

Additional context

No response

Validations

zikaari commented 2 years ago

It's quite tricky to define a proper spec for how a broadcast should behave, considering that webext-bridge was born because of a need for 1 on 1 messaging, with optional replies. Broadcasts are not that.

Besides you don't even need webext-bridge for a broadcast. I have a feeling that Chrome's stock messaging API's are exactly that - broadcasts. I think if you do chrome.runtime.sendMessage anywhere in your extension, all the listeners you setup using chrome.runtime.onMessage will get called.

Still if you want to use webext-bridge, for example if you want replies, you can create a quick wrapper like so - This one will broadcast to all and return the value of first one that responds:

// broadcast.ts

const broadcast= (messageId: string, data: any, tabId?: number) => Promise.race([
    sendMessage(messageId, data, { context: 'content-script', tabId }),
    sendMessage(messageId, data, { context: 'devtools', tabId }),
    sendMessage(messageId, data, 'background')
])
altryne commented 2 years ago

@zikaari thanks for the comment. I worked around the problem that I had, just wanted to make sure that I'd suggest this here, as broadcast has additional benefits, like for example, sending messages to all injected scripts on all tabs.

My use-case was this: I had a event listener on user preference for dark mode, and I wanted to put this in the background script, and when a user changes their preferences, I wanted to broadcast the new preference to everywhere in the app, options.html, and all inject scripts.

I noticed that sending sendMessage needs a tabId, and sending to options.html wasn't possible event, so I thought a broadcast could be the right way for this.

zikaari commented 2 years ago

Awesome. Closing since this use case is out of scope for this project, and there are other ways to achieve the broadcast effect without much hassle.