MCPcopy Index your code
hub / github.com/electrode-io/react-native-electrode-bridge

github.com/electrode-io/react-native-electrode-bridge @v2.0.2-legacy

Chat with this repo
repository ↗ · DeepWiki ↗ · release v2.0.2-legacy ↗ · + Follow
519 symbols 1,664 edges 90 files 119 documented · 23%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Electrode React Native Bridge

WIP/EXPERIMENTAL

Link to the demo app

This project is essentially a react native library, consisting of a JavaScript module and an associated Android Native Module and iOS Native module.

It is built on top of the react native built-in bridging constructs (to communicate between the react native JS side and Native side) and offers a clean bi-directional communication API, exposing methods to send events and/or requests from/to any side of the bridge (JS/Native). It offers more options and flexibility to communicate between the JS/Native side that is offered out of the box by react native. Ultimately it can help with integrating react native applications into existing native code bases. It might be used as one of the basic building block of react native mini apps and native modules.

Here is a non-exhaustive list of a few reasons to use this library as the low level communication bridge instead of the built-in react native constructs :

  • Isolates the host application from react native library types and specifics (vanilla Java/Android implementation)
  • Messages can be sent either to the other side of the bridge or on the same side (or both)
  • Request timeout supported
  • Offer a way to send requests from Native to JS side
  • More than a bridge, it can be used as a message hub allow react native apps / native modules intercommunication

The bridge API is built around two messaging idioms, events and requests :

  • An event is a fire & forget message type. You should emit an event whenever you are not expecting any kind of response back from whoever is listening for this specific event. Because of this, there can be multiple listeners for a given event name.
  • On the other hand, a request expects some kind of response. You should send a request whenever you are asking for something (be it some data or just an acknowledgment that the request was successfully handled or not). A request can only have one "handler" registered for it. Also due to the fact that sending a request expects a response back; you can specify a timeout when sending the request.

Both sides of the bridge (JS/Native) expose a similar API (mirrored) to respectively send requests and emit events, and also listen for specific events or requests.

While this bridge can be used a standalone react native plugin to integrate a single react native app into an native host application, this is not the optimal use of it. Indeed multiple native modules using the bridge for communication will be able to exchange messages between themselves or with the react native apps.

For iOS:
NOTE: Please do yarn add react-native@0.42.0, that installs react-native. This step is necessary to avoid compiling issues for iOS. 
For eg: @m-C02RW0LJG8WM ~/Documents/Projects/react-native-electrode-bridge (master) $ yarn add react-native@0.42.0
TODO :

ANDROID :
- Offer a way to unregister event/request handlers in order to avoid keeping references around
- Figure if annotations might offer a nicer client API and implement annotation support (@EventHandler @RequestHandler)

JavaScript API Reference

import { electrodeBridge } from '@walmart/react-native-electrode-bridge';

Once you import the module, you can interact with the electrodeBridge instance through a few API methods:

electrodeBridge.sendRequest

electrodeBridge.sendRequest(
    name: String, {
    data: Object = {},
    timeout: Number = DEFAULT_REQUEST_TIMEOUT_IN_MS /* 5000 */,
    dispatchMode = DispatchMode.NATIVE
  }): Promise

Sends a request with a specific name through the bridge.

Mandatory

  • name : The name of the request to emit

Optional :

  • data : An object to include as the data payload of the request (Default : {})

  • timeout : A timeout in milliseconds, after which, if no response was received, the returned promise will be rejected with error code EREQUESTIMEOUT. (Default : 5000)

  • dispatchMode : The dispatch mode to use for the request :

    • DispatchMode.NATIVE will send the request to the native side
    • DispatchMode.JS will send the request to the JS side

Example usage :

electrodeBridge.sendRequest(
    "myapp.get.current.weather", {
    data: { latlng: `37.381435,-122.036909` },
    timeout: 6000
  }).then(resp) {
    // Do whatever you need to do with the response
  }

electrodeBridge.emitEvent

electrodeBridge.emitEvent(
    name: String, {
    data: Object = {},
    dispatchMode: DispatchMode = DispatchMode.NATIVE
  }): void

Emits an event with a specific name through the bridge.

Mandatory

  • name : The name of the event to emit

Optional

  • data : An object to include as the data payload of the event (Default : {})

  • dispatchMode : The dispatch mode to use for the event :

    • DispatchMode.NATIVE will send the event to the native side
    • DispatchMode.JS will send the event to the JS side
    • DispatchMode.GLOBAL will send the event to both native & JS side

Example usage :

electrodeBridge.emitEvent("myapp.some.event");

electrodeBridge.registerRequestHandler

electrodeBridge.registerRequestHandler(
  name: String,
  handler: Promise): void

Registers a handler that can handle a specific request name.
Please note that if an handler already exists for the specific request name (on the side you are making the call) the method will throw an error. Current implementation only allows one request handler to be associated to a given request name.

Mandatory

  • name : The name of the request this handler can handle

  • handler : The handler function, taking a single parameter being the data of the request and returning a Promise. Implementer of the handler should either resolve the promise with an object being the response data (if any) or reject the promise with an Error.

Example usage :

electrodeBridge.registerRequestHandler(
  "myapp.awesomerequest",
  (requestData) => {
    return Promise.resolve({ hello: "World"});
  }
)

electrodeBridge.registerEventListener

electrodeBridge.registerEventListener(
  name: String,
  handler: Function): void
}

Registers an event listener that will be invoked whenever an event of the specific type is received by the bridge.

Mandatory

  • name : The name of the event that this listener is interested in

  • handler : A function to handle an incoming event. The function takes a single parameter being the data payload of the event (if any).

Example usage :

electrodeBridge.registerEventListener(
  "myapp.coolevent",
  (eventData) => {
    // Do whatever you need to do
  }
)

Android API Reference

First step is to add the ElectrodeBridgePackage containing the ElectrodeBridge Native Module to the list of packages included in your app :

@Override
protected List<ReactPackage> getPackages() {
  return Arrays.<ReactPackage>asList(
      new MainReactPackage(),
      new ElectrodeBridgePackage() // ADD THIS LINE !
  );
}

Then, access to API methods is provided through static methods of the ElectrodeBridgeHolder class.

ElectrodeBridge can deal with any PrimitiveWrapper and Bridgeable as the request and response types.

ElectrodeBridgeHolder.sendRequest

void sendRequest(
  @NonNull ElectrodeBridgeRequest request,
  @NonNull ElectrodeBridgeResponseListener responseListener);

Sends a request through the bridge.

Mandatory

  • request : A request instance created using ElectrodeBridgeRequest.Builder

  • completionListener : An instance of RequestCompletionListener to be notified of the response.

To make is easier to construct a request and send it via bridge the RequestProcessor class can be used

Example usage :


new RequestProcessor<>("my.request.name", <input data>, <ExpectedResponse>.class, new ElectrodeBridgeResponseListener<ExpectedResponse>() {
            @Override
            public void onFailure(@NonNull FailureMessage failureMessage) {
              //Handle failure
            }

            @Override
            public void onSuccess(@Nullable ExpectedResponse responseData) {
              // Do whatever you need to do with the response
            }
        }).execute();

The RequestProcessor takes care of generating a ElectrodeBridgeRequest and sending it over to the ElectrodeBridge

In case of a request not expecting any ExpectedResponse use None to indicate the same.

<input data>: can be null.

ElectrodeBridge.emitEvent

void emitEvent(@NonNull ElectrodeBridgeEvent event)

Emits an event through the bridge.

Mandatory

  • event : An event instance created using ElectrodeBridgeEvent.Builder

To make is easier to construct an event and emit it via bridge the EventProcessor class can be used

Example usage :


new EventProcessor<>("my.event.name", <data>).execute();

<data> can be null

ElectrodeBridge.registerRequestHandler

UUID registerRequestHandler(
  @NonNull String name,
  @NonNull ElectrodeBridgeRequestHandler requestHandler);

Registers a handler that can handle a specific request name.
When a request is fired, for example from JS side, ElectrodeBridge first looks for a registered request handler on JS side, if not found bridge will forward the request to Native side.

Mandatory

  • name : The name of the request this handler can handle

  • requestHandler an instance of ElectrodeBridgeRequestHandler that should take care of handling the request and completing it.

To make is easier to construct a request handler and register it to the bridge a RequestHandlerProcessor class can be used

Example usage :

new RequestHandlerProcessor<>("my.request.name", <ExpectedRequest>.class, <ExpectedResponse>.class, new ElectrodeBridgeRequestHandler<ExpectedRequest, ExpectedResponse>() {
           @Override
           public void onRequest(@Nullable ExpectedRequest payload, @NonNull ElectrodeBridgeResponseListener<ExpectedResponse> responseListener) {
             // Handle the request (sync or async) and call one of the completion methods once done
             requestCompletioner.onSuccess(expectedResponse); OR            
             requestCompletion.onFailure(failureMessage);  // With error
           }
       }).execute();

ElectrodeBridge.registerEventListener

void addEventListener(
  @NonNull String eventName,
  @NonNull ElectrodeBridgeEventListener eventListener);
)

Mandatory

  • name : The name of the event that this listener is interested in

  • eventListener an instance of ElectrodeBridgeEventListener that is interested in knowing when an event is emitted.

Example usage :

new EventListenerProcessor<>("my.event.name", <ExpectedEvent>.class, new ElectrodeBridgeEventListener<ExpectedEvent>() {
            @Override
            public void onEvent(@Nullable ExpectedEvent eventPayload) {
                //Do what you need to do now.
            }
        }).execute();

Note: Multiple event listeners can be registered for the same event.

Android remarks

This bridge implementation does not make use any third party library, so that we don't lock in any client into a specific framework. It makes use of vanilla Java/Android types to expose communication methods.

The client native app might want to build a specific adapter around the bridge, so that the native app can make use of whatever framework fits them best (Rx/Bolts/Otto ... for communication ... Jackson/Gson for serialization ...).

It would be nice at some point to see adapters for a specific frameworks being redistributed as libraries to be used by others.

Extension points exported contracts — how you extend this code

Bridgeable (Interface)
Indicates that any class that implements this interface can be sent across the ElectrodeNativeBridge. [15 implementers]
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/Bridgeable.java
ElectrodeBridgeResponseListener (Interface)
Provide methods to report response for a request. [5 implementers]
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/ElectrodeBridgeResponseListener.java
ElectrodeBridgeRequestHandler (Interface)
Provide method to be notified of incoming request. An implementor of this interface is expected to handle any incoming r [5 …
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/ElectrodeBridgeRequestHandler.java
ElectrodeBridgeEventListener (Interface)
Provide method to be notified of incoming event [5 implementers]
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/ElectrodeBridgeEventListener.java
Processor (Interface)
(no doc) [8 implementers]
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/Processor.java

Core symbols most depended-on inside this repo

d
called by 38
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/helpers/Logger.java
execute
called by 31
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/Processor.java
instance
called by 26
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/ElectrodeBridgeTransceiver.java
onSuccess
called by 22
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/ElectrodeBridgeResponseListener.java
getData
called by 19
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/BridgeMessage.java
sendMessage
called by 18
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/ElectrodeReactBridge.java
getId
called by 18
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/BridgeMessage.java
getType
called by 13
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/BridgeMessage.java

Shape

Method 430
Class 64
Interface 19
Function 4
Enum 2

Languages

Java95%
TypeScript3%
C++2%

Modules by API surface

android/electrode-reactnative-bridge/src/androidTest/java/com/walmartlabs/electrode/reactnative/bridge/RequestProcessorTest.java34 symbols
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/ElectrodeBridgeTransceiver.java31 symbols
android/electrode-reactnative-bridge/src/androidTest/java/com/walmartlabs/electrode/reactnative/bridge/BaseBridgeTestCase.java31 symbols
android/electrode-reactnative-bridge/src/androidTest/java/com/walmartlabs/electrode/reactnative/sample/model/Person.java26 symbols
android/electrode-reactnative-bridge/src/androidTest/java/com/walmartlabs/electrode/reactnative/sample/api/PersonApi.java23 symbols
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/util/BridgeArguments.java19 symbols
android/electrode-reactnative-bridge/src/androidTest/java/com/walmartlabs/electrode/reactnative/bridge/ElectrodeBridgeTransceiverTest.java19 symbols
example/android/app/src/main/java/com/electrode/reactnativebridge/example/NativeFragment.java16 symbols
android/electrode-reactnative-bridge/src/androidTest/java/com/walmartlabs/electrode/reactnative/sample/api/PersonRequests.java15 symbols
android/electrode-reactnative-bridge/src/main/java/com/walmartlabs/electrode/reactnative/bridge/BridgeMessage.java14 symbols
js/ElectrodeBridge.js13 symbols
android/electrode-reactnative-bridge/src/androidTest/java/com/walmartlabs/electrode/reactnative/sample/model/Status.java13 symbols

For agents

$ claude mcp add react-native-electrode-bridge \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page