Introduce DevicePlugin APIs
Summary: This stack introduces Sandy device plugins, they are quite similar to normal plugins, but, a devicePlugin module is organized as ``` export function supportsDevice(device): boolean export function devicePlugin(devicePluginClient) export function Component ``` Device plugins get access to the device meta data and can subscribe to the `onLogEntry` callback and `onDestroy` lifecycle. They will be able to store state just as normal plugins, but can't send or receive methods, so devicePluginClient is a bit limited. This diff only sets up most of the new data structures, and makes sure everything still compiles and no existing tests fail. To prevent this diff from becoming to big, actually loading, rendering and testing device plugins will be done in next diffs Please take a critical look at the api proposed and the (especially) the public names used :) Reviewed By: passy, nikoant Differential Revision: D22691351 fbshipit-source-id: bdbbd7f86d14b646fc9a693ad19f33583a76f26d
This commit is contained in:
committed by
Facebook GitHub Bot
parent
6083534025
commit
91ed4e31c0
@@ -8,20 +8,29 @@
|
||||
*/
|
||||
|
||||
import {PluginDetails} from 'flipper-plugin-lib';
|
||||
import {FlipperPluginFactory, FlipperPluginComponent} from './Plugin';
|
||||
import {PluginFactory, FlipperPluginComponent} from './Plugin';
|
||||
import {DevicePluginPredicate, DevicePluginFactory} from './DevicePlugin';
|
||||
|
||||
/**
|
||||
* FlipperPluginModule describe the exports that are provided by a typical Flipper Desktop plugin
|
||||
*/
|
||||
export type FlipperPluginModule<
|
||||
Factory extends FlipperPluginFactory<any, any>
|
||||
> = {
|
||||
export type FlipperDevicePluginModule = {
|
||||
/** predicate that determines if this plugin applies to the currently selcted device */
|
||||
supportsDevice: DevicePluginPredicate;
|
||||
/** 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>> = {
|
||||
/** the factory function that initializes a plugin instance */
|
||||
plugin: Factory;
|
||||
/** the component type that can render this plugin */
|
||||
Component: FlipperPluginComponent;
|
||||
// TODO: support device plugins T68738317
|
||||
// devicePlugin: FlipperPluginFactory
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -32,8 +41,9 @@ export type FlipperPluginModule<
|
||||
*/
|
||||
export class SandyPluginDefinition {
|
||||
id: string;
|
||||
module: FlipperPluginModule<any>;
|
||||
module: FlipperPluginModule<any> | FlipperDevicePluginModule;
|
||||
details: PluginDetails;
|
||||
isDevicePlugin: boolean;
|
||||
|
||||
// TODO: Implement T68683476
|
||||
exportPersistedState:
|
||||
@@ -47,13 +57,28 @@ export class SandyPluginDefinition {
|
||||
) => Promise<any /* TODO: StaticPersistedState | undefined */>)
|
||||
| undefined = undefined;
|
||||
|
||||
constructor(details: PluginDetails, module: FlipperPluginModule<any>) {
|
||||
constructor(
|
||||
details: PluginDetails,
|
||||
module: FlipperPluginModule<any> | FlipperDevicePluginModule,
|
||||
);
|
||||
constructor(details: PluginDetails, module: any) {
|
||||
this.id = details.id;
|
||||
this.details = details;
|
||||
if (!module.plugin || typeof module.plugin !== 'function') {
|
||||
throw new Error(
|
||||
`Flipper plugin '${this.id}' should export named function called 'plugin'`,
|
||||
);
|
||||
if (module.supportsDevice) {
|
||||
// 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(
|
||||
@@ -64,6 +89,16 @@ export class SandyPluginDefinition {
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user