Implement receiving messages from add-on on the client

Reviewed By: mweststrate

Differential Revision: D34249101

fbshipit-source-id: 07297b84ed8640e3b41599726ba613b6b4e2b62e
This commit is contained in:
Andrey Goncharov
2022-02-28 03:50:34 -08:00
committed by Facebook GitHub Bot
parent 4067f5bd88
commit b4b9c0ab28
8 changed files with 114 additions and 38 deletions

View File

@@ -8,35 +8,87 @@
*/
import {
ExecuteMessage,
FlipperServer,
ServerAddOnControls,
deserializeRemoteError,
} from 'flipper-common';
export const createServerAddOnControls = (
flipperServer: Pick<FlipperServer, 'exec'>,
): ServerAddOnControls => ({
start: (pluginName, owner) =>
flipperServer.exec('plugins-server-add-on-start', pluginName, owner),
stop: (pluginName, owner) =>
flipperServer.exec('plugins-server-add-on-stop', pluginName, owner),
sendMessage: async (pluginName, method, params) => {
const res = await flipperServer.exec(
'plugins-server-add-on-request-response',
{
method: 'execute',
params: {
method,
api: pluginName,
params,
},
},
);
type PluginName = string;
type Method = string;
if (res.error) {
throw deserializeRemoteError(res.error);
export const createServerAddOnControls = (
flipperServer: FlipperServer,
): ServerAddOnControls => {
const methodHandlers = new Map<
PluginName,
Map<Method, (data: unknown) => void>
>();
const catchAllHandlers = new Map<
PluginName,
(method: string, data: unknown) => void
>();
let subscribed = false;
const subscriptionCb = ({params}: ExecuteMessage) => {
const pluginName = params.api;
const methodHandler = methodHandlers.get(pluginName)?.get(params.method);
if (methodHandler) {
methodHandler(params.params);
return;
}
return res.success;
},
});
const catchAllHandler = catchAllHandlers.get(pluginName);
catchAllHandler?.(params.method, params.params);
};
return {
start: (pluginName, owner) =>
flipperServer.exec('plugins-server-add-on-start', pluginName, owner),
stop: (pluginName, owner) =>
flipperServer.exec('plugins-server-add-on-stop', pluginName, owner),
sendMessage: async (pluginName, method, params) => {
const res = await flipperServer.exec(
'plugins-server-add-on-request-response',
{
method: 'execute',
params: {
method,
api: pluginName,
params,
},
},
);
if (res.error) {
throw deserializeRemoteError(res.error);
}
return res.success;
},
receiveMessage: (pluginName, method, receiver) => {
if (!methodHandlers.has(pluginName)) {
methodHandlers.set(pluginName, new Map());
}
methodHandlers.get(pluginName)!.set(method, receiver);
// Subscribe client/device to messages from flipper server only when the first plugin subscribes to them
if (!subscribed) {
subscribed = true;
flipperServer.on('plugins-server-add-on-message', subscriptionCb);
}
},
receiveAnyMessage: (pluginName, receiver) => {
catchAllHandlers.set(pluginName, receiver);
},
unsubscribePlugin: (pluginName) => {
methodHandlers.delete(pluginName);
catchAllHandlers.delete(pluginName);
},
unsubscribe: () => {
flipperServer.off('plugins-server-add-on-message', subscriptionCb);
},
};
};