Summary:
*Stack summary*: this stack refactors plugin management actions to perform them in a dispatcher rather than in the root reducer (store.tsx) as all of these actions has side effects. To do that, we store requested plugin management actions (install/update/uninstall, star/unstar) in a queue which is then handled by pluginManager dispatcher. This dispatcher then dispatches all required state updates.
*Diff summary*: refactored Flipper mocking helpers to allow testing of plugin commands, and wrote some tests for pluginManager.
Reviewed By: mweststrate
Differential Revision: D26450344
fbshipit-source-id: 0e8414517cc1ad353781dffd7ffb4a5f9a815d38
Summary:
This diff introduces support for keeping clients around after they have disconnected. This is a pretty important debugging improvement, that will allow inspecting a device / app after it crashed for example.
With this diff, the current client is just kept around until it connects again, instead of throwing clients immediately away if they disconnect. After this change, ArchivedClients will only be created by imports / exports, and no longer by disconnects. Initially I played with improving the creation of archived devices, by migrating all plugin state over from the original client to the archive, but I discovered that is very prone, as it would be a lot of pointer redistribution (plugins would point to a different client / device etc). While in contrast, disconnected clients is already an existing concept in Flipper, so reusing that keeps all the changes relatively simple.
Note that we could potentially still reuse old clients around after reconnected, but it would become much harder to reason about how plugins would behave if they missed updates for a while, so throwing away the device / clients and starting with a fresh slate sounds safer. So I figured that chance to be too risky for now, but would probably be good follow up work.
Issues with import / export, UX, and making calls to to a disconnected client will be addressed in follow up diffs
Changelog: Clients will retain their state after being disconnected, until they reconnect again
Reviewed By: nikoant
Differential Revision: D26224677
fbshipit-source-id: feb9d241df2304341c2847fe7fd751ac54c045f6
Summary: This prefixes APIs of `flipper-plugin`, that are used by Flipper, but should not be used by plugins directly, with `_`. Also added tests to make sure we are always intentional when extending the exposed APIs
Reviewed By: passy
Differential Revision: D24991700
fbshipit-source-id: ed3700efa188fca7f5a14d5c68250598cf011e42
Summary:
Navigation plugin is a special cause that will remain connected and process messages directly even when disabled, this is to make sure the bookmarks feature keeps working even when the plugin is not enabled.
Changelog: [Sandy][Navigation] on Android, the currently active deeplink of the application will now be shown in the sidebar
Reviewed By: jknoxville
Differential Revision: D24890375
fbshipit-source-id: eb5e4141740e0436396cea5a7aae24337f2e903e
Summary:
I noticed that after the typescript upgrade, I got several weird positives from ESLint (like unused parameters in a type definition, which are obviously always unused, e.g. `type onClick = (e: Event) => void`). After some investigation, it turned out these warnings are generated by eslint, but that those rules should be performaned by typescript/eslint instead. For future reference to which rules this applies:
https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/README.md#extension-rules
Updated the config, and while at it, fixed all warnings in our codebase, except for `react-hooks/exhaustive-deps` warnings, since those require semantic changes.
This reduces the amount of eslint warnings from 86 to 39.
Reviewed By: passy
Differential Revision: D23905630
fbshipit-source-id: 0557708fd9ec6b17840a3c191e7d3baf225bdf23
Summary:
Some non-semantic changes. Mostly an earlier rename that was accidentally done only locally rather than across the codebase
Also support `.spec` test extension, which is more idiomatic Jest, since we don't use the `.node` and `.electron` distinction anymore anyway.
Reviewed By: jknoxville
Differential Revision: D22976438
fbshipit-source-id: f3abedb36cbac1e835295177117ccbca492a67a1
Summary:
This diff makes sure that devices will actually instantiate applicable sandy device plugins. Similar to how client plugins are owned by Client, device plugins are directly owned by BaseDevice, which significantly simplifies life cycle management and doesn't dispatch updates to all Redux connect components whenever something irrelevant changes.
Also made sure `device.teardown()` is called. That API already existed, but wasn't used or implemented before.
Updated Flipper test utils to support testing device plugins as well (both Sandy and classic ones)
Reviewed By: passy, nikoant
Differential Revision: D22693929
fbshipit-source-id: 73b2b8666ef7a0e748ea89360db84734d37eb5be
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
Summary: Sandy plugins can now send messages to plugins. The methods and params are strongly typed in implementation and unit tests, based on the <Methods> generic of FlipperClient.
Reviewed By: nikoant
Differential Revision: D22256972
fbshipit-source-id: 549523a402949b3eb6bb4b4ca160dedb5c5e722d
Summary:
This sets up the initial infra that is to be used by plugin devs to test plugins.
There is not much yet to see, as there is no state or message sending yet. But at least the life cycle of plugins can be test, things are strongly typed and everything is in the place where it should be :)
N.b. the import difference with these utils and the createFlipperMock utilities in Flipper are
1. this testing infra is entirely inside flipper-plugin package, so that plugin devs don't need flipper as a dependency
2. this testing infra doesn't provide abstractions for plugin / device / client switching; it tests plugins purely in isolation of the rest of the world (except for firing `onConnect` / `onDisconnect` which is normally the effect of switching plugins)
Reviewed By: nikoant
Differential Revision: D22255262
fbshipit-source-id: b94ccbab720d2b49428a646aed3c55af71a5bc80
Summary:
Introduced hooks that are called whenever the plugin is connected / disconnected to it's counter part on the device.
There is some logic duplication between `PluginContainer` for old plugins, and `PluginRenderer` for new plugins, mostly caused by the fact that those lifecycles are triggered from the UI rather than from the reducers, but I figured refactoring that to be too risky.
Reviewed By: jknoxville
Differential Revision: D22232337
fbshipit-source-id: a384c45731a4c8d9b8b532a83e2becf49ce807c2
Summary: PluginContainer will now wrap Sandy plugins in PluginRenderer. PluginRenderer will also be used by plugin unit tests in the future
Reviewed By: jknoxville
Differential Revision: D22159359
fbshipit-source-id: 69f9c8f4bec9392022c1d7a14957f5aca0339d97
Summary: This diff introduces the `onDestroy` hook that can be used by plugins to listen to the event where a plugin is cleaned up (either because it is disabled, or because the client is being cleaned up)
Reviewed By: jknoxville
Differential Revision: D22208121
fbshipit-source-id: 9c4951ae671be611f21da171c548d4054c481166
Summary:
This diff makes sure sandy plugins are initialized.
Sandy plugins are stored directly in the client for two reasons
1. we want to decouple any plugin state updates from our central redux store, as redux is particularly bad in handling high frequency updates.
2. The lifecycle of a plugin is now bound to the lifecycle of a client. This means that we don't need 'persistedStore' to make sure state is preserved; that is now the default. Switching plugins will no longer reinitialize them (but only run specific hooks, see later diffs).
3. PersistedState will be introduced for sandy plugins as well later, but primarily for import / export / debug reasons.
A significant difference with the current persistent state, is that if a client crashes and reconnects, plugins will loose their state. We can prevent this (again, since state persisting will be reintroduced), but I'm not sure we need that for the specific reconnect scenario. Because
1. we should fix reconnecting clients anyway, and from stats it looks to happen less already
2. reconnects are usually caused by plugins that aggregate a lot of data and get slower over time. Restoring old state also restores those unstabilites.
For the overview bringing back the archi picture of earlier diff:
{F241508042}
Also fixed a bug where enabling background plugins didn't enable them on all devices with that app.
Reviewed By: jknoxville
Differential Revision: D22186276
fbshipit-source-id: 3fd42b577f86920e5280aa8cce1a0bc4d5564ed9