Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rx.js, Chrome Messaging API

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?

like image 798
Tom Avatar asked Jun 26 '18 15:06

Tom


People also ask

How do I use the messaging API?

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.

How does native messaging work in chrome?

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.

What is rxjs and how does it work?

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.

What is Reactive Extensions library for JavaScript RxJS?

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.


1 Answers

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);
});
like image 56
cartant Avatar answered Jan 03 '23 22:01

cartant