{"version":3,"file":"index-Dy_gOSon.js","sources":["../../../app/assets/javascripts/app/network_latency_to_spacious/index.ts"],"sourcesContent":["\nimport log from \"plugins/loglevel/index\"\n\nimport * as retry from \"retry\"\nimport Promise from \"plugins/bluebird/index\"\nimport WindowState from \"app/window_state/index\"\nimport DataRetriever from \"app/data_retriever\"\nimport {\n  captureMessage,\n} from \"app/error_reporting\"\n\n\n/* eslint-disable no-unused-vars */\nenum NetworkLatencyStatuses {\n  LATENCY_UNKNOWN  = \"LATENCY_UNKNOWN\",\n  LATENCY_DETECTED = \"LATENCY_DETECTED\",\n}\n/* eslint-enable no-unused-vars */\n\ninterface NetworkLatencyToSpaciousResult {\n  latency_value_in_ms: number,\n  status: NetworkLatencyStatuses,\n}\n\n// Represents unknown\nconst UNKNOWN_NETWORK_LATENCY_TO_SERVER_MS_VALUE = -1\nlet network_latency_to_server_ms = UNKNOWN_NETWORK_LATENCY_TO_SERVER_MS_VALUE\nlet status = NetworkLatencyStatuses.LATENCY_UNKNOWN\n\n\nconst ENDPOINT_IDENTIFIER = \"network_latency_to_spacious\"\n\n\nconst refreshNetworkLatencyPromise = (): Promise<void> => {\n  // Set fallback value, although `beforeSend` should set it anyway\n  let start_time = new Date().getTime()\n\n  const timeout_options = {\n    minTimeout: 10 * 1000,\n    maxTimeout: 60 * 1000,\n    factor:     2,\n    // Should become 10,20,40,60\n    retries:    4,\n  }\n\n  // We are not waiting locally, only having different timeout values on AJAX\n  const retry_operation = retry.operation({\n    retries:    5,\n    factor:     1,\n    minTimeout: 0,\n    maxTimeout: 0,\n    randomize:  false,\n  })\n\n  const url = \"/ping\"\n  const fetch_options: RequestInit = {\n    method:         \"GET\",\n    // Shouldn't allow redirect by default due to potential bug\n    // Allow later if really needed\n    redirect:       \"error\" as \"error\",\n    // Safer default, update to other value is required\n    referrerPolicy: \"same-origin\" as \"same-origin\",\n    // Safer default, update to other value is required\n    credentials:    \"same-origin\" as \"same-origin\",\n    // Just explicitly stating the default\n    cache:          \"default\" as \"default\",\n    headers:        {\n      // AJAX simulation\n      \"X-Requested-With\": \"XMLHttpRequest\",\n    },\n  }\n\n  return new Promise((resolve) => {\n    // currentAttempt is 1-based, tested manually\n    retry_operation.attempt((currentAttempt) => {\n      // `attempt` is zero-indexed in `createTimeout` but `currentAttempt` is 1 based\n      const current_timeout_ms = retry.createTimeout(currentAttempt - 1, timeout_options)\n\n      // region timeout\n      const abort_controller = new AbortController()\n      fetch_options.signal = abort_controller.signal\n\n      // https://stackoverflow.com/a/50101022/838346\n      const timeoutId = setTimeout(() => {\n        abort_controller.abort()\n      }, current_timeout_ms)\n      // endregion timeout\n\n      start_time = new Date().getTime()\n      window.fetch(\n        url,\n        fetch_options,\n      )\n      .then((response) => {\n        clearTimeout(timeoutId)\n        if (response.ok) {\n          const new_network_latency_to_server_ms = new Date().getTime() - start_time\n          status = NetworkLatencyStatuses.LATENCY_DETECTED\n          // If unknown, assign detected value anyway\n          //\n          // If new value < existing value, assign new value too\n          // since values fetched during script load / dom load\n          // might be inaccurate due to busy main thread\n          if (network_latency_to_server_ms === UNKNOWN_NETWORK_LATENCY_TO_SERVER_MS_VALUE ||\n            new_network_latency_to_server_ms < network_latency_to_server_ms) {\n\n            network_latency_to_server_ms = new_network_latency_to_server_ms\n          }\n\n          log.info(`Network Latency to Spacious: ${network_latency_to_server_ms}ms`)\n\n          resolve()\n          return\n        }\n\n        const context = {\n          fetch_options:        JSON.stringify(fetch_options),\n          http_status_code:     response.status,\n          endpoint_identifier:  ENDPOINT_IDENTIFIER,\n          current_attempt:      currentAttempt,\n        }\n\n        // No error should be reported for AJAX errors\n        // caused by page being unloaded\n        if (WindowState.isUnloaded()) {\n          resolve()\n          return\n        }\n\n        // Could be gateway server not ready\n        if (response.status === 404) {\n          resolve()\n          return\n        }\n\n        if (retry_operation.retry(new Error(response.statusText))) {\n          return\n        }\n\n        // Status Code 0 Could be caused by:\n        // - Illegal CORS (We don't use it anyway)\n        // - Firewall blocking/filtering (We can't fix)\n        // - Request is cancelled (not `abort()`) (Expected)\n        // - Browser extension (any Adblocker) (We can't fix)\n        //\n        // https://stackoverflow.com/a/14507670/838346\n        //\n        // So we don't report status code 0\n        //\n        // Some clients got strange response codes\n        if (response.status !== 0 && isSaneUserAgent() && isSaneLocation()) {\n          captureMessage(\n            `Error occurred when using ajax with status <${(response.status || \"unknown\")}> on endpoint <${ENDPOINT_IDENTIFIER}>`,\n            context,\n          )\n        }\n\n        // Resolve with status stayed in unknown\n        resolve()\n      })\n      .catch((error) => {\n        if (retry_operation.retry(error)) {\n          return\n        }\n\n        // Resolve with status stayed in unknown\n        resolve()\n      })\n    })\n  })\n}\n\nfunction getNetworkLatencyToSpacious(): NetworkLatencyToSpaciousResult {\n  return {\n    latency_value_in_ms:  network_latency_to_server_ms,\n    status:               status,\n  }\n}\n\nfunction getNetworkLatencyToSpaciousPromise(): Promise<NetworkLatencyToSpaciousResult> {\n  return refreshNetworkLatencyPromise()\n  .then(() => {\n    return {\n      latency_value_in_ms:  network_latency_to_server_ms,\n      status:               status,\n    }\n  })\n}\n\n// Not reporting errors from \"insane\" user agents\nfunction isSaneUserAgent(): boolean {\n  return [\n    /Baiduspider-render/i,\n    /YandexBot/i,\n  ].every((regex) => !regex.test(window.navigator.userAgent))\n}\n\n// Not reporting errors from \"insane\" locations\nfunction isSaneLocation(): boolean {\n  return !DataRetriever.get(\"current-location-country-code-is-china\")\n}\n\n\nexport {\n  getNetworkLatencyToSpacious,\n  getNetworkLatencyToSpaciousPromise,\n  refreshNetworkLatencyPromise as refreshNetworkLatencyToSpaciousPromise,\n  NetworkLatencyStatuses as NetworkLatencyToSpaciousStatues,\n}\n"],"names":["NetworkLatencyStatuses","UNKNOWN_NETWORK_LATENCY_TO_SERVER_MS_VALUE","network_latency_to_server_ms","status","ENDPOINT_IDENTIFIER","refreshNetworkLatencyPromise","start_time","timeout_options","retry_operation","retry.operation","url","fetch_options","Promise","resolve","currentAttempt","current_timeout_ms","retry.createTimeout","abort_controller","timeoutId","response","new_network_latency_to_server_ms","log","context","WindowState","isSaneUserAgent","isSaneLocation","captureMessage","error","getNetworkLatencyToSpacious","getNetworkLatencyToSpaciousPromise","regex","DataRetriever"],"mappings":"gNAaK,IAAAA,GAAAA,IACHA,EAAA,gBAAmB,kBACnBA,EAAA,iBAAmB,mBAFhBA,IAAAA,GAAA,CAAA,CAAA,EAYL,MAAMC,EAA6C,GACnD,IAAIC,EAA+BD,EAC/BE,EAAS,kBAGb,MAAMC,EAAsB,8BAGtBC,EAA+B,IAAqB,CAExD,IAAIC,EAAa,IAAI,KAAK,EAAE,QAAQ,EAEpC,MAAMC,EAAkB,CACtB,WAAY,GAAK,IACjB,WAAY,GAAK,IACjB,OAAY,EAEZ,QAAY,CACd,EAGMC,EAAkBC,EAAAA,UAAgB,CACtC,QAAY,EACZ,OAAY,EACZ,WAAY,EACZ,WAAY,EACZ,UAAY,EAAA,CACb,EAEKC,EAAM,QACNC,EAA6B,CACjC,OAAgB,MAGhB,SAAgB,QAEhB,eAAgB,cAEhB,YAAgB,cAEhB,MAAgB,UAChB,QAAgB,CAEd,mBAAoB,gBAAA,CAExB,EAEO,OAAA,IAAIC,EAASC,GAAY,CAEdL,EAAA,QAASM,GAAmB,CAE1C,MAAMC,EAAqBC,EAAoB,cAAAF,EAAiB,EAAGP,CAAe,EAG5EU,EAAmB,IAAI,gBAC7BN,EAAc,OAASM,EAAiB,OAGlC,MAAAC,EAAY,WAAW,IAAM,CACjCD,EAAiB,MAAM,GACtBF,CAAkB,EAGRT,EAAA,IAAI,KAAK,EAAE,QAAQ,EACzB,OAAA,MACLI,EACAC,CAAA,EAED,KAAMQ,GAAa,CAElB,GADA,aAAaD,CAAS,EAClBC,EAAS,GAAI,CACf,MAAMC,EAAmC,IAAI,KAAK,EAAE,QAAY,EAAAd,EACvDH,EAAA,oBAMLD,IAAiCD,GACnCmB,EAAmClB,KAEJA,EAAAkB,GAG7BC,EAAA,KAAK,gCAAgC,OAAAnB,EAA4B,KAAI,EAEjEW,EAAA,EACR,MAAA,CAGF,MAAMS,EAAU,CACd,cAAsB,KAAK,UAAUX,CAAa,EAClD,iBAAsBQ,EAAS,OAC/B,oBAAsBf,EACtB,gBAAsBU,CACxB,EAII,GAAAS,EAAY,aAAc,CACpBV,EAAA,EACR,MAAA,CAIE,GAAAM,EAAS,SAAW,IAAK,CACnBN,EAAA,EACR,MAAA,CAGEL,EAAgB,MAAM,IAAI,MAAMW,EAAS,UAAU,CAAC,IAepDA,EAAS,SAAW,GAAKK,EAAgB,GAAKC,KAChDC,EACE,+CAAgD,OAAAP,EAAS,QAAU,UAAU,mBAAkB,OAAAf,EAAmB,KAClHkB,CACF,EAIMT,EAAA,EAAA,CACT,EACA,MAAOc,GAAU,CACZnB,EAAgB,MAAMmB,CAAK,GAKvBd,EAAA,CAAA,CACT,CAAA,CACF,CAAA,CACF,CACH,EAEA,SAASe,GAA8D,CAC9D,MAAA,CACL,oBAAsB1B,EACtB,OAAAC,CACF,CACF,CAEA,SAAS0B,GAA8E,CAC9E,OAAAxB,EAAA,EACN,KAAK,KACG,CACL,oBAAsBH,EACtB,OAAAC,CACF,EACD,CACH,CAGA,SAASqB,GAA2B,CAC3B,MAAA,CACL,sBACA,YAAA,EACA,MAAOM,GAAU,CAACA,EAAM,KAAK,OAAO,UAAU,SAAS,CAAC,CAC5D,CAGA,SAASL,GAA0B,CAC1B,MAAA,CAACM,EAAc,IAAI,wCAAwC,CACpE"}