diff --git a/desktop/app/src/Client.tsx b/desktop/app/src/Client.tsx index 20dfb92b9..8ea15b399 100644 --- a/desktop/app/src/Client.tsx +++ b/desktop/app/src/Client.tsx @@ -15,9 +15,7 @@ import {Payload, ConnectionStatus} from 'rsocket-types'; import {Flowable, Single} from 'rsocket-flowable'; import {performance} from 'perf_hooks'; import {reportPluginFailures} from './utils/metrics'; -import {notNull} from './utils/typeUtils'; import {default as isProduction} from './utils/isProduction'; -import {registerPlugins} from './reducers/plugins'; import {EventEmitter} from 'events'; import invariant from 'invariant'; import { @@ -39,7 +37,8 @@ import {freeze} from 'immer'; import GK from './fb-stubs/GK'; import {message} from 'antd'; -type Plugins = Array; +type Plugins = Set; +type PluginsArr = Array; export type ClientQuery = { app: string; @@ -149,8 +148,8 @@ export default class Client extends EventEmitter { ) { super(); this.connected.set(!!conn); - this.plugins = plugins ? plugins : []; - this.backgroundPlugins = []; + this.plugins = plugins ? plugins : new Set(); + this.backgroundPlugins = new Set(); this.connection = conn; this.id = id; this.query = query; @@ -184,11 +183,11 @@ export default class Client extends EventEmitter { } supportsPlugin(pluginId: string): boolean { - return this.plugins.includes(pluginId); + return this.plugins.has(pluginId); } isBackgroundPlugin(pluginId: string) { - return this.backgroundPlugins.includes(pluginId); + return this.backgroundPlugins.has(pluginId); } isEnabledPlugin(pluginId: string) { @@ -210,7 +209,7 @@ export default class Client extends EventEmitter { this.plugins.forEach((pluginId) => this.startPluginIfNeeded(this.getPlugin(pluginId)), ); - this.backgroundPlugins = await this.getBackgroundPlugins(); + this.backgroundPlugins = new Set(await this.getBackgroundPlugins()); this.backgroundPlugins.forEach((plugin) => { if (this.shouldConnectAsBackgroundPlugin(plugin)) { this.initPlugin(plugin); @@ -244,7 +243,7 @@ export default class Client extends EventEmitter { 'getPlugins', false, ); - this.plugins = plugins; + this.plugins = new Set(plugins); return plugins; } @@ -313,13 +312,14 @@ export default class Client extends EventEmitter { } // get the supported background plugins - async getBackgroundPlugins(): Promise { + async getBackgroundPlugins(): Promise { if (this.sdkVersion < 4) { return []; } - return this.rawCall<{plugins: Plugins}>('getBackgroundPlugins', false).then( - (data) => data.plugins, - ); + return this.rawCall<{plugins: PluginsArr}>( + 'getBackgroundPlugins', + false, + ).then((data) => data.plugins); } // get the plugins, and update the UI @@ -330,11 +330,11 @@ export default class Client extends EventEmitter { this.startPluginIfNeeded(this.getPlugin(pluginId)), ); const newBackgroundPlugins = await this.getBackgroundPlugins(); - this.backgroundPlugins = newBackgroundPlugins; + this.backgroundPlugins = new Set(newBackgroundPlugins); // diff the background plugin list, disconnect old, connect new ones oldBackgroundPlugins.forEach((plugin) => { if ( - !newBackgroundPlugins.includes(plugin) && + !this.backgroundPlugins.has(plugin) && this.store .getState() .connections.enabledPlugins[this.query.app]?.includes(plugin) @@ -344,7 +344,7 @@ export default class Client extends EventEmitter { }); newBackgroundPlugins.forEach((plugin) => { if ( - !oldBackgroundPlugins.includes(plugin) && + !oldBackgroundPlugins.has(plugin) && this.shouldConnectAsBackgroundPlugin(plugin) ) { this.initPlugin(plugin); diff --git a/desktop/app/src/PluginContainer.tsx b/desktop/app/src/PluginContainer.tsx index b38956dee..b6f9cec74 100644 --- a/desktop/app/src/PluginContainer.tsx +++ b/desktop/app/src/PluginContainer.tsx @@ -417,10 +417,7 @@ class PluginContainer extends PureComponent { selectPlugin: (pluginID: string, deepLinkPayload: unknown) => { const {target} = this.props; // check if plugin will be available - if ( - target instanceof Client && - target.plugins.some((p) => p === pluginID) - ) { + if (target instanceof Client && target.plugins.has(pluginID)) { this.props.selectPlugin({ selectedPlugin: pluginID, deepLinkPayload, diff --git a/desktop/app/src/__tests__/createMockFlipperWithPlugin.node.tsx b/desktop/app/src/__tests__/createMockFlipperWithPlugin.node.tsx index 1b845e319..02f935c59 100644 --- a/desktop/app/src/__tests__/createMockFlipperWithPlugin.node.tsx +++ b/desktop/app/src/__tests__/createMockFlipperWithPlugin.node.tsx @@ -47,7 +47,7 @@ test('can create a Fake flipper', async () => { expect(device).toBeTruthy(); expect(store).toBeTruthy(); expect(sendMessage).toBeTruthy(); - expect(client.plugins.includes(TestPlugin.id)).toBe(true); + expect(client.plugins.has(TestPlugin.id)).toBe(true); expect(store.getState().connections).toMatchSnapshot(); expect(store.getState().plugins).toMatchSnapshot(); sendMessage('inc', {}); @@ -73,7 +73,7 @@ test('can create a Fake flipper with legacy wrapper', async () => { expect(device).toBeTruthy(); expect(store).toBeTruthy(); expect(sendMessage).toBeTruthy(); - expect(client.plugins.includes(TestPlugin.id)).toBe(true); + expect(client.plugins.has(TestPlugin.id)).toBe(true); expect(client.sandyPluginStates.has(TestPlugin.id)).toBe(true); const state = store.getState(); expect(state.connections).toMatchSnapshot(); diff --git a/desktop/app/src/chrome/plugin-manager/PluginDebugger.tsx b/desktop/app/src/chrome/plugin-manager/PluginDebugger.tsx index 8c8e5b6d6..d9015c07b 100644 --- a/desktop/app/src/chrome/plugin-manager/PluginDebugger.tsx +++ b/desktop/app/src/chrome/plugin-manager/PluginDebugger.tsx @@ -128,7 +128,7 @@ class PluginDebugger extends Component { getSupportedClients(id: string): string { return this.props.clients .reduce((acc: Array, cv: Client) => { - if (cv.plugins.includes(id)) { + if (cv.plugins.has(id)) { acc.push(cv.query.app); } return acc; diff --git a/desktop/app/src/reducers/supportForm.tsx b/desktop/app/src/reducers/supportForm.tsx index fdd6e27ee..80ede5bdb 100644 --- a/desktop/app/src/reducers/supportForm.tsx +++ b/desktop/app/src/reducers/supportForm.tsx @@ -132,7 +132,7 @@ export class Group { enabledPlugins != null && enabledPlugins.includes(requiredPlugin); if ( selectedClient && - selectedClient.plugins.includes(requiredPlugin) && + selectedClient.plugins.has(requiredPlugin) && !requiredPluginEnabled ) { const plugin = @@ -146,7 +146,7 @@ export class Group { ); } else if ( !selectedClient || - !selectedClient.plugins.includes(requiredPlugin) + !selectedClient.plugins.has(requiredPlugin) ) { unsupportedPlugins.push(requiredPlugin); } diff --git a/desktop/app/src/sandy-chrome/appinspect/__tests__/PluginList.spec.tsx b/desktop/app/src/sandy-chrome/appinspect/__tests__/PluginList.spec.tsx index e02fa43a0..7c990b94c 100644 --- a/desktop/app/src/sandy-chrome/appinspect/__tests__/PluginList.spec.tsx +++ b/desktop/app/src/sandy-chrome/appinspect/__tests__/PluginList.spec.tsx @@ -224,11 +224,11 @@ describe('basic findBestDevice with metro present', () => { ); // ok, this is a little hackish - flipper.client.plugins = [ + flipper.client.plugins = new Set([ 'plugin1', 'plugin2', 'supportedUninstalledPlugin', - ]; + ]); let state = flipper.store.getState(); const pluginLists = computePluginLists(state.connections, state.plugins); diff --git a/desktop/app/src/server.tsx b/desktop/app/src/server.tsx index 92f9e9375..57f081c4b 100644 --- a/desktop/app/src/server.tsx +++ b/desktop/app/src/server.tsx @@ -555,9 +555,9 @@ class Server extends EventEmitter { client.init().then(() => { console.debug( - `Device client initialised: ${id}. Supported plugins: ${client.plugins.join( - ', ', - )}`, + `Device client initialised: ${id}. Supported plugins: ${Array.from( + client.plugins, + ).join(', ')}`, 'server', ); diff --git a/desktop/app/src/test-utils/MockFlipper.tsx b/desktop/app/src/test-utils/MockFlipper.tsx index 3b76b089a..d8e48e864 100644 --- a/desktop/app/src/test-utils/MockFlipper.tsx +++ b/desktop/app/src/test-utils/MockFlipper.tsx @@ -181,7 +181,7 @@ export default class MockFlipper { device.isArchived ? null : createStubConnection(), this._logger, this._store, - supportedPlugins, + new Set(supportedPlugins), device, ); // yikes diff --git a/desktop/app/src/utils/__tests__/exportData.node.tsx b/desktop/app/src/utils/__tests__/exportData.node.tsx index 4219a4944..1ae5a803a 100644 --- a/desktop/app/src/utils/__tests__/exportData.node.tsx +++ b/desktop/app/src/utils/__tests__/exportData.node.tsx @@ -718,7 +718,7 @@ test('test determinePluginsToProcess for mutilple clients having plugins present null, logger, mockStore, - ['TestPlugin', 'TestDevicePlugin'], + new Set(['TestPlugin', 'TestDevicePlugin']), device1, ); const client2 = new Client( @@ -732,7 +732,7 @@ test('test determinePluginsToProcess for mutilple clients having plugins present null, logger, mockStore, - ['TestDevicePlugin'], + new Set(['TestDevicePlugin']), device1, ); const client3 = new Client( @@ -746,7 +746,7 @@ test('test determinePluginsToProcess for mutilple clients having plugins present null, logger, mockStore, - ['TestPlugin', 'TestDevicePlugin'], + new Set(['TestPlugin', 'TestDevicePlugin']), device1, ); const plugins: PluginsState = { @@ -807,7 +807,7 @@ test('test determinePluginsToProcess for no selected plugin present in any clien null, logger, mockStore, - ['TestPlugin', 'TestDevicePlugin'], + new Set(['TestPlugin', 'TestDevicePlugin']), device1, ); const client2 = new Client( @@ -821,7 +821,7 @@ test('test determinePluginsToProcess for no selected plugin present in any clien null, logger, mockStore, - ['TestDevicePlugin'], + new Set(['TestDevicePlugin']), device1, ); const plugins: PluginsState = { @@ -863,7 +863,7 @@ test('test determinePluginsToProcess for multiple clients on same device', async null, logger, mockStore, - ['TestPlugin', 'TestDevicePlugin'], + new Set(['TestPlugin', 'TestDevicePlugin']), device1, ); const client2 = new Client( @@ -877,7 +877,7 @@ test('test determinePluginsToProcess for multiple clients on same device', async null, logger, mockStore, - ['TestDevicePlugin'], + new Set(['TestDevicePlugin']), device1, ); const plugins: PluginsState = { @@ -925,7 +925,7 @@ test('test determinePluginsToProcess for multiple clients on different device', null, logger, mockStore, - ['TestPlugin', 'TestDevicePlugin'], + new Set(['TestPlugin', 'TestDevicePlugin']), device1, ); const client2Device1 = new Client( @@ -939,7 +939,7 @@ test('test determinePluginsToProcess for multiple clients on different device', null, logger, mockStore, - ['TestDevicePlugin'], + new Set(['TestDevicePlugin']), device1, ); const client1Device2 = new Client( @@ -953,7 +953,7 @@ test('test determinePluginsToProcess for multiple clients on different device', null, logger, mockStore, - ['TestPlugin', 'TestDevicePlugin'], + new Set(['TestPlugin', 'TestDevicePlugin']), device1, ); const client2Device2 = new Client( @@ -967,7 +967,7 @@ test('test determinePluginsToProcess for multiple clients on different device', null, logger, mockStore, - ['TestDevicePlugin'], + new Set(['TestDevicePlugin']), device1, ); const plugins: PluginsState = { @@ -1039,7 +1039,7 @@ test('test determinePluginsToProcess to ignore archived clients', async () => { null, logger, mockStore, - ['TestPlugin', 'TestDevicePlugin'], + new Set(['TestPlugin', 'TestDevicePlugin']), archivedDevice, ); const archivedClient = new Client( @@ -1053,7 +1053,7 @@ test('test determinePluginsToProcess to ignore archived clients', async () => { null, logger, mockStore, - ['TestPlugin', 'TestDevicePlugin'], + new Set(['TestPlugin', 'TestDevicePlugin']), archivedDevice, ); const plugins: PluginsState = { @@ -1303,7 +1303,7 @@ test('Sandy plugins are imported properly', async () => { const client2 = store.getState().connections.clients[1]; expect(client2).not.toBeFalsy(); expect(client2).not.toBe(client); - expect(client2.plugins).toEqual([TestPlugin.id]); + expect(Array.from(client2.plugins)).toEqual([TestPlugin.id]); expect(client.sandyPluginStates.get(TestPlugin.id)!.exportStateSync()) .toMatchInlineSnapshot(` diff --git a/desktop/app/src/utils/exportData.tsx b/desktop/app/src/utils/exportData.tsx index 8f5156f52..1f503db2e 100644 --- a/desktop/app/src/utils/exportData.tsx +++ b/desktop/app/src/utils/exportData.tsx @@ -619,11 +619,13 @@ export function determinePluginsToProcess( } const selectedFilteredPlugins = client ? selectedPlugins.length > 0 - ? client.plugins.filter((plugin) => selectedPlugins.includes(plugin)) + ? Array.from(client.plugins).filter((plugin) => + selectedPlugins.includes(plugin), + ) : client.plugins : []; for (const plugin of selectedFilteredPlugins) { - if (!client.plugins.includes(plugin)) { + if (!client.plugins.has(plugin)) { // Ignore clients which doesn't support the selected plugins. continue; } @@ -827,7 +829,7 @@ export function importDataToStore(source: string, data: string, store: Store) { clients.forEach((client: {id: string; query: ClientQuery}) => { const sandyPluginStates = json.pluginStates2[client.id] || {}; - const clientPlugins: Array = [ + const clientPlugins: Set = new Set([ ...keys .filter((key) => { const plugin = deconstructPluginKey(key); @@ -835,7 +837,7 @@ export function importDataToStore(source: string, data: string, store: Store) { }) .map((pluginKey) => deconstructPluginKey(pluginKey).pluginName), ...Object.keys(sandyPluginStates), - ]; + ]); store.dispatch({ type: 'NEW_CLIENT', payload: new Client( diff --git a/desktop/app/src/utils/pluginUtils.tsx b/desktop/app/src/utils/pluginUtils.tsx index b4eacbfa4..48c41736f 100644 --- a/desktop/app/src/utils/pluginUtils.tsx +++ b/desktop/app/src/utils/pluginUtils.tsx @@ -352,9 +352,7 @@ function getFavoritePlugins( return []; } // for *imported* devices, all stored plugins are enabled - return allPlugins.filter( - (plugin) => client.plugins.indexOf(plugin.id) !== -1, - ); + return allPlugins.filter((plugin) => client.plugins.has(plugin.id)); } if (!enabledPlugins || !enabledPlugins.length) { return returnFavoredPlugins ? [] : allPlugins; diff --git a/desktop/app/tsconfig.json b/desktop/app/tsconfig.json index ca8ea7e67..f49ae1151 100644 --- a/desktop/app/tsconfig.json +++ b/desktop/app/tsconfig.json @@ -27,6 +27,5 @@ "**/node_modules/", "**/__tests__/", "**/lib/", - "**/fb/" ] } diff --git a/desktop/flipper-plugin/src/plugin/Plugin.tsx b/desktop/flipper-plugin/src/plugin/Plugin.tsx index c1003918b..07ad1a36e 100644 --- a/desktop/flipper-plugin/src/plugin/Plugin.tsx +++ b/desktop/flipper-plugin/src/plugin/Plugin.tsx @@ -108,7 +108,7 @@ export interface RealFlipperClient { device_id: string; }; deviceSync: RealFlipperDevice; - plugins: string[]; + plugins: Set; isBackgroundPlugin(pluginId: string): boolean; initPlugin(pluginId: string): void; deinitPlugin(pluginId: string): void; diff --git a/desktop/flipper-plugin/src/test-utils/test-utils.tsx b/desktop/flipper-plugin/src/test-utils/test-utils.tsx index df9968289..ab28d76de 100644 --- a/desktop/flipper-plugin/src/test-utils/test-utils.tsx +++ b/desktop/flipper-plugin/src/test-utils/test-utils.tsx @@ -196,7 +196,7 @@ export function startPlugin>( const deviceName = 'TestDevice'; const fakeFlipperClient: RealFlipperClient = { id: `${appName}#${testDevice.os}#${deviceName}#${testDevice.serial}`, - plugins: [definition.id], + plugins: new Set([definition.id]), query: { app: appName, device: deviceName,