hunk.code_window: #import "BranchLinkProperties+RNBranch.h"
   #import "BranchUniversalObject+RNBranch.h"
   #import "RNBranchAgingDictionary.h"
   #import "RNBranchEventEmitter.h"
   NSString * const RNBranchLinkOpenedNotification = @"RNBranchLinkOpenedNotification";
   NSString * const RNBranchLinkOpenedNotificationErrorKey = @"error";
  
hunk.labels: keep keep keep add keep keep keep
hunk.after_edit: #import "EXScope.h"
  
hunk.file_path: ios/Exponent/Versioned/Modules/Api/Standalone/Branch/RNBranch.m
hunk.type: add
file: /**
   * Copyright (c) 2015-present, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * LICENSE file in the root directory of this source tree. An additional grant
   * of patent rights can be found in the PATENTS file in the same directory.
   *
   * @providesModule HMRClient
   * @flow
   */
  'use strict';
  
  const Platform = require('Platform');
  const invariant = require('fbjs/lib/invariant');
  
  /**
   * HMR Client that receives from the server HMR updates and propagates them
   * runtime to reflects those changes.
   */
  const HMRClient = {
    enable(platform: string, bundleEntry: string, host: string, port: number) {
      invariant(platform, 'Missing required parameter `platform`');
      invariant(bundleEntry, 'Missing required paramenter `bundleEntry`');
      invariant(host, 'Missing required paramenter `host`');
  
      // need to require WebSocket inside of `enable` function because
      // this module is defined as a `polyfillGlobal`.
      // See `InitializeJavascriptAppEngine.js`
      const WebSocket = require('WebSocket');
  
      const wsHostPort = port !== null && port !== ''
        ? `${host}:${port}`
        : host;
  
      // Build the websocket url
      const wsUrl = `ws://${wsHostPort}/hot?` +
        `platform=${platform}&` +
        `bundleEntry=${bundleEntry.replace('.bundle', '.js')}`;
  
      const activeWS = new WebSocket(wsUrl);
      activeWS.onerror = (e) => {
        let error = (
  `Hot loading isn't working because it cannot connect to the development server.
  
  Try the following to fix the issue:
  - Ensure that the packager server is running and available on the same network`
        );
  
        if (Platform.OS === 'ios') {
          error += (
  `
  - Ensure that the Packager server URL is correctly set in AppDelegate`
          );
        } else {
          error += (
  `
  - Ensure that your device/emulator is connected to your machine and has USB debugging enabled - run 'adb devices' to see a list of connected devices
  - If you're on a physical device connected to the same machine, run 'adb reverse tcp:8081 tcp:8081' to forward requests from your device
  - If your device is on the same Wi-Fi network, set 'Debug server host & port for device' in 'Dev settings' to your machine's IP address and the port of the local dev server - e.g. 10.0.1.1:8081`
          );
        }
  
        error += (
  `
  
  URL: ${host}:${port}
  
  Error: ${e.message}`
        );
  
        throw new Error(error);
      };
      activeWS.onmessage = ({data}) => {
        // Moving to top gives errors due to NativeModules not being initialized
        const HMRLoadingView = require('HMRLoadingView');
  
        data = JSON.parse(data);
  
        switch (data.type) {
          case 'update-start': {
            HMRLoadingView.showMessage('Hot Loading...');
            break;
          }
          case 'update': {
            const {
              modules,
              sourceMappingURLs,
              sourceURLs,
              inverseDependencies,
            } = data.body;
  
            if (Platform.OS === 'ios') {
              const RCTRedBox = require('NativeModules').RedBox;
              RCTRedBox && RCTRedBox.dismiss && RCTRedBox.dismiss();
            } else {
              const RCTExceptionsManager = require('NativeModules').ExceptionsManager;
              RCTExceptionsManager && RCTExceptionsManager.dismissRedbox && RCTExceptionsManager.dismissRedbox();
            }
  
            modules.forEach(({id, code}, i) => {
              code = code + '\n\n' + sourceMappingURLs[i];
  
              // on JSC we need to inject from native for sourcemaps to work
              // (Safari doesn't support `sourceMappingURL` nor any variant when
              // evaluating code) but on Chrome we can simply use eval
              const injectFunction = typeof global.nativeInjectHMRUpdate === 'function'
                ? global.nativeInjectHMRUpdate
                : eval;
  
              code = [
                '__accept(',
                  `${id},`,
                  'function(global,require,module,exports){',
                    `${code}`,
                  '\n},',
                  `${JSON.stringify(inverseDependencies)}`,
                ');',
              ].join('');
  
              injectFunction(code, sourceURLs[i]);
            });
  
            HMRLoadingView.hide();
            break;
          }
          case 'update-done': {
            HMRLoadingView.hide();
            break;
          }
          case 'error': {
            HMRLoadingView.hide();
            throw new Error(data.body.type + ' ' + data.body.description);
          }
          default: {
            throw new Error(`Unexpected message: ${data}`);
          }
        }
      };
    },
  };
  
  module.exports = HMRClient;
  