export function autoUpdatePlugins()

in desktop/flipper-ui-core/src/dispatcher/pluginMarketplace.tsx [137:216]


export function autoUpdatePlugins(
  store: Store,
  marketplacePlugins: DownloadablePluginDetails[],
) {
  const state = store.getState();
  if (!state.plugins.initialized) {
    // skip auto-updating plugins if they are not initialized yet
    return;
  }
  const {loadedPlugins, installedPlugins, uninstalledPluginNames} =
    state.plugins;
  const autoInstalledPlugins = new Set<string>();
  for (const client of state.connections.clients.values()) {
    const enabledPlugins = state.connections.enabledPlugins[client.query.app];
    if (enabledPlugins) {
      // If we already have persisted list of enabled plugins -
      // we should install those of them which are enabled, but not installed by some reason.
      enabledPlugins.forEach((p) => {
        if (client.supportsPlugin(p)) {
          autoInstalledPlugins.add(p);
        }
      });
    } else {
      // If there is no persisted list of enabled plugins this means that user
      // opened this app for first time. In such case we should enable and install
      // plugins which are enabled by default.
      for (const plugin of marketplacePlugins) {
        if (plugin.isEnabledByDefault && client.supportsPlugin(plugin.id)) {
          autoInstalledPlugins.add(plugin.id);
          const loadedPluginInstance = state.plugins.clientPlugins.get(
            plugin.id,
          );
          if (loadedPluginInstance) {
            // If plugin was already installed before (e.g. for debugging another mobile app),
            // then we should switch its state to "loaded" for the current app.
            store.dispatch(
              switchPlugin({
                plugin: loadedPluginInstance,
                selectedApp: client.query.app,
              }),
            );
          } else {
            // If plugin was not installed before, then we should mark it as enabled
            // to ensure it is automatically loaded after downloaded from Marketplace.
            store.dispatch(setPluginEnabled(plugin.id, client.query.app));
          }
        }
      }
    }
  }
  if (isAutoUpdateDisabled(store)) {
    return;
  }
  for (const plugin of marketplacePlugins) {
    if (uninstalledPluginNames.has(plugin.name)) {
      // Skip if plugin is marked as uninstalled
      continue;
    }
    if (!isPluginCompatible(plugin)) {
      // Skip if new plugin version is not compatible with the current Flipper version
      continue;
    }
    const loadedPlugin = loadedPlugins.get(plugin.id);
    if (loadedPlugin && !isPluginVersionMoreRecent(plugin, loadedPlugin)) {
      // Skip if plugin is installed and new version is less or equal to the installed one
      continue;
    }
    if (!loadedPlugin && !autoInstalledPlugins.has(plugin.id)) {
      // Skip if plugin is not installed and not in the list of auto-installable plugins
      continue;
    }
    const installedVersion = installedPlugins.get(plugin.name)?.version;
    if (installedVersion && semver.gte(installedVersion, plugin.version)) {
      // Skip if the same or newer version already downloaded
      continue;
    }
    // Finally if we are good to go - dispatch downloading of the updated version
    store.dispatch(startPluginDownload({plugin, startedByUser: false}));
  }
}