Split flipper-plugin package
Summary: flipper-server-companion depends on flipper-plugin. flipper-plugin includes dependencies that run only in a browser. Splitting flipper-plugin into core and browser packages helps to avoid including browser-only dependencies into flipper-server bundle. As a result, bundle size could be cut in half. Subsequently, RSS usage drops as there is twice as less code to process for V8. Note: it currently breaks external flipper-data-source package. It will be restored in subsequent diffs Reviewed By: lblasa Differential Revision: D38658285 fbshipit-source-id: 751b11fa9f3a2d938ce166687b8310ba8b059dee
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2090120cda
commit
97b8b8a1c4
139
desktop/flipper-plugin-core/src/plugin/SandyPluginDefinition.tsx
Normal file
139
desktop/flipper-plugin-core/src/plugin/SandyPluginDefinition.tsx
Normal file
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* 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 {ActivatablePluginDetails} from 'flipper-common';
|
||||
import {PluginFactory, FlipperPluginComponent} from './Plugin';
|
||||
import {DevicePluginPredicate, DevicePluginFactory} from './DevicePlugin';
|
||||
|
||||
export type FlipperPluginAPI<T extends (...args: any[]) => object> = (
|
||||
pluginInstance: ReturnType<T>,
|
||||
) => object;
|
||||
|
||||
export type FlipperPluginInstance<T extends (...args: any[]) => object> =
|
||||
Parameters<FlipperPluginAPI<T>>[0];
|
||||
|
||||
/**
|
||||
* FlipperPluginModule describe the exports that are provided by a typical Flipper Desktop plugin
|
||||
*/
|
||||
export type FlipperDevicePluginModule = {
|
||||
/** predicate that determines if this plugin applies to the currently selcted device */
|
||||
supportsDevice?: DevicePluginPredicate; // TODO T84453692: remove this function after some transition period in favor of BaseDevice.supportsPlugin.
|
||||
/** the factory function that exposes plugin API over the wire */
|
||||
API?: FlipperPluginAPI<DevicePluginFactory>;
|
||||
/** the factory function that initializes a plugin instance */
|
||||
devicePlugin: DevicePluginFactory;
|
||||
/** the component type that can render this plugin */
|
||||
Component: FlipperPluginComponent;
|
||||
};
|
||||
|
||||
/**
|
||||
* FlipperPluginModule describe the exports that are provided by a typical Flipper Desktop plugin
|
||||
*/
|
||||
export type FlipperPluginModule<
|
||||
Factory extends PluginFactory<any, any, any, any>,
|
||||
> = {
|
||||
/** the factory function that exposes plugin API over the wire */
|
||||
API?: FlipperPluginAPI<Factory>;
|
||||
/** the factory function that initializes a plugin instance */
|
||||
plugin: Factory;
|
||||
/** the component type that can render this plugin */
|
||||
Component: FlipperPluginComponent;
|
||||
};
|
||||
|
||||
/**
|
||||
* A sandy plugin definition represents a loaded plugin definition, storing two things:
|
||||
* the loaded JS module, and the meta data (typically coming from package.json).
|
||||
*
|
||||
* Also delegates some of the standard plugin functionality to have a similar public static api as FlipperPlugin
|
||||
*/
|
||||
export class SandyPluginDefinition {
|
||||
id: string;
|
||||
module: FlipperPluginModule<any> | FlipperDevicePluginModule;
|
||||
details: ActivatablePluginDetails;
|
||||
isDevicePlugin: boolean;
|
||||
|
||||
constructor(
|
||||
details: ActivatablePluginDetails,
|
||||
module: FlipperPluginModule<any> | FlipperDevicePluginModule,
|
||||
);
|
||||
constructor(details: ActivatablePluginDetails, module: any) {
|
||||
this.id = details.id;
|
||||
this.details = details;
|
||||
if (
|
||||
details.pluginType === 'device' ||
|
||||
module.supportsDevice ||
|
||||
module.devicePlugin
|
||||
) {
|
||||
// device plugin
|
||||
this.isDevicePlugin = true;
|
||||
if (!module.devicePlugin || typeof module.devicePlugin !== 'function') {
|
||||
throw new Error(
|
||||
`Flipper device plugin '${this.id}' should export named function called 'devicePlugin'`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.isDevicePlugin = false;
|
||||
if (!module.plugin || typeof module.plugin !== 'function') {
|
||||
throw new Error(
|
||||
`Flipper plugin '${this.id}' should export named function called 'plugin'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!module.Component || typeof module.Component !== 'function') {
|
||||
throw new Error(
|
||||
`Flipper plugin '${this.id}' should export named function called 'Component'`,
|
||||
);
|
||||
}
|
||||
this.module = module;
|
||||
this.module.Component.displayName = `FlipperPlugin(${this.id})`;
|
||||
}
|
||||
|
||||
asDevicePluginModule(): FlipperDevicePluginModule {
|
||||
if (!this.isDevicePlugin) throw new Error('Not a device plugin');
|
||||
return this.module as FlipperDevicePluginModule;
|
||||
}
|
||||
|
||||
asPluginModule(): FlipperPluginModule<any> {
|
||||
if (this.isDevicePlugin) throw new Error('Not an application plugin');
|
||||
return this.module as FlipperPluginModule<any>;
|
||||
}
|
||||
|
||||
get packageName() {
|
||||
return this.details.name;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return this.details.title;
|
||||
}
|
||||
|
||||
get icon() {
|
||||
return this.details.icon;
|
||||
}
|
||||
|
||||
get category() {
|
||||
return this.details.category;
|
||||
}
|
||||
|
||||
get gatekeeper() {
|
||||
return this.details.gatekeeper;
|
||||
}
|
||||
|
||||
get version() {
|
||||
return this.details.version;
|
||||
}
|
||||
|
||||
get isBundled() {
|
||||
return this.details.isBundled;
|
||||
}
|
||||
|
||||
get keyboardActions() {
|
||||
// TODO: T68882551 support keyboard actions
|
||||
return [];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user