export function connectFlipperServerToStore()

in desktop/flipper-ui-core/src/dispatcher/flipperServer.tsx [28:149]


export function connectFlipperServerToStore(
  server: FlipperServer,
  store: Store,
  logger: Logger,
) {
  server.on('notification', ({type, title, description}) => {
    const text = `[${type}] ${title}: ${description}`;
    console.warn(text);
    notification.open({
      message: title,
      description: description,
      type: type,
      duration: 0,
      key: text,
    });
  });

  server.on('server-state', handleServerStateChange);

  server.on('server-error', (err) => {
    notification.error({
      message: 'Connection error',
      description:
        err.code === 'EADDRINUSE' ? (
          <>
            Couldn't start connection server. Looks like you have multiple
            copies of Flipper running or another process is using the same
            port(s). As a result devices will not be able to connect to Flipper.
            <br />
            <br />
            Please try to kill the offending process by running{' '}
            <code>kill $(lsof -ti:PORTNUMBER)</code> and restart flipper.
            <br />
            <br />
            {'' + err}
          </>
        ) : (
          <>{err.message ?? err}</>
        ),
      duration: null,
    });
  });

  server.on('device-connected', (deviceInfo) => {
    handleDeviceConnected(server, store, logger, deviceInfo);
  });

  server.on('device-disconnected', (device) => {
    logger.track('usage', 'unregister-device', {
      os: device.os,
      serial: device.serial,
    });
    // N.B.: note that we don't remove the device, we keep it in offline
  });

  server.on('client-setup', (client) => {
    store.dispatch({
      type: 'START_CLIENT_SETUP',
      payload: client,
    });
  });

  server.on('client-connected', (payload: ClientDescription) =>
    handleClientConnected(server, store, logger, payload),
  );

  server.on('client-disconnected', ({id}) => {
    const existingClient = store.getState().connections.clients.get(id);
    existingClient?.disconnect();
  });

  server.on('client-message', ({id, message}) => {
    const existingClient = store.getState().connections.clients.get(id);
    existingClient?.onMessage(message);
  });

  if (typeof window !== 'undefined') {
    window.addEventListener('beforeunload', () => {
      server.close();
    });
  }

  let sideEffectDisposer: undefined | (() => void);

  if (!isTest()) {
    sideEffectDisposer = startSideEffects(store, server);
  }
  console.log(
    'Flipper server started and accepting device / client connections',
  );

  server
    .exec('get-server-state')
    .then(handleServerStateChange)
    .catch((e) => {
      console.error(`Failed to get initial server state`, e);
    });

  // this flow is spawned delibarately from this main flow
  waitFor(store, (state) => state.plugins.initialized)
    .then(() => server.exec('device-list'))
    .then((devices) => {
      // register all devices
      devices.forEach((device) => {
        handleDeviceConnected(server, store, logger, device);
      });
    })
    .then(() => server.exec('client-list'))
    .then((clients) => {
      clients.forEach((client) => {
        handleClientConnected(server, store, logger, client);
      });
    })
    .catch((e) => {
      console.error('Failed to get initial device/client list: ', e);
    });

  return () => {
    sideEffectDisposer?.();
    server.close();
  };
}