Copy RenderHost, FlipperLib initialization, device definition to flipper-frontend-core

Reviewed By: passy

Differential Revision: D36129746

fbshipit-source-id: 15e32b9482d7fe3a24567d2e6bc087095b98226e
This commit is contained in:
Andrey Goncharov
2022-05-10 05:13:24 -07:00
committed by Facebook GitHub Bot
parent db49673d8a
commit f0b5e7cadb
10 changed files with 1023 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
/**
* 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<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;
}
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);
},
};
};

View File

@@ -0,0 +1,26 @@
/**
* 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 {PluginDetails} from 'flipper-common';
import semver from 'semver';
import {getRenderHostInstance} from '../RenderHost';
export function isPluginCompatible(
plugin: PluginDetails,
flipperVersion: string,
) {
return (
getRenderHostInstance().GK('flipper_disable_plugin_compatibility_checks') ||
flipperVersion === '0.0.0' ||
!plugin.engines?.flipper ||
semver.lte(plugin.engines?.flipper, flipperVersion)
);
}
export default isPluginCompatible;

View File

@@ -0,0 +1,54 @@
/**
* 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 {ConcretePluginDetails} from 'flipper-common';
import semver from 'semver';
import isPluginCompatible from './isPluginCompatible';
export function isPluginVersionMoreRecent(
versionDetails: ConcretePluginDetails,
otherVersionDetails: ConcretePluginDetails,
flipperVersion: string,
) {
const isPlugin1Compatible = isPluginCompatible(
versionDetails,
flipperVersion,
);
const isPlugin2Compatible = isPluginCompatible(
otherVersionDetails,
flipperVersion,
);
// prefer compatible plugins
if (isPlugin1Compatible && !isPlugin2Compatible) return true;
if (!isPlugin1Compatible && isPlugin2Compatible) return false;
// prefer plugins with greater version
if (semver.gt(versionDetails.version, otherVersionDetails.version)) {
return true;
}
if (
semver.eq(versionDetails.version, otherVersionDetails.version) &&
versionDetails.isBundled
) {
// prefer bundled versions
return true;
}
if (
semver.eq(versionDetails.version, otherVersionDetails.version) &&
versionDetails.isActivatable &&
!otherVersionDetails.isActivatable
) {
// prefer locally available versions to the versions available remotely on marketplace
return true;
}
return false;
}
export default isPluginVersionMoreRecent;

View File

@@ -0,0 +1,27 @@
/**
* 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
*/
export function getPluginKey(
selectedAppId: string | null | undefined,
baseDevice: {serial: string} | null | undefined,
pluginID: string,
): string {
if (selectedAppId) {
return `${selectedAppId}#${pluginID}`;
}
if (baseDevice) {
// If selected App is not defined, then the plugin is a device plugin
return `${baseDevice.serial}#${pluginID}`;
}
return `unknown#${pluginID}`;
}
export const pluginKey = (serial: string, pluginName: string): string => {
return `${serial}#${pluginName}`;
};