Use AbstractPluginInitializer from flipper-frontend-core in flipper-ui-core

Summary: See D37139129

Reviewed By: passy

Differential Revision: D37238571

fbshipit-source-id: 39d6bb87d6beacc793ef5acd71097fcc4e82969d
This commit is contained in:
Andrey Goncharov
2022-06-20 12:18:40 -07:00
committed by Facebook GitHub Bot
parent 8768405e80
commit 115a4b7997
3 changed files with 76 additions and 101 deletions

View File

@@ -29,15 +29,18 @@ export abstract class AbstractPluginInitializer {
protected gatekeepedPlugins: Array<ActivatablePluginDetails> = []; protected gatekeepedPlugins: Array<ActivatablePluginDetails> = [];
protected disabledPlugins: Array<ActivatablePluginDetails> = []; protected disabledPlugins: Array<ActivatablePluginDetails> = [];
protected failedPlugins: Array<[ActivatablePluginDetails, string]> = []; protected failedPlugins: Array<[ActivatablePluginDetails, string]> = [];
protected bundledPlugins: Array<BundledPluginDetails> = [];
protected _loadedPlugins: _SandyPluginDefinition[] = []; protected loadedPlugins: Array<
BundledPluginDetails | InstalledPluginDetails
> = [];
protected _initialPlugins: _SandyPluginDefinition[] = [];
async init() { async init() {
this._loadedPlugins = await this._init(); this._initialPlugins = await this._init();
} }
get loadedPlugins(): ReadonlyArray<_SandyPluginDefinition> { get initialPlugins(): ReadonlyArray<_SandyPluginDefinition> {
return this._loadedPlugins; return this._initialPlugins;
} }
protected async _init(): Promise<_SandyPluginDefinition[]> { protected async _init(): Promise<_SandyPluginDefinition[]> {
@@ -69,6 +72,7 @@ export abstract class AbstractPluginInitializer {
uninstalledPluginNames: Set<string>, uninstalledPluginNames: Set<string>,
): Promise<(BundledPluginDetails | InstalledPluginDetails)[]> { ): Promise<(BundledPluginDetails | InstalledPluginDetails)[]> {
const bundledPlugins = await getBundledPlugins(); const bundledPlugins = await getBundledPlugins();
this.bundledPlugins = bundledPlugins;
const allLocalVersions = [ const allLocalVersions = [
...bundledPlugins, ...bundledPlugins,
@@ -85,6 +89,7 @@ export abstract class AbstractPluginInitializer {
allLocalVersions, allLocalVersions,
flipperVersion, flipperVersion,
); );
this.loadedPlugins = loadedPlugins;
const pluginsToLoad = loadedPlugins const pluginsToLoad = loadedPlugins
.map(reportVersion) .map(reportVersion)

View File

@@ -64,7 +64,7 @@ export function attachSocketServer(
flipperServerCompanion = new FlipperServerCompanion( flipperServerCompanion = new FlipperServerCompanion(
flipperServer, flipperServer,
getLogger(), getLogger(),
companionEnv.pluginInitializer.loadedPlugins, companionEnv.pluginInitializer.initialPlugins,
); );
} }
} }

View File

@@ -30,12 +30,7 @@ import {
pluginsInitialized, pluginsInitialized,
} from '../reducers/plugins'; } from '../reducers/plugins';
import {FlipperBasePlugin} from '../plugin'; import {FlipperBasePlugin} from '../plugin';
import {notNull} from '../utils/typeUtils'; import {ActivatablePluginDetails, ConcretePluginDetails} from 'flipper-common';
import {
ActivatablePluginDetails,
BundledPluginDetails,
ConcretePluginDetails,
} from 'flipper-common';
import {reportUsage} from 'flipper-common'; import {reportUsage} from 'flipper-common';
import * as FlipperPluginSDK from 'flipper-plugin'; import * as FlipperPluginSDK from 'flipper-plugin';
import {_SandyPluginDefinition} from 'flipper-plugin'; import {_SandyPluginDefinition} from 'flipper-plugin';
@@ -48,61 +43,23 @@ import {isDevicePluginDefinition} from '../utils/pluginUtils';
import isPluginCompatible from '../utils/isPluginCompatible'; import isPluginCompatible from '../utils/isPluginCompatible';
import isPluginVersionMoreRecent from '../utils/isPluginVersionMoreRecent'; import isPluginVersionMoreRecent from '../utils/isPluginVersionMoreRecent';
import {createSandyPluginWrapper} from '../utils/createSandyPluginWrapper'; import {createSandyPluginWrapper} from '../utils/createSandyPluginWrapper';
import {getRenderHostInstance, setGlobalObject} from 'flipper-frontend-core'; import {
import pMap from 'p-map'; AbstractPluginInitializer,
getRenderHostInstance,
setGlobalObject,
} from 'flipper-frontend-core';
import * as deprecatedExports from '../deprecated-exports'; import * as deprecatedExports from '../deprecated-exports';
import {getAppVersion} from '../utils/info';
let defaultPluginsIndex: any = null; class UIPluginInitializer extends AbstractPluginInitializer {
constructor(private readonly store: Store) {
super();
}
export default async (store: Store, _logger: Logger) => { async init() {
setGlobalObject({ await super.init();
React,
ReactDOM,
ReactDOMClient,
ReactIs,
Flipper: deprecatedExports,
FlipperPlugin: FlipperPluginSDK,
Immer,
antd,
emotion_styled,
antdesign_icons,
});
const gatekeepedPlugins: Array<ActivatablePluginDetails> = []; const classicPlugins = this._initialPlugins.filter(
const disabledPlugins: Array<ActivatablePluginDetails> = [];
const failedPlugins: Array<[ActivatablePluginDetails, string]> = [];
defaultPluginsIndex = getRenderHostInstance().loadDefaultPlugins();
const marketplacePlugins = selectCompatibleMarketplaceVersions(
store.getState().plugins.marketplacePlugins,
);
store.dispatch(registerMarketplacePlugins(marketplacePlugins));
const uninstalledPluginNames =
store.getState().plugins.uninstalledPluginNames;
const bundledPlugins = await getBundledPlugins();
const allLocalVersions = [
...bundledPlugins,
...(await getDynamicPlugins()),
].filter((p) => !uninstalledPluginNames.has(p.name));
const loadedPlugins =
getLatestCompatibleVersionOfEachPlugin(allLocalVersions);
const pluginsToLoad = loadedPlugins
.map(reportVersion)
.filter(checkDisabled(disabledPlugins))
.filter(checkGK(gatekeepedPlugins));
const loader = createRequirePluginFunction(failedPlugins);
const initialPlugins: PluginDefinition[] = (
await pMap(pluginsToLoad, loader)
).filter(notNull);
const classicPlugins = initialPlugins.filter(
(p) => !isSandyPlugin(p.details), (p) => !isSandyPlugin(p.details),
); );
if ( if (
@@ -119,26 +76,54 @@ export default async (store: Store, _logger: Logger) => {
); );
} }
store.dispatch(registerBundledPlugins(bundledPlugins)); this.store.dispatch(registerBundledPlugins(this.bundledPlugins));
store.dispatch(registerLoadedPlugins(loadedPlugins)); this.store.dispatch(registerLoadedPlugins(this.loadedPlugins));
store.dispatch(addGatekeepedPlugins(gatekeepedPlugins)); this.store.dispatch(addGatekeepedPlugins(this.gatekeepedPlugins));
store.dispatch(addDisabledPlugins(disabledPlugins)); this.store.dispatch(addDisabledPlugins(this.disabledPlugins));
store.dispatch(addFailedPlugins(failedPlugins)); this.store.dispatch(addFailedPlugins(this.failedPlugins));
store.dispatch(registerPlugins(initialPlugins)); this.store.dispatch(registerPlugins(this._initialPlugins));
store.dispatch(pluginsInitialized()); this.store.dispatch(pluginsInitialized());
};
function reportVersion(pluginDetails: ActivatablePluginDetails) {
reportUsage(
'plugin:version',
{
version: pluginDetails.version,
},
pluginDetails.id,
);
return pluginDetails;
} }
protected async getFlipperVersion() {
return getAppVersion();
}
public requirePluginImpl(pluginDetails: ActivatablePluginDetails) {
return requirePluginInternal(this.defaultPluginsIndex, pluginDetails);
}
protected loadMarketplacePlugins() {
const marketplacePlugins = selectCompatibleMarketplaceVersions(
this.store.getState().plugins.marketplacePlugins,
);
this.store.dispatch(registerMarketplacePlugins(marketplacePlugins));
}
protected loadUninstalledPluginNames() {
return this.store.getState().plugins.uninstalledPluginNames;
}
}
let uiPluginInitializer: UIPluginInitializer;
export default async (store: Store, _logger: Logger) => {
setGlobalObject({
React,
ReactDOM,
ReactDOMClient,
ReactIs,
Flipper: deprecatedExports,
FlipperPlugin: FlipperPluginSDK,
Immer,
antd,
emotion_styled,
antdesign_icons,
});
uiPluginInitializer = new UIPluginInitializer(store);
await uiPluginInitializer.init();
};
export function getLatestCompatibleVersionOfEachPlugin< export function getLatestCompatibleVersionOfEachPlugin<
T extends ConcretePluginDetails, T extends ConcretePluginDetails,
>(plugins: T[]): T[] { >(plugins: T[]): T[] {
@@ -154,22 +139,6 @@ export function getLatestCompatibleVersionOfEachPlugin<
return Array.from(latestCompatibleVersions.values()); return Array.from(latestCompatibleVersions.values());
} }
async function getBundledPlugins(): Promise<Array<BundledPluginDetails>> {
if (getRenderHostInstance().serverConfig.env.NODE_ENV === 'test') {
return [];
}
try {
// defaultPlugins that are included in the Flipper distributive.
// List of default bundled plugins is written at build time to defaultPlugins/bundled.json.
return await getRenderHostInstance().flipperServer!.exec(
'plugins-get-bundled-plugins',
);
} catch (e) {
console.error('Failed to load list of bundled plugins', e);
return [];
}
}
export async function getDynamicPlugins(): Promise<InstalledPluginDetails[]> { export async function getDynamicPlugins(): Promise<InstalledPluginDetails[]> {
try { try {
return await getRenderHostInstance().flipperServer!.exec( return await getRenderHostInstance().flipperServer!.exec(
@@ -280,7 +249,7 @@ export const requirePlugin = (
pluginDetails.id, pluginDetails.id,
); );
return tryCatchReportPluginFailuresAsync( return tryCatchReportPluginFailuresAsync(
() => requirePluginInternal(pluginDetails), () => uiPluginInitializer.requirePluginImpl(pluginDetails),
'plugin:load', 'plugin:load',
pluginDetails.id, pluginDetails.id,
); );
@@ -291,6 +260,7 @@ const isSandyPlugin = (pluginDetails: ActivatablePluginDetails) => {
}; };
const requirePluginInternal = async ( const requirePluginInternal = async (
defaultPluginsIndex: any,
pluginDetails: ActivatablePluginDetails, pluginDetails: ActivatablePluginDetails,
): Promise<PluginDefinition> => { ): Promise<PluginDefinition> => {
let plugin = pluginDetails.isBundled let plugin = pluginDetails.isBundled