Open esindger opened 1 year ago
Upon thorough analysis, I have determined that the root cause of this issue lies within the behavior of the Bridge
in Quasar BEX context. Bridge creates a new instance for each new connection, and each Bridge
instance operates independently from the others.
This implies that an event handler I've set for test
in one Bridge instance is not visible to other Bridge instances. As a result, when I'm sending the test
event from the test.bg
event handler, the new Bridge
instance that gets created for this connection does not have a handler for the test
event. This means that the promise that I expect to get resolved upon calling respond()
never gets resolved, as the test
event handler in the new Bridge instance is missing.
What is the recommended solution?
I ran into the same situation. Responses seem to not work, and I'm not sure they are supposed to?
The only way I could get data back to my popup from a content script, is by having another set of proxy events for the "upstream": on event, content script send -> background script listen & re-send -> listener in popup
This caused every active content script to emit such an event, because obviously, there's got to be multicasting when sending "downstream" from one background script to multiple tabs' content scripts.
And I'm not sure how respond functions would handle this, since they resolve single Promises, so I guess currently they just don't do anything and that's what we're encountering?
Logically, responding to a multicast event would necessitate either a callback function or an Observable stream from the sender's side to handle multiple async value pushes properly, not a Promise which is only viable for single async value push scenarios, so it seems a different bridge API would be needed for content-background script communication to not be misleading?
For me, the documentation implied that a "downstream" proxy would be enough, nothing suggested that responses would not work, nor did the API of the bridge imply that responses are sometimes unusable. They don't even get into a race condition, they just never resolve.
At least a note on this in the docs would've saved me quite a bit of fiddling around, unless I missed that / this is actually a bug somehow?
The source of this issue is that the response is emitted on the content script's bridge, but the response callback is registered on the background script's bridge. The bridges are not ...bridged.
This actually results in a leak as well. The uncalled callbacks pile up.
There is also another issue that if multiple content scripts are active, only one of them will end up resolving the promise, although all of them will be invoked. This is because there is a one-to-many relationship between the background script and the content-scripts.
I think a good solution may be for the allActiveConnections
parameter to expose the other active bridges. Then the client could choose the bridge to dispatch to. This would resolve the multiple content-script issue while also ensuring the callback was invoked.
export default bexBackground((bridge, allActiveConnections) => {
bridge.on('go', ({data, respond}) => {
const contentBridge = allActiveConnections.findBridge(someCondition)
contentBridge?.sendOnlyTo('go', data).then(it=> respond(it,data);
});
I've also just come across this issue... I added event listeners (eg. chrome.contextMenus.onClicked
) within the bexBackground
function so that I could communicate with the rest of the extension, however, my event listeners are being called twice.
It seems that bexBackground
and the bridge
are not reliable and that I may have to resort to native messaging instead, unless anyone has a solution?
What happened?
I am trying to dispatch an event test to
my-content-script
from a popup, usingbackground
as a proxy, and sending the eventtest.bg
to it.https://github.com/esindger/quasar-bex-bridge/blob/4681cffab581194baeb201964a5b5d2aa54006f7/src/pages/IndexPage.vue#L47-L56
The problem lies in that if I call
bridge.send('test')
from the handler of another event (e.g.,test.bg
), the promise never gets resolved. Therespond()
function does not seem to work.https://github.com/esindger/quasar-bex-bridge/blob/4681cffab581194baeb201964a5b5d2aa54006f7/src-bex/background.ts#L32-L45
my-content-script.ts
https://github.com/esindger/quasar-bex-bridge/blob/65a94c9c4c1e4bdee30d6cca343c5dcc7d7852c0/src-bex/my-content-script.ts#L17-L25
Could you please help in identifying the root cause of this issue and provide a suitable fix or workaround?
What did you expect to happen?
I expect that after the call to respond(), the promise will resolve.
Reproduction URL
https://github.com/esindger/quasar-bex-bridge
How to reproduce?
Flavour
Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)
Areas
BEX Mode
Platforms/Browsers
Chrome
Quasar info output
Relevant log output
No response
Additional context
No response