Remote Procedure Call implementation for WebExtensions, to easily call functions across content scripts and background script.
Browse Source

Create Readme.md

master
Gerben 10 months ago
parent
commit
ad256dac5c
2 changed files with 64 additions and 39 deletions
  1. +63
    -0
      Readme.md
  2. +1
    -39
      src/webextension-rpc.js

+ 63
- 0
Readme.md View File

@@ -0,0 +1,63 @@
# webextension-rpc

This module provides a *Remote Procedure Call* abstraction around the message passing that is
available to WebExtension (browser extension) scripts. It makes it easier to call a function in the
background script from a tab’s content script, or vice versa.


## Example use

In `background.js`:

function myFunc(arg) {
return arg * 2
}
makeRemotelyCallable({ myFunc })

In `content_script.js`:

const myRemoteFunc = remoteFunction('myFunc')
myRemoteFunc(21).then(result => { ... result is 42! ... })

Note that the remote function always returns a `Promise`, which resolves with the remote function’s
actual return value (if the return value is itself a Promise, its result is awaited too).


## Install

### Using NPM

This module is published [on npm](https://www.npmjs.com/package/webextension-rpc).

Run `npm install webextension-rpc` or equivalent.

### Standalone

Try one of the magic npm bundlers, for example:

`wget https://wzrd.in/standalone/webextension-rpc -O webextension-rpc.js`


## API

### `remoteFunction(functionName, { tabId })`

Create a proxy function that invokes the specified remote function.

- `functionName` (string, required): name of the function as registered on the remote side.
- `options` (object, optional):
- `tabId` (number): The id of the tab whose content script is the remote side. Leave undefined
to call the background script (from a content script).

### `makeRemotelyCallable(functions, { insertExtraArg })`

Register one or more functions to enable remote scripts to call them. Arguments:

- `functions` (object, required): An object with a `{ functionName: function }` mapping. Each
function will be remotely callable using the given name.
- `options` (object, optional):
- `insertExtraArg` (boolean, default is `false`): If truthy, each executed function also
receives, as its first argument before the arguments it was invoked with, a [Tab][] object,
which contains the details of the tab that sent the message.

[Tab]: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/Tab

+ 1
- 39
src/webextension-rpc.js View File

@@ -1,24 +1,4 @@

// A Remote Procedure Call abstraction around the message passing available to
// WebExtension scripts. Usable to call a function in the background script from
// a tab's content script, or vice versa.
//
// The calling side always gets a Promise of the return value. The executing
// (remote) function can be an async function (= it returns a Promise), whose
// completion then will then be waited for.

// Example use:
//
// === background.js ===
// function myFunc(arg) {
// return arg*2
// }
// makeRemotelyCallable({myFunc})
//
// === content_script.js ===
// const myRemoteFunc = remoteFunction('myFunc')
// myRemoteFunc(21).then(result => { ... result is 42! ... })

// Our secret tokens to recognise our messages
const RPC_CALL = '__RPC_CALL__'
const RPC_RESPONSE = '__RPC_RESPONSE__'
@@ -37,15 +17,9 @@ export class RemoteError extends Error {
}
}


// === Initiating side ===

// Create a proxy function that invokes the specified remote function.
// Arguments
// - funcName (required): name of the function as registered on the remote side.
// - options (optional): {
// tabId: The id of the tab whose content script is the remote side.
// Leave undefined to call the background script (from a tab).
// }
export function remoteFunction(funcName, { tabId } = {}) {
const otherSide = (tabId !== undefined)
? "the tab's content script"
@@ -145,18 +119,6 @@ function incomingRPCListener(message, sender) {
// A bit of global state to ensure we only attach the event listener once.
let enabled = false

// Register a function to allow remote scripts to call it.
// Arguments:
// - functions (required):
// An object with a {functionName: function} mapping.
// Each function will be callable with the given name.
// - options (optional): {
// insertExtraArg:
// If truthy, each executed function also receives, as its first
// argument before the arguments it was invoked with, an object with
// the details of the tab that sent the message.
// }

export function makeRemotelyCallable(functions, { insertExtraArg = false } = {}) {
// Every function is passed an extra argument with sender information,
// so remove this from the call if this was not desired.


Loading…
Cancel
Save