12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553 |
- import { ErrorFactory, areCookiesEnabled, isIndexedDBAvailable, validateIndexedDBOpenable, getModularInstance, deepEqual } from '@firebase/util';
- import { Logger, LogLevel } from '@firebase/logger';
- import { __spreadArray, __assign } from 'tslib';
- import { getApp, _getProvider, _registerComponent, registerVersion } from '@firebase/app';
- import { Component } from '@firebase/component';
- import '@firebase/installations';
-
- var name = "@firebase/performance";
- var version = "0.6.1";
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var SDK_VERSION = version;
- /** The prefix for start User Timing marks used for creating Traces. */
- var TRACE_START_MARK_PREFIX = 'FB-PERF-TRACE-START';
- /** The prefix for stop User Timing marks used for creating Traces. */
- var TRACE_STOP_MARK_PREFIX = 'FB-PERF-TRACE-STOP';
- /** The prefix for User Timing measure used for creating Traces. */
- var TRACE_MEASURE_PREFIX = 'FB-PERF-TRACE-MEASURE';
- /** The prefix for out of the box page load Trace name. */
- var OOB_TRACE_PAGE_LOAD_PREFIX = '_wt_';
- var FIRST_PAINT_COUNTER_NAME = '_fp';
- var FIRST_CONTENTFUL_PAINT_COUNTER_NAME = '_fcp';
- var FIRST_INPUT_DELAY_COUNTER_NAME = '_fid';
- var CONFIG_LOCAL_STORAGE_KEY = '@firebase/performance/config';
- var CONFIG_EXPIRY_LOCAL_STORAGE_KEY = '@firebase/performance/configexpire';
- var SERVICE = 'performance';
- var SERVICE_NAME = 'Performance';
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var _a;
- var ERROR_DESCRIPTION_MAP = (_a = {},
- _a["trace started" /* ErrorCode.TRACE_STARTED_BEFORE */] = 'Trace {$traceName} was started before.',
- _a["trace stopped" /* ErrorCode.TRACE_STOPPED_BEFORE */] = 'Trace {$traceName} is not running.',
- _a["nonpositive trace startTime" /* ErrorCode.NONPOSITIVE_TRACE_START_TIME */] = 'Trace {$traceName} startTime should be positive.',
- _a["nonpositive trace duration" /* ErrorCode.NONPOSITIVE_TRACE_DURATION */] = 'Trace {$traceName} duration should be positive.',
- _a["no window" /* ErrorCode.NO_WINDOW */] = 'Window is not available.',
- _a["no app id" /* ErrorCode.NO_APP_ID */] = 'App id is not available.',
- _a["no project id" /* ErrorCode.NO_PROJECT_ID */] = 'Project id is not available.',
- _a["no api key" /* ErrorCode.NO_API_KEY */] = 'Api key is not available.',
- _a["invalid cc log" /* ErrorCode.INVALID_CC_LOG */] = 'Attempted to queue invalid cc event',
- _a["FB not default" /* ErrorCode.FB_NOT_DEFAULT */] = 'Performance can only start when Firebase app instance is the default one.',
- _a["RC response not ok" /* ErrorCode.RC_NOT_OK */] = 'RC response is not ok',
- _a["invalid attribute name" /* ErrorCode.INVALID_ATTRIBUTE_NAME */] = 'Attribute name {$attributeName} is invalid.',
- _a["invalid attribute value" /* ErrorCode.INVALID_ATTRIBUTE_VALUE */] = 'Attribute value {$attributeValue} is invalid.',
- _a["invalid custom metric name" /* ErrorCode.INVALID_CUSTOM_METRIC_NAME */] = 'Custom metric name {$customMetricName} is invalid',
- _a["invalid String merger input" /* ErrorCode.INVALID_STRING_MERGER_PARAMETER */] = 'Input for String merger is invalid, contact support team to resolve.',
- _a["already initialized" /* ErrorCode.ALREADY_INITIALIZED */] = 'initializePerformance() has already been called with ' +
- 'different options. To avoid this error, call initializePerformance() with the ' +
- 'same options as when it was originally called, or call getPerformance() to return the' +
- ' already initialized instance.',
- _a);
- var ERROR_FACTORY = new ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP);
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var consoleLogger = new Logger(SERVICE_NAME);
- consoleLogger.logLevel = LogLevel.INFO;
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var apiInstance;
- var windowInstance;
- /**
- * This class holds a reference to various browser related objects injected by
- * set methods.
- */
- var Api = /** @class */ (function () {
- function Api(window) {
- this.window = window;
- if (!window) {
- throw ERROR_FACTORY.create("no window" /* ErrorCode.NO_WINDOW */);
- }
- this.performance = window.performance;
- this.PerformanceObserver = window.PerformanceObserver;
- this.windowLocation = window.location;
- 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.
- this.localStorage = window.localStorage;
- }
- if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) {
- this.onFirstInputDelay = window.perfMetrics.onFirstInputDelay;
- }
- }
- Api.prototype.getUrl = function () {
- // Do not capture the string query part of url.
- return this.windowLocation.href.split('?')[0];
- };
- Api.prototype.mark = function (name) {
- if (!this.performance || !this.performance.mark) {
- return;
- }
- this.performance.mark(name);
- };
- Api.prototype.measure = function (measureName, mark1, mark2) {
- if (!this.performance || !this.performance.measure) {
- return;
- }
- this.performance.measure(measureName, mark1, mark2);
- };
- Api.prototype.getEntriesByType = function (type) {
- if (!this.performance || !this.performance.getEntriesByType) {
- return [];
- }
- return this.performance.getEntriesByType(type);
- };
- Api.prototype.getEntriesByName = function (name) {
- if (!this.performance || !this.performance.getEntriesByName) {
- return [];
- }
- return this.performance.getEntriesByName(name);
- };
- Api.prototype.getTimeOrigin = function () {
- // Polyfill the time origin with performance.timing.navigationStart.
- return (this.performance &&
- (this.performance.timeOrigin || this.performance.timing.navigationStart));
- };
- Api.prototype.requiredApisAvailable = function () {
- if (!fetch || !Promise || !areCookiesEnabled()) {
- consoleLogger.info('Firebase Performance cannot start if browser does not support fetch and Promise or cookie is disabled.');
- return false;
- }
- if (!isIndexedDBAvailable()) {
- consoleLogger.info('IndexedDB is not supported by current browswer');
- return false;
- }
- return true;
- };
- Api.prototype.setupObserver = function (entryType, callback) {
- if (!this.PerformanceObserver) {
- return;
- }
- var observer = new this.PerformanceObserver(function (list) {
- for (var _i = 0, _a = list.getEntries(); _i < _a.length; _i++) {
- var entry = _a[_i];
- // `entry` is a PerformanceEntry instance.
- callback(entry);
- }
- });
- // Start observing the entry types you care about.
- observer.observe({ entryTypes: [entryType] });
- };
- Api.getInstance = function () {
- if (apiInstance === undefined) {
- apiInstance = new Api(windowInstance);
- }
- return apiInstance;
- };
- return Api;
- }());
- function setupApi(window) {
- windowInstance = window;
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var iid;
- function getIidPromise(installationsService) {
- var iidPromise = installationsService.getId();
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
- iidPromise.then(function (iidVal) {
- iid = iidVal;
- });
- return iidPromise;
- }
- // This method should be used after the iid is retrieved by getIidPromise method.
- function getIid() {
- return iid;
- }
- function getAuthTokenPromise(installationsService) {
- var authTokenPromise = installationsService.getToken();
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
- authTokenPromise.then(function (authTokenVal) {
- });
- return authTokenPromise;
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- function mergeStrings(part1, part2) {
- var sizeDiff = part1.length - part2.length;
- if (sizeDiff < 0 || sizeDiff > 1) {
- throw ERROR_FACTORY.create("invalid String merger input" /* ErrorCode.INVALID_STRING_MERGER_PARAMETER */);
- }
- var resultArray = [];
- for (var i = 0; i < part1.length; i++) {
- resultArray.push(part1.charAt(i));
- if (part2.length > i) {
- resultArray.push(part2.charAt(i));
- }
- }
- return resultArray.join('');
- }
-
- /**
- * @license
- * Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var settingsServiceInstance;
- var SettingsService = /** @class */ (function () {
- function SettingsService() {
- // The variable which controls logging of automatic traces and HTTP/S network monitoring.
- this.instrumentationEnabled = true;
- // The variable which controls logging of custom traces.
- this.dataCollectionEnabled = true;
- // Configuration flags set through remote config.
- this.loggingEnabled = false;
- // Sampling rate between 0 and 1.
- this.tracesSamplingRate = 1;
- this.networkRequestsSamplingRate = 1;
- // Address of logging service.
- this.logEndPointUrl = 'https://firebaselogging.googleapis.com/v0cc/log?format=json_proto';
- // Performance event transport endpoint URL which should be compatible with proto3.
- // New Address for transport service, not configurable via Remote Config.
- this.flTransportEndpointUrl = mergeStrings('hts/frbslgigp.ogepscmv/ieo/eaylg', 'tp:/ieaeogn-agolai.o/1frlglgc/o');
- this.transportKey = mergeStrings('AzSC8r6ReiGqFMyfvgow', 'Iayx0u-XT3vksVM-pIV');
- // Source type for performance event logs.
- this.logSource = 462;
- // Flags which control per session logging of traces and network requests.
- this.logTraceAfterSampling = false;
- this.logNetworkAfterSampling = false;
- // TTL of config retrieved from remote config in hours.
- this.configTimeToLive = 12;
- }
- SettingsService.prototype.getFlTransportFullUrl = function () {
- return this.flTransportEndpointUrl.concat('?key=', this.transportKey);
- };
- SettingsService.getInstance = function () {
- if (settingsServiceInstance === undefined) {
- settingsServiceInstance = new SettingsService();
- }
- return settingsServiceInstance;
- };
- return SettingsService;
- }());
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var VisibilityState;
- (function (VisibilityState) {
- VisibilityState[VisibilityState["UNKNOWN"] = 0] = "UNKNOWN";
- VisibilityState[VisibilityState["VISIBLE"] = 1] = "VISIBLE";
- VisibilityState[VisibilityState["HIDDEN"] = 2] = "HIDDEN";
- })(VisibilityState || (VisibilityState = {}));
- var RESERVED_ATTRIBUTE_PREFIXES = ['firebase_', 'google_', 'ga_'];
- var ATTRIBUTE_FORMAT_REGEX = new RegExp('^[a-zA-Z]\\w*$');
- var MAX_ATTRIBUTE_NAME_LENGTH = 40;
- var MAX_ATTRIBUTE_VALUE_LENGTH = 100;
- function getServiceWorkerStatus() {
- var navigator = Api.getInstance().navigator;
- if (navigator === null || navigator === void 0 ? void 0 : navigator.serviceWorker) {
- if (navigator.serviceWorker.controller) {
- return 2 /* ServiceWorkerStatus.CONTROLLED */;
- }
- else {
- return 3 /* ServiceWorkerStatus.UNCONTROLLED */;
- }
- }
- else {
- return 1 /* ServiceWorkerStatus.UNSUPPORTED */;
- }
- }
- function getVisibilityState() {
- var document = Api.getInstance().document;
- var visibilityState = document.visibilityState;
- switch (visibilityState) {
- case 'visible':
- return VisibilityState.VISIBLE;
- case 'hidden':
- return VisibilityState.HIDDEN;
- default:
- return VisibilityState.UNKNOWN;
- }
- }
- function getEffectiveConnectionType() {
- var navigator = Api.getInstance().navigator;
- var navigatorConnection = navigator.connection;
- var effectiveType = navigatorConnection && navigatorConnection.effectiveType;
- switch (effectiveType) {
- case 'slow-2g':
- return 1 /* EffectiveConnectionType.CONNECTION_SLOW_2G */;
- case '2g':
- return 2 /* EffectiveConnectionType.CONNECTION_2G */;
- case '3g':
- return 3 /* EffectiveConnectionType.CONNECTION_3G */;
- case '4g':
- return 4 /* EffectiveConnectionType.CONNECTION_4G */;
- default:
- return 0 /* EffectiveConnectionType.UNKNOWN */;
- }
- }
- function isValidCustomAttributeName(name) {
- if (name.length === 0 || name.length > MAX_ATTRIBUTE_NAME_LENGTH) {
- return false;
- }
- var matchesReservedPrefix = RESERVED_ATTRIBUTE_PREFIXES.some(function (prefix) {
- return name.startsWith(prefix);
- });
- return !matchesReservedPrefix && !!name.match(ATTRIBUTE_FORMAT_REGEX);
- }
- function isValidCustomAttributeValue(value) {
- return value.length !== 0 && value.length <= MAX_ATTRIBUTE_VALUE_LENGTH;
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- function getAppId(firebaseApp) {
- var _a;
- var appId = (_a = firebaseApp.options) === null || _a === void 0 ? void 0 : _a.appId;
- if (!appId) {
- throw ERROR_FACTORY.create("no app id" /* ErrorCode.NO_APP_ID */);
- }
- return appId;
- }
- function getProjectId(firebaseApp) {
- var _a;
- var projectId = (_a = firebaseApp.options) === null || _a === void 0 ? void 0 : _a.projectId;
- if (!projectId) {
- throw ERROR_FACTORY.create("no project id" /* ErrorCode.NO_PROJECT_ID */);
- }
- return projectId;
- }
- function getApiKey(firebaseApp) {
- var _a;
- var apiKey = (_a = firebaseApp.options) === null || _a === void 0 ? void 0 : _a.apiKey;
- if (!apiKey) {
- throw ERROR_FACTORY.create("no api key" /* ErrorCode.NO_API_KEY */);
- }
- return apiKey;
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var REMOTE_CONFIG_SDK_VERSION = '0.0.1';
- // These values will be used if the remote config object is successfully
- // retrieved, but the template does not have these fields.
- var DEFAULT_CONFIGS = {
- loggingEnabled: true
- };
- var FIS_AUTH_PREFIX = 'FIREBASE_INSTALLATIONS_AUTH';
- function getConfig(performanceController, iid) {
- var config = getStoredConfig();
- if (config) {
- processConfig(config);
- return Promise.resolve();
- }
- return getRemoteConfig(performanceController, iid)
- .then(processConfig)
- .then(function (config) { return storeConfig(config); },
- /** Do nothing for error, use defaults set in settings service. */
- function () { });
- }
- function getStoredConfig() {
- var localStorage = Api.getInstance().localStorage;
- if (!localStorage) {
- return;
- }
- var expiryString = localStorage.getItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY);
- if (!expiryString || !configValid(expiryString)) {
- return;
- }
- var configStringified = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY);
- if (!configStringified) {
- return;
- }
- try {
- var configResponse = JSON.parse(configStringified);
- return configResponse;
- }
- catch (_a) {
- return;
- }
- }
- function storeConfig(config) {
- var localStorage = Api.getInstance().localStorage;
- if (!config || !localStorage) {
- return;
- }
- localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));
- localStorage.setItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY, String(Date.now() +
- SettingsService.getInstance().configTimeToLive * 60 * 60 * 1000));
- }
- var COULD_NOT_GET_CONFIG_MSG = 'Could not fetch config, will use default configs';
- function getRemoteConfig(performanceController, iid) {
- // Perf needs auth token only to retrieve remote config.
- return getAuthTokenPromise(performanceController.installations)
- .then(function (authToken) {
- var projectId = getProjectId(performanceController.app);
- var apiKey = getApiKey(performanceController.app);
- var configEndPoint = "https://firebaseremoteconfig.googleapis.com/v1/projects/".concat(projectId, "/namespaces/fireperf:fetch?key=").concat(apiKey);
- var request = new Request(configEndPoint, {
- method: 'POST',
- headers: { Authorization: "".concat(FIS_AUTH_PREFIX, " ").concat(authToken) },
- /* eslint-disable camelcase */
- body: JSON.stringify({
- app_instance_id: iid,
- app_instance_id_token: authToken,
- app_id: getAppId(performanceController.app),
- app_version: SDK_VERSION,
- sdk_version: REMOTE_CONFIG_SDK_VERSION
- })
- /* eslint-enable camelcase */
- });
- return fetch(request).then(function (response) {
- if (response.ok) {
- return response.json();
- }
- // In case response is not ok. This will be caught by catch.
- throw ERROR_FACTORY.create("RC response not ok" /* ErrorCode.RC_NOT_OK */);
- });
- })
- .catch(function () {
- consoleLogger.info(COULD_NOT_GET_CONFIG_MSG);
- return undefined;
- });
- }
- /**
- * Processes config coming either from calling RC or from local storage.
- * This method only runs if call is successful or config in storage
- * is valid.
- */
- function processConfig(config) {
- if (!config) {
- return config;
- }
- var settingsServiceInstance = SettingsService.getInstance();
- var entries = config.entries || {};
- if (entries.fpr_enabled !== undefined) {
- // TODO: Change the assignment of loggingEnabled once the received type is
- // known.
- settingsServiceInstance.loggingEnabled =
- String(entries.fpr_enabled) === 'true';
- }
- else {
- // Config retrieved successfully, but there is no fpr_enabled in template.
- // Use secondary configs value.
- settingsServiceInstance.loggingEnabled = DEFAULT_CONFIGS.loggingEnabled;
- }
- if (entries.fpr_log_source) {
- settingsServiceInstance.logSource = Number(entries.fpr_log_source);
- }
- else if (DEFAULT_CONFIGS.logSource) {
- settingsServiceInstance.logSource = DEFAULT_CONFIGS.logSource;
- }
- if (entries.fpr_log_endpoint_url) {
- settingsServiceInstance.logEndPointUrl = entries.fpr_log_endpoint_url;
- }
- else if (DEFAULT_CONFIGS.logEndPointUrl) {
- settingsServiceInstance.logEndPointUrl = DEFAULT_CONFIGS.logEndPointUrl;
- }
- // Key from Remote Config has to be non-empty string, otherwsie use local value.
- if (entries.fpr_log_transport_key) {
- settingsServiceInstance.transportKey = entries.fpr_log_transport_key;
- }
- else if (DEFAULT_CONFIGS.transportKey) {
- settingsServiceInstance.transportKey = DEFAULT_CONFIGS.transportKey;
- }
- if (entries.fpr_vc_network_request_sampling_rate !== undefined) {
- settingsServiceInstance.networkRequestsSamplingRate = Number(entries.fpr_vc_network_request_sampling_rate);
- }
- else if (DEFAULT_CONFIGS.networkRequestsSamplingRate !== undefined) {
- settingsServiceInstance.networkRequestsSamplingRate =
- DEFAULT_CONFIGS.networkRequestsSamplingRate;
- }
- if (entries.fpr_vc_trace_sampling_rate !== undefined) {
- settingsServiceInstance.tracesSamplingRate = Number(entries.fpr_vc_trace_sampling_rate);
- }
- else if (DEFAULT_CONFIGS.tracesSamplingRate !== undefined) {
- settingsServiceInstance.tracesSamplingRate =
- DEFAULT_CONFIGS.tracesSamplingRate;
- }
- // Set the per session trace and network logging flags.
- settingsServiceInstance.logTraceAfterSampling = shouldLogAfterSampling(settingsServiceInstance.tracesSamplingRate);
- settingsServiceInstance.logNetworkAfterSampling = shouldLogAfterSampling(settingsServiceInstance.networkRequestsSamplingRate);
- return config;
- }
- function configValid(expiry) {
- return Number(expiry) > Date.now();
- }
- function shouldLogAfterSampling(samplingRate) {
- return Math.random() <= samplingRate;
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var initializationStatus = 1 /* InitializationStatus.notInitialized */;
- var initializationPromise;
- function getInitializationPromise(performanceController) {
- initializationStatus = 2 /* InitializationStatus.initializationPending */;
- initializationPromise =
- initializationPromise || initializePerf(performanceController);
- return initializationPromise;
- }
- function isPerfInitialized() {
- return initializationStatus === 3 /* InitializationStatus.initialized */;
- }
- function initializePerf(performanceController) {
- return getDocumentReadyComplete()
- .then(function () { return getIidPromise(performanceController.installations); })
- .then(function (iid) { return getConfig(performanceController, iid); })
- .then(function () { return changeInitializationStatus(); }, function () { return changeInitializationStatus(); });
- }
- /**
- * Returns a promise which resolves whenever the document readystate is complete or
- * immediately if it is called after page load complete.
- */
- function getDocumentReadyComplete() {
- var document = Api.getInstance().document;
- return new Promise(function (resolve) {
- if (document && document.readyState !== 'complete') {
- var handler_1 = function () {
- if (document.readyState === 'complete') {
- document.removeEventListener('readystatechange', handler_1);
- resolve();
- }
- };
- document.addEventListener('readystatechange', handler_1);
- }
- else {
- resolve();
- }
- });
- }
- function changeInitializationStatus() {
- initializationStatus = 3 /* InitializationStatus.initialized */;
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var DEFAULT_SEND_INTERVAL_MS = 10 * 1000;
- var INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000;
- // If end point does not work, the call will be tried for these many times.
- var DEFAULT_REMAINING_TRIES = 3;
- var MAX_EVENT_COUNT_PER_REQUEST = 1000;
- var remainingTries = DEFAULT_REMAINING_TRIES;
- /* eslint-enable camelcase */
- var queue = [];
- var isTransportSetup = false;
- function setupTransportService() {
- if (!isTransportSetup) {
- processQueue(INITIAL_SEND_TIME_DELAY_MS);
- isTransportSetup = true;
- }
- }
- function processQueue(timeOffset) {
- setTimeout(function () {
- // If there is no remainingTries left, stop retrying.
- if (remainingTries === 0) {
- return;
- }
- // If there are no events to process, wait for DEFAULT_SEND_INTERVAL_MS and try again.
- if (!queue.length) {
- return processQueue(DEFAULT_SEND_INTERVAL_MS);
- }
- dispatchQueueEvents();
- }, timeOffset);
- }
- function dispatchQueueEvents() {
- // Extract events up to the maximum cap of single logRequest from top of "official queue".
- // The staged events will be used for current logRequest attempt, remaining events will be kept
- // for next attempt.
- var staged = queue.splice(0, MAX_EVENT_COUNT_PER_REQUEST);
- /* eslint-disable camelcase */
- // We will pass the JSON serialized event to the backend.
- var log_event = staged.map(function (evt) { return ({
- source_extension_json_proto3: evt.message,
- event_time_ms: String(evt.eventTime)
- }); });
- var data = {
- request_time_ms: String(Date.now()),
- client_info: {
- client_type: 1,
- js_client_info: {}
- },
- log_source: SettingsService.getInstance().logSource,
- log_event: log_event
- };
- /* eslint-enable camelcase */
- sendEventsToFl(data, staged).catch(function () {
- // If the request fails for some reason, add the events that were attempted
- // back to the primary queue to retry later.
- queue = __spreadArray(__spreadArray([], staged, true), queue, true);
- remainingTries--;
- consoleLogger.info("Tries left: ".concat(remainingTries, "."));
- processQueue(DEFAULT_SEND_INTERVAL_MS);
- });
- }
- function sendEventsToFl(data, staged) {
- return postToFlEndpoint(data)
- .then(function (res) {
- if (!res.ok) {
- consoleLogger.info('Call to Firebase backend failed.');
- }
- return res.json();
- })
- .then(function (res) {
- // Find the next call wait time from the response.
- var transportWait = Number(res.nextRequestWaitMillis);
- var requestOffset = DEFAULT_SEND_INTERVAL_MS;
- if (!isNaN(transportWait)) {
- requestOffset = Math.max(transportWait, requestOffset);
- }
- // Delete request if response include RESPONSE_ACTION_UNKNOWN or DELETE_REQUEST action.
- // Otherwise, retry request using normal scheduling if response include RETRY_REQUEST_LATER.
- var logResponseDetails = res.logResponseDetails;
- if (Array.isArray(logResponseDetails) &&
- logResponseDetails.length > 0 &&
- logResponseDetails[0].responseAction === 'RETRY_REQUEST_LATER') {
- queue = __spreadArray(__spreadArray([], staged, true), queue, true);
- consoleLogger.info("Retry transport request later.");
- }
- remainingTries = DEFAULT_REMAINING_TRIES;
- // Schedule the next process.
- processQueue(requestOffset);
- });
- }
- function postToFlEndpoint(data) {
- var flTransportFullUrl = SettingsService.getInstance().getFlTransportFullUrl();
- return fetch(flTransportFullUrl, {
- method: 'POST',
- body: JSON.stringify(data)
- });
- }
- function addToQueue(evt) {
- if (!evt.eventTime || !evt.message) {
- throw ERROR_FACTORY.create("invalid cc log" /* ErrorCode.INVALID_CC_LOG */);
- }
- // Add the new event to the queue.
- queue = __spreadArray(__spreadArray([], queue, true), [evt], false);
- }
- /** Log handler for cc service to send the performance logs to the server. */
- function transportHandler(
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- serializer) {
- return function () {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- var message = serializer.apply(void 0, args);
- addToQueue({
- message: message,
- eventTime: Date.now()
- });
- };
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /* eslint-enble camelcase */
- var logger;
- // This method is not called before initialization.
- function sendLog(resource, resourceType) {
- if (!logger) {
- logger = transportHandler(serializer);
- }
- logger(resource, resourceType);
- }
- function logTrace(trace) {
- var settingsService = SettingsService.getInstance();
- // Do not log if trace is auto generated and instrumentation is disabled.
- if (!settingsService.instrumentationEnabled && trace.isAuto) {
- return;
- }
- // Do not log if trace is custom and data collection is disabled.
- if (!settingsService.dataCollectionEnabled && !trace.isAuto) {
- return;
- }
- // Do not log if required apis are not available.
- if (!Api.getInstance().requiredApisAvailable()) {
- return;
- }
- // Only log the page load auto traces if page is visible.
- if (trace.isAuto && getVisibilityState() !== VisibilityState.VISIBLE) {
- return;
- }
- if (isPerfInitialized()) {
- sendTraceLog(trace);
- }
- else {
- // Custom traces can be used before the initialization but logging
- // should wait until after.
- getInitializationPromise(trace.performanceController).then(function () { return sendTraceLog(trace); }, function () { return sendTraceLog(trace); });
- }
- }
- function sendTraceLog(trace) {
- if (!getIid()) {
- return;
- }
- var settingsService = SettingsService.getInstance();
- if (!settingsService.loggingEnabled ||
- !settingsService.logTraceAfterSampling) {
- return;
- }
- setTimeout(function () { return sendLog(trace, 1 /* ResourceType.Trace */); }, 0);
- }
- function logNetworkRequest(networkRequest) {
- var settingsService = SettingsService.getInstance();
- // Do not log network requests if instrumentation is disabled.
- if (!settingsService.instrumentationEnabled) {
- return;
- }
- // Do not log the js sdk's call to transport service domain to avoid unnecessary cycle.
- // Need to blacklist both old and new endpoints to avoid migration gap.
- var networkRequestUrl = networkRequest.url;
- // Blacklist old log endpoint and new transport endpoint.
- // Because Performance SDK doesn't instrument requests sent from SDK itself.
- var logEndpointUrl = settingsService.logEndPointUrl.split('?')[0];
- var flEndpointUrl = settingsService.flTransportEndpointUrl.split('?')[0];
- if (networkRequestUrl === logEndpointUrl ||
- networkRequestUrl === flEndpointUrl) {
- return;
- }
- if (!settingsService.loggingEnabled ||
- !settingsService.logNetworkAfterSampling) {
- return;
- }
- setTimeout(function () { return sendLog(networkRequest, 0 /* ResourceType.NetworkRequest */); }, 0);
- }
- function serializer(resource, resourceType) {
- if (resourceType === 0 /* ResourceType.NetworkRequest */) {
- return serializeNetworkRequest(resource);
- }
- return serializeTrace(resource);
- }
- function serializeNetworkRequest(networkRequest) {
- var networkRequestMetric = {
- url: networkRequest.url,
- http_method: networkRequest.httpMethod || 0,
- http_response_code: 200,
- response_payload_bytes: networkRequest.responsePayloadBytes,
- client_start_time_us: networkRequest.startTimeUs,
- time_to_response_initiated_us: networkRequest.timeToResponseInitiatedUs,
- time_to_response_completed_us: networkRequest.timeToResponseCompletedUs
- };
- var perfMetric = {
- application_info: getApplicationInfo(networkRequest.performanceController.app),
- network_request_metric: networkRequestMetric
- };
- return JSON.stringify(perfMetric);
- }
- function serializeTrace(trace) {
- var traceMetric = {
- name: trace.name,
- is_auto: trace.isAuto,
- client_start_time_us: trace.startTimeUs,
- duration_us: trace.durationUs
- };
- if (Object.keys(trace.counters).length !== 0) {
- traceMetric.counters = trace.counters;
- }
- var customAttributes = trace.getAttributes();
- if (Object.keys(customAttributes).length !== 0) {
- traceMetric.custom_attributes = customAttributes;
- }
- var perfMetric = {
- application_info: getApplicationInfo(trace.performanceController.app),
- trace_metric: traceMetric
- };
- return JSON.stringify(perfMetric);
- }
- function getApplicationInfo(firebaseApp) {
- return {
- google_app_id: getAppId(firebaseApp),
- app_instance_id: getIid(),
- web_app_info: {
- sdk_version: SDK_VERSION,
- page_url: Api.getInstance().getUrl(),
- service_worker_status: getServiceWorkerStatus(),
- visibility_state: getVisibilityState(),
- effective_connection_type: getEffectiveConnectionType()
- },
- application_process_state: 0
- };
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var MAX_METRIC_NAME_LENGTH = 100;
- var RESERVED_AUTO_PREFIX = '_';
- var oobMetrics = [
- FIRST_PAINT_COUNTER_NAME,
- FIRST_CONTENTFUL_PAINT_COUNTER_NAME,
- FIRST_INPUT_DELAY_COUNTER_NAME
- ];
- /**
- * Returns true if the metric is custom and does not start with reserved prefix, or if
- * the metric is one of out of the box page load trace metrics.
- */
- function isValidMetricName(name, traceName) {
- if (name.length === 0 || name.length > MAX_METRIC_NAME_LENGTH) {
- return false;
- }
- return ((traceName &&
- traceName.startsWith(OOB_TRACE_PAGE_LOAD_PREFIX) &&
- oobMetrics.indexOf(name) > -1) ||
- !name.startsWith(RESERVED_AUTO_PREFIX));
- }
- /**
- * Converts the provided value to an integer value to be used in case of a metric.
- * @param providedValue Provided number value of the metric that needs to be converted to an integer.
- *
- * @returns Converted integer number to be set for the metric.
- */
- function convertMetricValueToInteger(providedValue) {
- var valueAsInteger = Math.floor(providedValue);
- if (valueAsInteger < providedValue) {
- consoleLogger.info("Metric value should be an Integer, setting the value as : ".concat(valueAsInteger, "."));
- }
- return valueAsInteger;
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Trace = /** @class */ (function () {
- /**
- * @param performanceController The performance controller running.
- * @param name The name of the trace.
- * @param isAuto If the trace is auto-instrumented.
- * @param traceMeasureName The name of the measure marker in user timing specification. This field
- * is only set when the trace is built for logging when the user directly uses the user timing
- * api (performance.mark and performance.measure).
- */
- function Trace(performanceController, name, isAuto, traceMeasureName) {
- if (isAuto === void 0) { isAuto = false; }
- this.performanceController = performanceController;
- this.name = name;
- this.isAuto = isAuto;
- this.state = 1 /* TraceState.UNINITIALIZED */;
- this.customAttributes = {};
- this.counters = {};
- this.api = Api.getInstance();
- this.randomId = Math.floor(Math.random() * 1000000);
- if (!this.isAuto) {
- this.traceStartMark = "".concat(TRACE_START_MARK_PREFIX, "-").concat(this.randomId, "-").concat(this.name);
- this.traceStopMark = "".concat(TRACE_STOP_MARK_PREFIX, "-").concat(this.randomId, "-").concat(this.name);
- this.traceMeasure =
- traceMeasureName ||
- "".concat(TRACE_MEASURE_PREFIX, "-").concat(this.randomId, "-").concat(this.name);
- if (traceMeasureName) {
- // For the case of direct user timing traces, no start stop will happen. The measure object
- // is already available.
- this.calculateTraceMetrics();
- }
- }
- }
- /**
- * Starts a trace. The measurement of the duration starts at this point.
- */
- Trace.prototype.start = function () {
- if (this.state !== 1 /* TraceState.UNINITIALIZED */) {
- throw ERROR_FACTORY.create("trace started" /* ErrorCode.TRACE_STARTED_BEFORE */, {
- traceName: this.name
- });
- }
- this.api.mark(this.traceStartMark);
- this.state = 2 /* TraceState.RUNNING */;
- };
- /**
- * Stops the trace. The measurement of the duration of the trace stops at this point and trace
- * is logged.
- */
- Trace.prototype.stop = function () {
- if (this.state !== 2 /* TraceState.RUNNING */) {
- throw ERROR_FACTORY.create("trace stopped" /* ErrorCode.TRACE_STOPPED_BEFORE */, {
- traceName: this.name
- });
- }
- this.state = 3 /* TraceState.TERMINATED */;
- this.api.mark(this.traceStopMark);
- this.api.measure(this.traceMeasure, this.traceStartMark, this.traceStopMark);
- this.calculateTraceMetrics();
- logTrace(this);
- };
- /**
- * Records a trace with predetermined values. If this method is used a trace is created and logged
- * directly. No need to use start and stop methods.
- * @param startTime Trace start time since epoch in millisec
- * @param duration The duraction of the trace in millisec
- * @param options An object which can optionally hold maps of custom metrics and custom attributes
- */
- Trace.prototype.record = function (startTime, duration, options) {
- if (startTime <= 0) {
- throw ERROR_FACTORY.create("nonpositive trace startTime" /* ErrorCode.NONPOSITIVE_TRACE_START_TIME */, {
- traceName: this.name
- });
- }
- if (duration <= 0) {
- throw ERROR_FACTORY.create("nonpositive trace duration" /* ErrorCode.NONPOSITIVE_TRACE_DURATION */, {
- traceName: this.name
- });
- }
- this.durationUs = Math.floor(duration * 1000);
- this.startTimeUs = Math.floor(startTime * 1000);
- if (options && options.attributes) {
- this.customAttributes = __assign({}, options.attributes);
- }
- if (options && options.metrics) {
- for (var _i = 0, _a = Object.keys(options.metrics); _i < _a.length; _i++) {
- var metricName = _a[_i];
- if (!isNaN(Number(options.metrics[metricName]))) {
- this.counters[metricName] = Math.floor(Number(options.metrics[metricName]));
- }
- }
- }
- logTrace(this);
- };
- /**
- * Increments a custom metric by a certain number or 1 if number not specified. Will create a new
- * custom metric if one with the given name does not exist. The value will be floored down to an
- * integer.
- * @param counter Name of the custom metric
- * @param numAsInteger Increment by value
- */
- Trace.prototype.incrementMetric = function (counter, numAsInteger) {
- if (numAsInteger === void 0) { numAsInteger = 1; }
- if (this.counters[counter] === undefined) {
- this.putMetric(counter, numAsInteger);
- }
- else {
- this.putMetric(counter, this.counters[counter] + numAsInteger);
- }
- };
- /**
- * Sets a custom metric to a specified value. Will create a new custom metric if one with the
- * given name does not exist. The value will be floored down to an integer.
- * @param counter Name of the custom metric
- * @param numAsInteger Set custom metric to this value
- */
- Trace.prototype.putMetric = function (counter, numAsInteger) {
- if (isValidMetricName(counter, this.name)) {
- this.counters[counter] = convertMetricValueToInteger(numAsInteger !== null && numAsInteger !== void 0 ? numAsInteger : 0);
- }
- else {
- throw ERROR_FACTORY.create("invalid custom metric name" /* ErrorCode.INVALID_CUSTOM_METRIC_NAME */, {
- customMetricName: counter
- });
- }
- };
- /**
- * Returns the value of the custom metric by that name. If a custom metric with that name does
- * not exist will return zero.
- * @param counter
- */
- Trace.prototype.getMetric = function (counter) {
- return this.counters[counter] || 0;
- };
- /**
- * Sets a custom attribute of a trace to a certain value.
- * @param attr
- * @param value
- */
- Trace.prototype.putAttribute = function (attr, value) {
- var isValidName = isValidCustomAttributeName(attr);
- var isValidValue = isValidCustomAttributeValue(value);
- if (isValidName && isValidValue) {
- this.customAttributes[attr] = value;
- return;
- }
- // Throw appropriate error when the attribute name or value is invalid.
- if (!isValidName) {
- throw ERROR_FACTORY.create("invalid attribute name" /* ErrorCode.INVALID_ATTRIBUTE_NAME */, {
- attributeName: attr
- });
- }
- if (!isValidValue) {
- throw ERROR_FACTORY.create("invalid attribute value" /* ErrorCode.INVALID_ATTRIBUTE_VALUE */, {
- attributeValue: value
- });
- }
- };
- /**
- * Retrieves the value a custom attribute of a trace is set to.
- * @param attr
- */
- Trace.prototype.getAttribute = function (attr) {
- return this.customAttributes[attr];
- };
- Trace.prototype.removeAttribute = function (attr) {
- if (this.customAttributes[attr] === undefined) {
- return;
- }
- delete this.customAttributes[attr];
- };
- Trace.prototype.getAttributes = function () {
- return __assign({}, this.customAttributes);
- };
- Trace.prototype.setStartTime = function (startTime) {
- this.startTimeUs = startTime;
- };
- Trace.prototype.setDuration = function (duration) {
- this.durationUs = duration;
- };
- /**
- * Calculates and assigns the duration and start time of the trace using the measure performance
- * entry.
- */
- Trace.prototype.calculateTraceMetrics = function () {
- var perfMeasureEntries = this.api.getEntriesByName(this.traceMeasure);
- var perfMeasureEntry = perfMeasureEntries && perfMeasureEntries[0];
- if (perfMeasureEntry) {
- this.durationUs = Math.floor(perfMeasureEntry.duration * 1000);
- this.startTimeUs = Math.floor((perfMeasureEntry.startTime + this.api.getTimeOrigin()) * 1000);
- }
- };
- /**
- * @param navigationTimings A single element array which contains the navigationTIming object of
- * the page load
- * @param paintTimings A array which contains paintTiming object of the page load
- * @param firstInputDelay First input delay in millisec
- */
- Trace.createOobTrace = function (performanceController, navigationTimings, paintTimings, firstInputDelay) {
- var route = Api.getInstance().getUrl();
- if (!route) {
- return;
- }
- var trace = new Trace(performanceController, OOB_TRACE_PAGE_LOAD_PREFIX + route, true);
- var timeOriginUs = Math.floor(Api.getInstance().getTimeOrigin() * 1000);
- trace.setStartTime(timeOriginUs);
- // navigationTimings includes only one element.
- if (navigationTimings && navigationTimings[0]) {
- trace.setDuration(Math.floor(navigationTimings[0].duration * 1000));
- trace.putMetric('domInteractive', Math.floor(navigationTimings[0].domInteractive * 1000));
- trace.putMetric('domContentLoadedEventEnd', Math.floor(navigationTimings[0].domContentLoadedEventEnd * 1000));
- trace.putMetric('loadEventEnd', Math.floor(navigationTimings[0].loadEventEnd * 1000));
- }
- var FIRST_PAINT = 'first-paint';
- var FIRST_CONTENTFUL_PAINT = 'first-contentful-paint';
- if (paintTimings) {
- var firstPaint = paintTimings.find(function (paintObject) { return paintObject.name === FIRST_PAINT; });
- if (firstPaint && firstPaint.startTime) {
- trace.putMetric(FIRST_PAINT_COUNTER_NAME, Math.floor(firstPaint.startTime * 1000));
- }
- var firstContentfulPaint = paintTimings.find(function (paintObject) { return paintObject.name === FIRST_CONTENTFUL_PAINT; });
- if (firstContentfulPaint && firstContentfulPaint.startTime) {
- trace.putMetric(FIRST_CONTENTFUL_PAINT_COUNTER_NAME, Math.floor(firstContentfulPaint.startTime * 1000));
- }
- if (firstInputDelay) {
- trace.putMetric(FIRST_INPUT_DELAY_COUNTER_NAME, Math.floor(firstInputDelay * 1000));
- }
- }
- logTrace(trace);
- };
- Trace.createUserTimingTrace = function (performanceController, measureName) {
- var trace = new Trace(performanceController, measureName, false, measureName);
- logTrace(trace);
- };
- return Trace;
- }());
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- function createNetworkRequestEntry(performanceController, entry) {
- var performanceEntry = entry;
- if (!performanceEntry || performanceEntry.responseStart === undefined) {
- return;
- }
- var timeOrigin = Api.getInstance().getTimeOrigin();
- var startTimeUs = Math.floor((performanceEntry.startTime + timeOrigin) * 1000);
- var timeToResponseInitiatedUs = performanceEntry.responseStart
- ? Math.floor((performanceEntry.responseStart - performanceEntry.startTime) * 1000)
- : undefined;
- var timeToResponseCompletedUs = Math.floor((performanceEntry.responseEnd - performanceEntry.startTime) * 1000);
- // Remove the query params from logged network request url.
- var url = performanceEntry.name && performanceEntry.name.split('?')[0];
- var networkRequest = {
- performanceController: performanceController,
- url: url,
- responsePayloadBytes: performanceEntry.transferSize,
- startTimeUs: startTimeUs,
- timeToResponseInitiatedUs: timeToResponseInitiatedUs,
- timeToResponseCompletedUs: timeToResponseCompletedUs
- };
- logNetworkRequest(networkRequest);
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var FID_WAIT_TIME_MS = 5000;
- function setupOobResources(performanceController) {
- // Do not initialize unless iid is available.
- if (!getIid()) {
- return;
- }
- // The load event might not have fired yet, and that means performance navigation timing
- // object has a duration of 0. The setup should run after all current tasks in js queue.
- setTimeout(function () { return setupOobTraces(performanceController); }, 0);
- setTimeout(function () { return setupNetworkRequests(performanceController); }, 0);
- setTimeout(function () { return setupUserTimingTraces(performanceController); }, 0);
- }
- function setupNetworkRequests(performanceController) {
- var api = Api.getInstance();
- var resources = api.getEntriesByType('resource');
- for (var _i = 0, resources_1 = resources; _i < resources_1.length; _i++) {
- var resource = resources_1[_i];
- createNetworkRequestEntry(performanceController, resource);
- }
- api.setupObserver('resource', function (entry) {
- return createNetworkRequestEntry(performanceController, entry);
- });
- }
- function setupOobTraces(performanceController) {
- var api = Api.getInstance();
- var navigationTimings = api.getEntriesByType('navigation');
- var paintTimings = api.getEntriesByType('paint');
- // If First Input Desly polyfill is added to the page, report the fid value.
- // https://github.com/GoogleChromeLabs/first-input-delay
- if (api.onFirstInputDelay) {
- // If the fid call back is not called for certain time, continue without it.
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- var timeoutId_1 = setTimeout(function () {
- Trace.createOobTrace(performanceController, navigationTimings, paintTimings);
- timeoutId_1 = undefined;
- }, FID_WAIT_TIME_MS);
- api.onFirstInputDelay(function (fid) {
- if (timeoutId_1) {
- clearTimeout(timeoutId_1);
- Trace.createOobTrace(performanceController, navigationTimings, paintTimings, fid);
- }
- });
- }
- else {
- Trace.createOobTrace(performanceController, navigationTimings, paintTimings);
- }
- }
- function setupUserTimingTraces(performanceController) {
- var api = Api.getInstance();
- // Run through the measure performance entries collected up to this point.
- var measures = api.getEntriesByType('measure');
- for (var _i = 0, measures_1 = measures; _i < measures_1.length; _i++) {
- var measure = measures_1[_i];
- createUserTimingTrace(performanceController, measure);
- }
- // Setup an observer to capture the measures from this point on.
- api.setupObserver('measure', function (entry) {
- return createUserTimingTrace(performanceController, entry);
- });
- }
- function createUserTimingTrace(performanceController, measure) {
- var measureName = measure.name;
- // Do not create a trace, if the user timing marks and measures are created by the sdk itself.
- if (measureName.substring(0, TRACE_MEASURE_PREFIX.length) ===
- TRACE_MEASURE_PREFIX) {
- return;
- }
- Trace.createUserTimingTrace(performanceController, measureName);
- }
-
- /**
- * @license
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var PerformanceController = /** @class */ (function () {
- function PerformanceController(app, installations) {
- this.app = app;
- this.installations = installations;
- this.initialized = false;
- }
- /**
- * This method *must* be called internally as part of creating a
- * PerformanceController instance.
- *
- * Currently it's not possible to pass the settings object through the
- * constructor using Components, so this method exists to be called with the
- * desired settings, to ensure nothing is collected without the user's
- * consent.
- */
- PerformanceController.prototype._init = function (settings) {
- var _this = this;
- if (this.initialized) {
- return;
- }
- if ((settings === null || settings === void 0 ? void 0 : settings.dataCollectionEnabled) !== undefined) {
- this.dataCollectionEnabled = settings.dataCollectionEnabled;
- }
- if ((settings === null || settings === void 0 ? void 0 : settings.instrumentationEnabled) !== undefined) {
- this.instrumentationEnabled = settings.instrumentationEnabled;
- }
- if (Api.getInstance().requiredApisAvailable()) {
- validateIndexedDBOpenable()
- .then(function (isAvailable) {
- if (isAvailable) {
- setupTransportService();
- getInitializationPromise(_this).then(function () { return setupOobResources(_this); }, function () { return setupOobResources(_this); });
- _this.initialized = true;
- }
- })
- .catch(function (error) {
- consoleLogger.info("Environment doesn't support IndexedDB: ".concat(error));
- });
- }
- else {
- consoleLogger.info('Firebase Performance cannot start if the browser does not support ' +
- '"Fetch" and "Promise", or cookies are disabled.');
- }
- };
- Object.defineProperty(PerformanceController.prototype, "instrumentationEnabled", {
- get: function () {
- return SettingsService.getInstance().instrumentationEnabled;
- },
- set: function (val) {
- SettingsService.getInstance().instrumentationEnabled = val;
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(PerformanceController.prototype, "dataCollectionEnabled", {
- get: function () {
- return SettingsService.getInstance().dataCollectionEnabled;
- },
- set: function (val) {
- SettingsService.getInstance().dataCollectionEnabled = val;
- },
- enumerable: false,
- configurable: true
- });
- return PerformanceController;
- }());
-
- /**
- * Firebase Performance Monitoring
- *
- * @packageDocumentation
- */
- var DEFAULT_ENTRY_NAME = '[DEFAULT]';
- /**
- * Returns a {@link FirebasePerformance} instance for the given app.
- * @param app - The {@link @firebase/app#FirebaseApp} to use.
- * @public
- */
- function getPerformance(app) {
- if (app === void 0) { app = getApp(); }
- app = getModularInstance(app);
- var provider = _getProvider(app, 'performance');
- var perfInstance = provider.getImmediate();
- return perfInstance;
- }
- /**
- * Returns a {@link FirebasePerformance} instance for the given app. Can only be called once.
- * @param app - The {@link @firebase/app#FirebaseApp} to use.
- * @param settings - Optional settings for the {@link FirebasePerformance} instance.
- * @public
- */
- function initializePerformance(app, settings) {
- app = getModularInstance(app);
- var provider = _getProvider(app, 'performance');
- // throw if an instance was already created.
- // It could happen if initializePerformance() is called more than once, or getPerformance() is called first.
- if (provider.isInitialized()) {
- var existingInstance = provider.getImmediate();
- var initialSettings = provider.getOptions();
- if (deepEqual(initialSettings, settings !== null && settings !== void 0 ? settings : {})) {
- return existingInstance;
- }
- else {
- throw ERROR_FACTORY.create("already initialized" /* ErrorCode.ALREADY_INITIALIZED */);
- }
- }
- var perfInstance = provider.initialize({
- options: settings
- });
- return perfInstance;
- }
- /**
- * Returns a new `PerformanceTrace` instance.
- * @param performance - The {@link FirebasePerformance} instance to use.
- * @param name - The name of the trace.
- * @public
- */
- function trace(performance, name) {
- performance = getModularInstance(performance);
- return new Trace(performance, name);
- }
- var factory = function (container, _a) {
- var settings = _a.options;
- // Dependencies
- var app = container.getProvider('app').getImmediate();
- var installations = container
- .getProvider('installations-internal')
- .getImmediate();
- if (app.name !== DEFAULT_ENTRY_NAME) {
- throw ERROR_FACTORY.create("FB not default" /* ErrorCode.FB_NOT_DEFAULT */);
- }
- if (typeof window === 'undefined') {
- throw ERROR_FACTORY.create("no window" /* ErrorCode.NO_WINDOW */);
- }
- setupApi(window);
- var perfInstance = new PerformanceController(app, installations);
- perfInstance._init(settings);
- return perfInstance;
- };
- function registerPerformance() {
- _registerComponent(new Component('performance', factory, "PUBLIC" /* ComponentType.PUBLIC */));
- registerVersion(name, version);
- // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
- registerVersion(name, version, 'esm5');
- }
- registerPerformance();
-
- export { getPerformance, initializePerformance, trace };
- //# sourceMappingURL=index.esm.js.map
|