Implement JS flipper client
Summary: Standardize WS implementation for JS environments. Why do we need a separate server implementation for browsers? Browser targets cannot authenticate via the default certificate exchange flow. We need a dedicated client for them that works over an insecure channel (without the cert exchange). Major changes: 1. Renamed `flipper-js-client-sdk` to `js-flipper` for consistency with `react-native-flipper` 2. Updated `js-flipper` implementation to match our other existing clients Documentation will be updated in a separate subsequent PR. https://fb.quip.com/2mboA0xbgoxl Reviewed By: mweststrate Differential Revision: D31688105 fbshipit-source-id: 418aa80e0fd86361c089cf54b0d44a8b4f748efa
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2be631ea4d
commit
9a47f41056
74
js/js-flipper/src/connection.ts
Normal file
74
js/js-flipper/src/connection.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {FlipperErrorMessage, FlipperMessageBus} from './message';
|
||||
import {FlipperPluginConnection, FlipperPluginReceiver} from './plugin';
|
||||
import {FlipperResponder} from './responder';
|
||||
import {isPromise, safeJSONStringify} from './util';
|
||||
|
||||
type FlipperReceiver = (data: unknown, responder: FlipperResponder) => void;
|
||||
|
||||
export class FlipperConnection implements FlipperPluginConnection {
|
||||
pluginId: string;
|
||||
private client: FlipperMessageBus;
|
||||
private subscriptions: Map<string, FlipperReceiver> = new Map();
|
||||
|
||||
constructor(pluginId: string, client: FlipperMessageBus) {
|
||||
this.pluginId = pluginId;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
send(method: string, params?: unknown) {
|
||||
this.client.sendData({
|
||||
method: 'execute',
|
||||
params: {
|
||||
api: this.pluginId,
|
||||
method,
|
||||
params,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
receive(method: string, receiver: FlipperPluginReceiver) {
|
||||
const wrappedReceiver: FlipperReceiver = (data, responder) => {
|
||||
const handleError = (e: unknown) => {
|
||||
const errorMessage: FlipperErrorMessage =
|
||||
e instanceof Error
|
||||
? {name: e.name, message: e.message, stacktrace: e.stack}
|
||||
: {name: 'Unknown', message: safeJSONStringify(e)};
|
||||
responder.error(errorMessage);
|
||||
};
|
||||
try {
|
||||
const response = receiver(data);
|
||||
if (isPromise(response)) {
|
||||
response.then((data) => responder.success(data)).catch(handleError);
|
||||
return;
|
||||
}
|
||||
responder.success(response);
|
||||
} catch (e) {
|
||||
handleError(e);
|
||||
}
|
||||
};
|
||||
this.subscriptions.set(method, wrappedReceiver);
|
||||
}
|
||||
|
||||
call(method: string, params: unknown, responder: FlipperResponder) {
|
||||
const receiver = this.subscriptions.get(method);
|
||||
if (receiver == null) {
|
||||
const errorMessage = `Receiver ${method} not found.`;
|
||||
responder.error({message: errorMessage});
|
||||
return;
|
||||
}
|
||||
receiver.call(receiver, params, responder);
|
||||
}
|
||||
|
||||
hasReceiver(method: string): boolean {
|
||||
return this.subscriptions.has(method);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user