diff --git a/packages/performance/src/services/api_service.ts b/packages/performance/src/services/api_service.ts index 0495bfed165..28bbc5a2954 100644 --- a/packages/performance/src/services/api_service.ts +++ b/packages/performance/src/services/api_service.ts @@ -36,19 +36,20 @@ export type EntryType = | 'navigation'; /** - * This class holds a reference to various browser related objects injected by set methods. + * This class holds a reference to various browser related objects injected by + * set methods. */ export class Api { - private performance: Performance; + private readonly performance: Performance; /** PreformanceObserver constructor function. */ - private PerformanceObserver: typeof PerformanceObserver; - private windowLocation: Location; - onFirstInputDelay?: Function; - localStorage!: Storage; - document: Document; - navigator: Navigator; - - constructor(window?: Window) { + private readonly PerformanceObserver: typeof PerformanceObserver; + private readonly windowLocation: Location; + readonly onFirstInputDelay?: Function; + readonly localStorage?: Storage; + readonly document: Document; + readonly navigator: Navigator; + + constructor(readonly window?: Window) { if (!window) { throw ERROR_FACTORY.create(ErrorCode.NO_WINDOW); } @@ -58,7 +59,8 @@ export class Api { this.navigator = window.navigator; this.document = window.document; if (this.navigator && this.navigator.cookieEnabled) { - // If user blocks cookies on the browser, accessing localStorage will throw an exception. + // If user blocks cookies on the browser, accessing localStorage will + // throw an exception. this.localStorage = window.localStorage; } if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) { diff --git a/packages/performance/src/services/remote_config_service.ts b/packages/performance/src/services/remote_config_service.ts index a1e522b3d18..d886f24e35d 100644 --- a/packages/performance/src/services/remote_config_service.ts +++ b/packages/performance/src/services/remote_config_service.ts @@ -15,17 +15,18 @@ * limitations under the License. */ -import { SettingsService } from './settings_service'; import { - SDK_VERSION, + CONFIG_EXPIRY_LOCAL_STORAGE_KEY, CONFIG_LOCAL_STORAGE_KEY, - CONFIG_EXPIRY_LOCAL_STORAGE_KEY + SDK_VERSION } from '../constants'; -import { Api } from './api_service'; -import { getAuthTokenPromise } from './iid_service'; import { consoleLogger } from '../utils/console_logger'; import { ERROR_FACTORY, ErrorCode } from '../utils/errors'; +import { Api } from './api_service'; +import { getAuthTokenPromise } from './iid_service'; +import { SettingsService } from './settings_service'; + const REMOTE_CONFIG_SDK_VERSION = '0.0.1'; interface SecondaryConfig { @@ -71,12 +72,16 @@ export function getConfig(iid: string): Promise { .then(config => processConfig(config)) .then( config => storeConfig(config), - /** Do nothing for error, use defaults set in settings service. */ () => {} + /** Do nothing for error, use defaults set in settings service. */ + () => {} ); } function getStoredConfig(): RemoteConfigResponse | undefined { const localStorage = Api.getInstance().localStorage; + if (!localStorage) { + return; + } const expiryString = localStorage.getItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY); if (!expiryString || !configValid(expiryString)) { return; @@ -95,10 +100,11 @@ function getStoredConfig(): RemoteConfigResponse | undefined { } function storeConfig(config: RemoteConfigResponse | undefined): void { - if (!config) { + const localStorage = Api.getInstance().localStorage; + if (!config || !localStorage) { return; } - const localStorage = Api.getInstance().localStorage; + localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config)); localStorage.setItem( CONFIG_EXPIRY_LOCAL_STORAGE_KEY, @@ -122,9 +128,7 @@ function getRemoteConfig( const configEndPoint = `https://firebaseremoteconfig.googleapis.com/v1/projects/${projectId}/namespaces/fireperf:fetch?key=${SettingsService.getInstance().getApiKey()}`; const request = new Request(configEndPoint, { method: 'POST', - headers: { - Authorization: `${FIS_AUTH_PREFIX} ${authToken}` - }, + headers: { Authorization: `${FIS_AUTH_PREFIX} ${authToken}` }, /* eslint-disable camelcase */ body: JSON.stringify({ app_instance_id: iid, @@ -163,7 +167,8 @@ function processConfig( const settingsServiceInstance = SettingsService.getInstance(); const entries = config.entries || {}; if (entries.fpr_enabled !== undefined) { - // TODO: Change the assignment of loggingEnabled once the received type is known. + // TODO: Change the assignment of loggingEnabled once the received type is + // known. settingsServiceInstance.loggingEnabled = String(entries.fpr_enabled) === 'true'; } else if (SECONDARY_CONFIGS.loggingEnabled !== undefined) { diff --git a/packages/performance/src/utils/attributes_utils.ts b/packages/performance/src/utils/attributes_utils.ts index 0cfa2abe276..0ea8755b1e1 100644 --- a/packages/performance/src/utils/attributes_utils.ts +++ b/packages/performance/src/utils/attributes_utils.ts @@ -39,6 +39,19 @@ const enum EffectiveConnectionType { CONNECTION_4G = 4 } +/** + * NetworkInformation + * + * ref: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation + */ +interface NetworkInformation { + readonly effectiveType?: 'slow-2g' | '2g' | '3g' | '4g'; +} + +interface NavigatorWithConnection extends Navigator { + readonly connection: NetworkInformation; +} + const RESERVED_ATTRIBUTE_PREFIXES = ['firebase_', 'google_', 'ga_']; const ATTRIBUTE_FORMAT_REGEX = new RegExp('^[a-zA-Z]\\w*$'); const MAX_ATTRIBUTE_NAME_LENGTH = 40; @@ -72,8 +85,7 @@ export function getVisibilityState(): VisibilityState { export function getEffectiveConnectionType(): EffectiveConnectionType { const navigator = Api.getInstance().navigator; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const navigatorConnection = (navigator as any).connection; + const navigatorConnection = (navigator as NavigatorWithConnection).connection; const effectiveType = navigatorConnection && navigatorConnection.effectiveType; switch (effectiveType) {