text: import { computeNextBackoffInterval } from '@ide/backoff';
  import * as Application from 'expo-application';
  import { CodedError, Platform, UnavailabilityError } from 'expo-modules-core';
  import ServerRegistrationModule from '../ServerRegistrationModule';
  const updateDevicePushTokenUrl = 'https://exp.host/--/api/v2/push/updateDeviceToken';
  export async function updateDevicePushTokenAsync(signal, token) {
      const doUpdateDevicePushTokenAsync = async (retry) => {
          const [development, deviceId] = await Promise.all([
              shouldUseDevelopmentNotificationService(),
              getDeviceIdAsync(),
          ]);
          const body = {
              deviceId: deviceId.toLowerCase(),
              development,
              deviceToken: token.data,
              appId: Application.applicationId,
              type: getTypeOfToken(token),
          };
          try {
              const response = await fetch(updateDevicePushTokenUrl, {
                  method: 'POST',
                  headers: {
                      'content-type': 'application/json',
                  },
                  body: JSON.stringify(body),
                  signal,
              });
              // Help debug erroring servers
              if (!response.ok) {
                  console.debug('[expo-notifications] Error encountered while updating the device push token with the server:', await response.text());
              }
              // Retry if request failed
              if (!response.ok) {
                  retry();
              }
          }
          catch (e) {
              // Error returned if the request is aborted should be an 'AbortError'. In
              // React Native fetch is polyfilled using `whatwg-fetch` which:
              // - creates `AbortError`s like this
              //   https://github.com/github/fetch/blob/75d9455d380f365701151f3ac85c5bda4bbbde76/fetch.js#L505
              // - which creates exceptions like
              //   https://github.com/github/fetch/blob/75d9455d380f365701151f3ac85c5bda4bbbde76/fetch.js#L490-L494
              if (e.name === 'AbortError') {
                  // We don't consider AbortError a failure, it's a sign somewhere else the
                  // request is expected to succeed and we don't need this one, so let's
                  // just return.
                  return;
              }
              console.warn('[expo-notifications] Error thrown while updating the device push token with the server:', e);
              retry();
          }
      };
      let shouldTry = true;
      const retry = () => {
          shouldTry = true;
      };
      let retriesCount = 0;
      const initialBackoff = 500; // 0.5 s
      const backoffOptions = {
          maxBackoff: 2 * 60 * 1000, // 2 minutes
      };
      let nextBackoffInterval = computeNextBackoffInterval(initialBackoff, retriesCount, backoffOptions);
      while (shouldTry && !signal.aborted) {
          // Will be set to true by `retry` if it's called
          shouldTry = false;
          await doUpdateDevicePushTokenAsync(retry);
          // Do not wait if we won't retry
          if (shouldTry && !signal.aborted) {
              nextBackoffInterval = computeNextBackoffInterval(initialBackoff, retriesCount, backoffOptions);
              retriesCount += 1;
              await new Promise((resolve) => setTimeout(resolve, nextBackoffInterval));
          }
      }
  }
  // Same as in getExpoPushTokenAsync
  async function getDeviceIdAsync() {
      try {
          if (!ServerRegistrationModule.getInstallationIdAsync) {
              throw new UnavailabilityError('ExpoServerRegistrationModule', 'getInstallationIdAsync');
          }
          return await ServerRegistrationModule.getInstallationIdAsync();
      }
      catch (e) {
          throw new CodedError('ERR_NOTIFICATIONS_DEVICE_ID', `Could not fetch the installation ID of the application: ${e}.`);
      }
  }
  // Same as in getExpoPushTokenAsync
  function getTypeOfToken(devicePushToken) {
      switch (devicePushToken.type) {
          case 'ios':
              return 'apns';
          case 'android':
              return 'fcm';
          // This probably will error on server, but let's make this function future-safe.
          default:
              return devicePushToken.type;
      }
  }
  // Same as in getExpoPushTokenAsync
  async function shouldUseDevelopmentNotificationService() {
      if (Platform.OS === 'ios') {
          try {
              const notificationServiceEnvironment = await Application.getIosPushNotificationServiceEnvironmentAsync();
              if (notificationServiceEnvironment === 'development') {
                  return true;
              }
          }
          catch {
              // We can't do anything here, we'll fallback to false then.
          }
      }
      return false;
  }
  //# sourceMappingURL=updateDevicePushTokenAsync.js.map