After another part of the extension has sent a message using this code
chrome.runtime.sendMessage({greeting: "hello"});
Any Rx.js experts out there who can take this messaging API
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
});
and wrap it in an Observable that emits new messages and allows a sendResponse?
Simply emitting incoming messages as an Observable is very easy.
const MessagingObservable = Rx.Observable.create(observer => {
chrome.runtime.onMessage.addListener(listener);
function listener(request, sender, sendResponse) {
observer.next(request);
}
return () => {
chrome.runtime.onMessage.removeListener(listener);
};
});
But how to bind the sendResponse callback?
In addition to sending messages between different components in your extension, you can use the messaging API to communicate with other extensions. This lets you expose a public API that other extensions can take advantage of.
Chrome starts each native messaging host in a separate process and communicates with it using standard input (stdin) and standard output (stdout). The same format is used to send messages in both directions: each message is serialized using JSON, UTF-8 encoded and is preceded with 32-bit message length in native byte order.
and much more... If you want to know more about the breaking changes, click here... RxJS is a library for reactive programming using Observables, to make it easier to compose asynchronous or callback-based code.
Reactive Extensions Library for JavaScript RxJS is a library for reactive programming using Observables, to make it easier to compose asynchronous or callback-based code.
You can use the built-in fromEventPattern
function to create an observable, like this:
const messages = Rx.Observable.fromEventPattern(
handler => chrome.runtime.onMessage.addListener(handler),
handler => chrome.runtime.onMessage.removeListener(handler),
(request, sender, sendResponse) => ({ request, sender, sendResponse })
);
Note that the call to fromEventPattern
includes a result selector, so that values emitted by the observable contain the request
, the sender
, and the sendResponse
, which you'd use like this:
messages.subscribe(({ request, sender, sendResponse }) => {
console.log(request);
sendResponse(/* ... whatever ... */);
});
To support calling sendResponse
asynchronously, the listener needs to be able to return true
. This can be done by wrapping the handler
, like this:
const messages = Rx.Observable.fromEventPattern(
handler => {
const wrapper = (request, sender, sendResponse) => {
const event = { async: false, request, sender, sendResponse };
handler(event);
return event.async;
};
chrome.runtime.onMessage.addListener(wrapper);
return wrapper;
},
(handler, wrapper) => chrome.runtime.onMessage.removeListener(wrapper)
);
And you'd use it like this:
messages.subscribe(event => {
console.log(event.request);
event.async = true;
setTimeout(() => event.sendResponse(/* ... whatever ... */), 1000);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With