/** * Copyright (c) Meta Platforms, Inc. and 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 { ExecuteMessage, FlipperServer, ServerAddOnControls, deserializeRemoteError, } from 'flipper-common'; type PluginName = string; type Method = string; export const createServerAddOnControls = ( flipperServer: FlipperServer, ): ServerAddOnControls => { const methodHandlers = new Map< PluginName, Map 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; } const catchAllHandler = catchAllHandlers.get(pluginName); catchAllHandler?.(params.method, params.params); }; return { start: (pluginName, details, owner) => flipperServer.exec( 'plugins-server-add-on-start', pluginName, details, 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); }, }; };