@firebase/performance 0.6.10 → 0.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/esm/index.esm2017.js +1473 -1473
  2. package/dist/esm/index.esm2017.js.map +1 -1
  3. package/dist/esm/src/constants.d.ts +32 -32
  4. package/dist/esm/src/controllers/perf.d.ts +39 -39
  5. package/dist/esm/src/controllers/perf.test.d.ts +17 -17
  6. package/dist/esm/src/index.d.ts +46 -46
  7. package/dist/esm/src/index.test.d.ts +17 -17
  8. package/dist/esm/src/public_types.d.ts +136 -136
  9. package/dist/esm/src/resources/network_request.d.ts +43 -43
  10. package/dist/esm/src/resources/network_request.test.d.ts +17 -17
  11. package/dist/esm/src/resources/trace.d.ts +119 -119
  12. package/dist/esm/src/resources/trace.test.d.ts +17 -17
  13. package/dist/esm/src/services/api_service.d.ts +51 -51
  14. package/dist/esm/src/services/api_service.test.d.ts +17 -17
  15. package/dist/esm/src/services/iid_service.d.ts +21 -21
  16. package/dist/esm/src/services/iid_service.test.d.ts +17 -17
  17. package/dist/esm/src/services/initialization_service.d.ts +19 -19
  18. package/dist/esm/src/services/initialization_service.test.d.ts +17 -17
  19. package/dist/esm/src/services/oob_resources_service.d.ts +18 -18
  20. package/dist/esm/src/services/oob_resources_service.test.d.ts +17 -17
  21. package/dist/esm/src/services/perf_logger.d.ts +20 -20
  22. package/dist/esm/src/services/perf_logger.test.d.ts +17 -17
  23. package/dist/esm/src/services/remote_config_service.d.ts +18 -18
  24. package/dist/esm/src/services/remote_config_service.test.d.ts +17 -17
  25. package/dist/esm/src/services/settings_service.d.ts +32 -32
  26. package/dist/esm/src/services/transport_service.d.ts +23 -23
  27. package/dist/esm/src/services/transport_service.test.d.ts +17 -17
  28. package/dist/esm/src/utils/app_utils.d.ts +20 -20
  29. package/dist/esm/src/utils/attribute_utils.test.d.ts +17 -17
  30. package/dist/esm/src/utils/attributes_utils.d.ts +40 -40
  31. package/dist/esm/src/utils/console_logger.d.ts +18 -18
  32. package/dist/esm/src/utils/errors.d.ts +60 -60
  33. package/dist/esm/src/utils/metric_utils.d.ts +28 -28
  34. package/dist/esm/src/utils/metric_utils.test.d.ts +17 -17
  35. package/dist/esm/src/utils/string_merger.d.ts +17 -17
  36. package/dist/esm/src/utils/string_merger.test.d.ts +17 -17
  37. package/dist/esm/test/setup.d.ts +17 -17
  38. package/dist/index.cjs.js +1473 -1473
  39. package/dist/index.cjs.js.map +1 -1
  40. package/dist/src/constants.d.ts +32 -32
  41. package/dist/src/controllers/perf.d.ts +39 -39
  42. package/dist/src/controllers/perf.test.d.ts +17 -17
  43. package/dist/src/index.d.ts +46 -46
  44. package/dist/src/index.test.d.ts +17 -17
  45. package/dist/src/public_types.d.ts +136 -136
  46. package/dist/src/resources/network_request.d.ts +43 -43
  47. package/dist/src/resources/network_request.test.d.ts +17 -17
  48. package/dist/src/resources/trace.d.ts +119 -119
  49. package/dist/src/resources/trace.test.d.ts +17 -17
  50. package/dist/src/services/api_service.d.ts +51 -51
  51. package/dist/src/services/api_service.test.d.ts +17 -17
  52. package/dist/src/services/iid_service.d.ts +21 -21
  53. package/dist/src/services/iid_service.test.d.ts +17 -17
  54. package/dist/src/services/initialization_service.d.ts +19 -19
  55. package/dist/src/services/initialization_service.test.d.ts +17 -17
  56. package/dist/src/services/oob_resources_service.d.ts +18 -18
  57. package/dist/src/services/oob_resources_service.test.d.ts +17 -17
  58. package/dist/src/services/perf_logger.d.ts +20 -20
  59. package/dist/src/services/perf_logger.test.d.ts +17 -17
  60. package/dist/src/services/remote_config_service.d.ts +18 -18
  61. package/dist/src/services/remote_config_service.test.d.ts +17 -17
  62. package/dist/src/services/settings_service.d.ts +32 -32
  63. package/dist/src/services/transport_service.d.ts +23 -23
  64. package/dist/src/services/transport_service.test.d.ts +17 -17
  65. package/dist/src/utils/app_utils.d.ts +20 -20
  66. package/dist/src/utils/attribute_utils.test.d.ts +17 -17
  67. package/dist/src/utils/attributes_utils.d.ts +40 -40
  68. package/dist/src/utils/console_logger.d.ts +18 -18
  69. package/dist/src/utils/errors.d.ts +60 -60
  70. package/dist/src/utils/metric_utils.d.ts +28 -28
  71. package/dist/src/utils/metric_utils.test.d.ts +17 -17
  72. package/dist/src/utils/string_merger.d.ts +17 -17
  73. package/dist/src/utils/string_merger.test.d.ts +17 -17
  74. package/dist/test/setup.d.ts +17 -17
  75. package/package.json +7 -7
@@ -5,1516 +5,1516 @@ import { Component } from '@firebase/component';
5
5
  import '@firebase/installations';
6
6
 
7
7
  const name = "@firebase/performance";
8
- const version = "0.6.10";
8
+ const version = "0.6.11";
9
9
 
10
- /**
11
- * @license
12
- * Copyright 2020 Google LLC
13
- *
14
- * Licensed under the Apache License, Version 2.0 (the "License");
15
- * you may not use this file except in compliance with the License.
16
- * You may obtain a copy of the License at
17
- *
18
- * http://www.apache.org/licenses/LICENSE-2.0
19
- *
20
- * Unless required by applicable law or agreed to in writing, software
21
- * distributed under the License is distributed on an "AS IS" BASIS,
22
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
- * See the License for the specific language governing permissions and
24
- * limitations under the License.
25
- */
26
- const SDK_VERSION = version;
27
- /** The prefix for start User Timing marks used for creating Traces. */
28
- const TRACE_START_MARK_PREFIX = 'FB-PERF-TRACE-START';
29
- /** The prefix for stop User Timing marks used for creating Traces. */
30
- const TRACE_STOP_MARK_PREFIX = 'FB-PERF-TRACE-STOP';
31
- /** The prefix for User Timing measure used for creating Traces. */
32
- const TRACE_MEASURE_PREFIX = 'FB-PERF-TRACE-MEASURE';
33
- /** The prefix for out of the box page load Trace name. */
34
- const OOB_TRACE_PAGE_LOAD_PREFIX = '_wt_';
35
- const FIRST_PAINT_COUNTER_NAME = '_fp';
36
- const FIRST_CONTENTFUL_PAINT_COUNTER_NAME = '_fcp';
37
- const FIRST_INPUT_DELAY_COUNTER_NAME = '_fid';
38
- const CONFIG_LOCAL_STORAGE_KEY = '@firebase/performance/config';
39
- const CONFIG_EXPIRY_LOCAL_STORAGE_KEY = '@firebase/performance/configexpire';
40
- const SERVICE = 'performance';
10
+ /**
11
+ * @license
12
+ * Copyright 2020 Google LLC
13
+ *
14
+ * Licensed under the Apache License, Version 2.0 (the "License");
15
+ * you may not use this file except in compliance with the License.
16
+ * You may obtain a copy of the License at
17
+ *
18
+ * http://www.apache.org/licenses/LICENSE-2.0
19
+ *
20
+ * Unless required by applicable law or agreed to in writing, software
21
+ * distributed under the License is distributed on an "AS IS" BASIS,
22
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ * See the License for the specific language governing permissions and
24
+ * limitations under the License.
25
+ */
26
+ const SDK_VERSION = version;
27
+ /** The prefix for start User Timing marks used for creating Traces. */
28
+ const TRACE_START_MARK_PREFIX = 'FB-PERF-TRACE-START';
29
+ /** The prefix for stop User Timing marks used for creating Traces. */
30
+ const TRACE_STOP_MARK_PREFIX = 'FB-PERF-TRACE-STOP';
31
+ /** The prefix for User Timing measure used for creating Traces. */
32
+ const TRACE_MEASURE_PREFIX = 'FB-PERF-TRACE-MEASURE';
33
+ /** The prefix for out of the box page load Trace name. */
34
+ const OOB_TRACE_PAGE_LOAD_PREFIX = '_wt_';
35
+ const FIRST_PAINT_COUNTER_NAME = '_fp';
36
+ const FIRST_CONTENTFUL_PAINT_COUNTER_NAME = '_fcp';
37
+ const FIRST_INPUT_DELAY_COUNTER_NAME = '_fid';
38
+ const CONFIG_LOCAL_STORAGE_KEY = '@firebase/performance/config';
39
+ const CONFIG_EXPIRY_LOCAL_STORAGE_KEY = '@firebase/performance/configexpire';
40
+ const SERVICE = 'performance';
41
41
  const SERVICE_NAME = 'Performance';
42
42
 
43
- /**
44
- * @license
45
- * Copyright 2020 Google LLC
46
- *
47
- * Licensed under the Apache License, Version 2.0 (the "License");
48
- * you may not use this file except in compliance with the License.
49
- * You may obtain a copy of the License at
50
- *
51
- * http://www.apache.org/licenses/LICENSE-2.0
52
- *
53
- * Unless required by applicable law or agreed to in writing, software
54
- * distributed under the License is distributed on an "AS IS" BASIS,
55
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
56
- * See the License for the specific language governing permissions and
57
- * limitations under the License.
58
- */
59
- const ERROR_DESCRIPTION_MAP = {
60
- ["trace started" /* ErrorCode.TRACE_STARTED_BEFORE */]: 'Trace {$traceName} was started before.',
61
- ["trace stopped" /* ErrorCode.TRACE_STOPPED_BEFORE */]: 'Trace {$traceName} is not running.',
62
- ["nonpositive trace startTime" /* ErrorCode.NONPOSITIVE_TRACE_START_TIME */]: 'Trace {$traceName} startTime should be positive.',
63
- ["nonpositive trace duration" /* ErrorCode.NONPOSITIVE_TRACE_DURATION */]: 'Trace {$traceName} duration should be positive.',
64
- ["no window" /* ErrorCode.NO_WINDOW */]: 'Window is not available.',
65
- ["no app id" /* ErrorCode.NO_APP_ID */]: 'App id is not available.',
66
- ["no project id" /* ErrorCode.NO_PROJECT_ID */]: 'Project id is not available.',
67
- ["no api key" /* ErrorCode.NO_API_KEY */]: 'Api key is not available.',
68
- ["invalid cc log" /* ErrorCode.INVALID_CC_LOG */]: 'Attempted to queue invalid cc event',
69
- ["FB not default" /* ErrorCode.FB_NOT_DEFAULT */]: 'Performance can only start when Firebase app instance is the default one.',
70
- ["RC response not ok" /* ErrorCode.RC_NOT_OK */]: 'RC response is not ok',
71
- ["invalid attribute name" /* ErrorCode.INVALID_ATTRIBUTE_NAME */]: 'Attribute name {$attributeName} is invalid.',
72
- ["invalid attribute value" /* ErrorCode.INVALID_ATTRIBUTE_VALUE */]: 'Attribute value {$attributeValue} is invalid.',
73
- ["invalid custom metric name" /* ErrorCode.INVALID_CUSTOM_METRIC_NAME */]: 'Custom metric name {$customMetricName} is invalid',
74
- ["invalid String merger input" /* ErrorCode.INVALID_STRING_MERGER_PARAMETER */]: 'Input for String merger is invalid, contact support team to resolve.',
75
- ["already initialized" /* ErrorCode.ALREADY_INITIALIZED */]: 'initializePerformance() has already been called with ' +
76
- 'different options. To avoid this error, call initializePerformance() with the ' +
77
- 'same options as when it was originally called, or call getPerformance() to return the' +
78
- ' already initialized instance.'
79
- };
43
+ /**
44
+ * @license
45
+ * Copyright 2020 Google LLC
46
+ *
47
+ * Licensed under the Apache License, Version 2.0 (the "License");
48
+ * you may not use this file except in compliance with the License.
49
+ * You may obtain a copy of the License at
50
+ *
51
+ * http://www.apache.org/licenses/LICENSE-2.0
52
+ *
53
+ * Unless required by applicable law or agreed to in writing, software
54
+ * distributed under the License is distributed on an "AS IS" BASIS,
55
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
56
+ * See the License for the specific language governing permissions and
57
+ * limitations under the License.
58
+ */
59
+ const ERROR_DESCRIPTION_MAP = {
60
+ ["trace started" /* ErrorCode.TRACE_STARTED_BEFORE */]: 'Trace {$traceName} was started before.',
61
+ ["trace stopped" /* ErrorCode.TRACE_STOPPED_BEFORE */]: 'Trace {$traceName} is not running.',
62
+ ["nonpositive trace startTime" /* ErrorCode.NONPOSITIVE_TRACE_START_TIME */]: 'Trace {$traceName} startTime should be positive.',
63
+ ["nonpositive trace duration" /* ErrorCode.NONPOSITIVE_TRACE_DURATION */]: 'Trace {$traceName} duration should be positive.',
64
+ ["no window" /* ErrorCode.NO_WINDOW */]: 'Window is not available.',
65
+ ["no app id" /* ErrorCode.NO_APP_ID */]: 'App id is not available.',
66
+ ["no project id" /* ErrorCode.NO_PROJECT_ID */]: 'Project id is not available.',
67
+ ["no api key" /* ErrorCode.NO_API_KEY */]: 'Api key is not available.',
68
+ ["invalid cc log" /* ErrorCode.INVALID_CC_LOG */]: 'Attempted to queue invalid cc event',
69
+ ["FB not default" /* ErrorCode.FB_NOT_DEFAULT */]: 'Performance can only start when Firebase app instance is the default one.',
70
+ ["RC response not ok" /* ErrorCode.RC_NOT_OK */]: 'RC response is not ok',
71
+ ["invalid attribute name" /* ErrorCode.INVALID_ATTRIBUTE_NAME */]: 'Attribute name {$attributeName} is invalid.',
72
+ ["invalid attribute value" /* ErrorCode.INVALID_ATTRIBUTE_VALUE */]: 'Attribute value {$attributeValue} is invalid.',
73
+ ["invalid custom metric name" /* ErrorCode.INVALID_CUSTOM_METRIC_NAME */]: 'Custom metric name {$customMetricName} is invalid',
74
+ ["invalid String merger input" /* ErrorCode.INVALID_STRING_MERGER_PARAMETER */]: 'Input for String merger is invalid, contact support team to resolve.',
75
+ ["already initialized" /* ErrorCode.ALREADY_INITIALIZED */]: 'initializePerformance() has already been called with ' +
76
+ 'different options. To avoid this error, call initializePerformance() with the ' +
77
+ 'same options as when it was originally called, or call getPerformance() to return the' +
78
+ ' already initialized instance.'
79
+ };
80
80
  const ERROR_FACTORY = new ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP);
81
81
 
82
- /**
83
- * @license
84
- * Copyright 2020 Google LLC
85
- *
86
- * Licensed under the Apache License, Version 2.0 (the "License");
87
- * you may not use this file except in compliance with the License.
88
- * You may obtain a copy of the License at
89
- *
90
- * http://www.apache.org/licenses/LICENSE-2.0
91
- *
92
- * Unless required by applicable law or agreed to in writing, software
93
- * distributed under the License is distributed on an "AS IS" BASIS,
94
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95
- * See the License for the specific language governing permissions and
96
- * limitations under the License.
97
- */
98
- const consoleLogger = new Logger(SERVICE_NAME);
82
+ /**
83
+ * @license
84
+ * Copyright 2020 Google LLC
85
+ *
86
+ * Licensed under the Apache License, Version 2.0 (the "License");
87
+ * you may not use this file except in compliance with the License.
88
+ * You may obtain a copy of the License at
89
+ *
90
+ * http://www.apache.org/licenses/LICENSE-2.0
91
+ *
92
+ * Unless required by applicable law or agreed to in writing, software
93
+ * distributed under the License is distributed on an "AS IS" BASIS,
94
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95
+ * See the License for the specific language governing permissions and
96
+ * limitations under the License.
97
+ */
98
+ const consoleLogger = new Logger(SERVICE_NAME);
99
99
  consoleLogger.logLevel = LogLevel.INFO;
100
100
 
101
- /**
102
- * @license
103
- * Copyright 2020 Google LLC
104
- *
105
- * Licensed under the Apache License, Version 2.0 (the "License");
106
- * you may not use this file except in compliance with the License.
107
- * You may obtain a copy of the License at
108
- *
109
- * http://www.apache.org/licenses/LICENSE-2.0
110
- *
111
- * Unless required by applicable law or agreed to in writing, software
112
- * distributed under the License is distributed on an "AS IS" BASIS,
113
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114
- * See the License for the specific language governing permissions and
115
- * limitations under the License.
116
- */
117
- let apiInstance;
118
- let windowInstance;
119
- /**
120
- * This class holds a reference to various browser related objects injected by
121
- * set methods.
122
- */
123
- class Api {
124
- constructor(window) {
125
- this.window = window;
126
- if (!window) {
127
- throw ERROR_FACTORY.create("no window" /* ErrorCode.NO_WINDOW */);
128
- }
129
- this.performance = window.performance;
130
- this.PerformanceObserver = window.PerformanceObserver;
131
- this.windowLocation = window.location;
132
- this.navigator = window.navigator;
133
- this.document = window.document;
134
- if (this.navigator && this.navigator.cookieEnabled) {
135
- // If user blocks cookies on the browser, accessing localStorage will
136
- // throw an exception.
137
- this.localStorage = window.localStorage;
138
- }
139
- if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) {
140
- this.onFirstInputDelay = window.perfMetrics.onFirstInputDelay;
141
- }
142
- }
143
- getUrl() {
144
- // Do not capture the string query part of url.
145
- return this.windowLocation.href.split('?')[0];
146
- }
147
- mark(name) {
148
- if (!this.performance || !this.performance.mark) {
149
- return;
150
- }
151
- this.performance.mark(name);
152
- }
153
- measure(measureName, mark1, mark2) {
154
- if (!this.performance || !this.performance.measure) {
155
- return;
156
- }
157
- this.performance.measure(measureName, mark1, mark2);
158
- }
159
- getEntriesByType(type) {
160
- if (!this.performance || !this.performance.getEntriesByType) {
161
- return [];
162
- }
163
- return this.performance.getEntriesByType(type);
164
- }
165
- getEntriesByName(name) {
166
- if (!this.performance || !this.performance.getEntriesByName) {
167
- return [];
168
- }
169
- return this.performance.getEntriesByName(name);
170
- }
171
- getTimeOrigin() {
172
- // Polyfill the time origin with performance.timing.navigationStart.
173
- return (this.performance &&
174
- (this.performance.timeOrigin || this.performance.timing.navigationStart));
175
- }
176
- requiredApisAvailable() {
177
- if (!fetch || !Promise || !areCookiesEnabled()) {
178
- consoleLogger.info('Firebase Performance cannot start if browser does not support fetch and Promise or cookie is disabled.');
179
- return false;
180
- }
181
- if (!isIndexedDBAvailable()) {
182
- consoleLogger.info('IndexedDB is not supported by current browser');
183
- return false;
184
- }
185
- return true;
186
- }
187
- setupObserver(entryType, callback) {
188
- if (!this.PerformanceObserver) {
189
- return;
190
- }
191
- const observer = new this.PerformanceObserver(list => {
192
- for (const entry of list.getEntries()) {
193
- // `entry` is a PerformanceEntry instance.
194
- callback(entry);
195
- }
196
- });
197
- // Start observing the entry types you care about.
198
- observer.observe({ entryTypes: [entryType] });
199
- }
200
- static getInstance() {
201
- if (apiInstance === undefined) {
202
- apiInstance = new Api(windowInstance);
203
- }
204
- return apiInstance;
205
- }
206
- }
207
- function setupApi(window) {
208
- windowInstance = window;
101
+ /**
102
+ * @license
103
+ * Copyright 2020 Google LLC
104
+ *
105
+ * Licensed under the Apache License, Version 2.0 (the "License");
106
+ * you may not use this file except in compliance with the License.
107
+ * You may obtain a copy of the License at
108
+ *
109
+ * http://www.apache.org/licenses/LICENSE-2.0
110
+ *
111
+ * Unless required by applicable law or agreed to in writing, software
112
+ * distributed under the License is distributed on an "AS IS" BASIS,
113
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114
+ * See the License for the specific language governing permissions and
115
+ * limitations under the License.
116
+ */
117
+ let apiInstance;
118
+ let windowInstance;
119
+ /**
120
+ * This class holds a reference to various browser related objects injected by
121
+ * set methods.
122
+ */
123
+ class Api {
124
+ constructor(window) {
125
+ this.window = window;
126
+ if (!window) {
127
+ throw ERROR_FACTORY.create("no window" /* ErrorCode.NO_WINDOW */);
128
+ }
129
+ this.performance = window.performance;
130
+ this.PerformanceObserver = window.PerformanceObserver;
131
+ this.windowLocation = window.location;
132
+ this.navigator = window.navigator;
133
+ this.document = window.document;
134
+ if (this.navigator && this.navigator.cookieEnabled) {
135
+ // If user blocks cookies on the browser, accessing localStorage will
136
+ // throw an exception.
137
+ this.localStorage = window.localStorage;
138
+ }
139
+ if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) {
140
+ this.onFirstInputDelay = window.perfMetrics.onFirstInputDelay;
141
+ }
142
+ }
143
+ getUrl() {
144
+ // Do not capture the string query part of url.
145
+ return this.windowLocation.href.split('?')[0];
146
+ }
147
+ mark(name) {
148
+ if (!this.performance || !this.performance.mark) {
149
+ return;
150
+ }
151
+ this.performance.mark(name);
152
+ }
153
+ measure(measureName, mark1, mark2) {
154
+ if (!this.performance || !this.performance.measure) {
155
+ return;
156
+ }
157
+ this.performance.measure(measureName, mark1, mark2);
158
+ }
159
+ getEntriesByType(type) {
160
+ if (!this.performance || !this.performance.getEntriesByType) {
161
+ return [];
162
+ }
163
+ return this.performance.getEntriesByType(type);
164
+ }
165
+ getEntriesByName(name) {
166
+ if (!this.performance || !this.performance.getEntriesByName) {
167
+ return [];
168
+ }
169
+ return this.performance.getEntriesByName(name);
170
+ }
171
+ getTimeOrigin() {
172
+ // Polyfill the time origin with performance.timing.navigationStart.
173
+ return (this.performance &&
174
+ (this.performance.timeOrigin || this.performance.timing.navigationStart));
175
+ }
176
+ requiredApisAvailable() {
177
+ if (!fetch || !Promise || !areCookiesEnabled()) {
178
+ consoleLogger.info('Firebase Performance cannot start if browser does not support fetch and Promise or cookie is disabled.');
179
+ return false;
180
+ }
181
+ if (!isIndexedDBAvailable()) {
182
+ consoleLogger.info('IndexedDB is not supported by current browser');
183
+ return false;
184
+ }
185
+ return true;
186
+ }
187
+ setupObserver(entryType, callback) {
188
+ if (!this.PerformanceObserver) {
189
+ return;
190
+ }
191
+ const observer = new this.PerformanceObserver(list => {
192
+ for (const entry of list.getEntries()) {
193
+ // `entry` is a PerformanceEntry instance.
194
+ callback(entry);
195
+ }
196
+ });
197
+ // Start observing the entry types you care about.
198
+ observer.observe({ entryTypes: [entryType] });
199
+ }
200
+ static getInstance() {
201
+ if (apiInstance === undefined) {
202
+ apiInstance = new Api(windowInstance);
203
+ }
204
+ return apiInstance;
205
+ }
206
+ }
207
+ function setupApi(window) {
208
+ windowInstance = window;
209
209
  }
210
210
 
211
- /**
212
- * @license
213
- * Copyright 2020 Google LLC
214
- *
215
- * Licensed under the Apache License, Version 2.0 (the "License");
216
- * you may not use this file except in compliance with the License.
217
- * You may obtain a copy of the License at
218
- *
219
- * http://www.apache.org/licenses/LICENSE-2.0
220
- *
221
- * Unless required by applicable law or agreed to in writing, software
222
- * distributed under the License is distributed on an "AS IS" BASIS,
223
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
224
- * See the License for the specific language governing permissions and
225
- * limitations under the License.
226
- */
227
- let iid;
228
- function getIidPromise(installationsService) {
229
- const iidPromise = installationsService.getId();
230
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
231
- iidPromise.then((iidVal) => {
232
- iid = iidVal;
233
- });
234
- return iidPromise;
235
- }
236
- // This method should be used after the iid is retrieved by getIidPromise method.
237
- function getIid() {
238
- return iid;
239
- }
240
- function getAuthTokenPromise(installationsService) {
241
- const authTokenPromise = installationsService.getToken();
242
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
243
- authTokenPromise.then((authTokenVal) => {
244
- });
245
- return authTokenPromise;
211
+ /**
212
+ * @license
213
+ * Copyright 2020 Google LLC
214
+ *
215
+ * Licensed under the Apache License, Version 2.0 (the "License");
216
+ * you may not use this file except in compliance with the License.
217
+ * You may obtain a copy of the License at
218
+ *
219
+ * http://www.apache.org/licenses/LICENSE-2.0
220
+ *
221
+ * Unless required by applicable law or agreed to in writing, software
222
+ * distributed under the License is distributed on an "AS IS" BASIS,
223
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
224
+ * See the License for the specific language governing permissions and
225
+ * limitations under the License.
226
+ */
227
+ let iid;
228
+ function getIidPromise(installationsService) {
229
+ const iidPromise = installationsService.getId();
230
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
231
+ iidPromise.then((iidVal) => {
232
+ iid = iidVal;
233
+ });
234
+ return iidPromise;
235
+ }
236
+ // This method should be used after the iid is retrieved by getIidPromise method.
237
+ function getIid() {
238
+ return iid;
239
+ }
240
+ function getAuthTokenPromise(installationsService) {
241
+ const authTokenPromise = installationsService.getToken();
242
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
243
+ authTokenPromise.then((authTokenVal) => {
244
+ });
245
+ return authTokenPromise;
246
246
  }
247
247
 
248
- /**
249
- * @license
250
- * Copyright 2020 Google LLC
251
- *
252
- * Licensed under the Apache License, Version 2.0 (the "License");
253
- * you may not use this file except in compliance with the License.
254
- * You may obtain a copy of the License at
255
- *
256
- * http://www.apache.org/licenses/LICENSE-2.0
257
- *
258
- * Unless required by applicable law or agreed to in writing, software
259
- * distributed under the License is distributed on an "AS IS" BASIS,
260
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
261
- * See the License for the specific language governing permissions and
262
- * limitations under the License.
263
- */
264
- function mergeStrings(part1, part2) {
265
- const sizeDiff = part1.length - part2.length;
266
- if (sizeDiff < 0 || sizeDiff > 1) {
267
- throw ERROR_FACTORY.create("invalid String merger input" /* ErrorCode.INVALID_STRING_MERGER_PARAMETER */);
268
- }
269
- const resultArray = [];
270
- for (let i = 0; i < part1.length; i++) {
271
- resultArray.push(part1.charAt(i));
272
- if (part2.length > i) {
273
- resultArray.push(part2.charAt(i));
274
- }
275
- }
276
- return resultArray.join('');
248
+ /**
249
+ * @license
250
+ * Copyright 2020 Google LLC
251
+ *
252
+ * Licensed under the Apache License, Version 2.0 (the "License");
253
+ * you may not use this file except in compliance with the License.
254
+ * You may obtain a copy of the License at
255
+ *
256
+ * http://www.apache.org/licenses/LICENSE-2.0
257
+ *
258
+ * Unless required by applicable law or agreed to in writing, software
259
+ * distributed under the License is distributed on an "AS IS" BASIS,
260
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
261
+ * See the License for the specific language governing permissions and
262
+ * limitations under the License.
263
+ */
264
+ function mergeStrings(part1, part2) {
265
+ const sizeDiff = part1.length - part2.length;
266
+ if (sizeDiff < 0 || sizeDiff > 1) {
267
+ throw ERROR_FACTORY.create("invalid String merger input" /* ErrorCode.INVALID_STRING_MERGER_PARAMETER */);
268
+ }
269
+ const resultArray = [];
270
+ for (let i = 0; i < part1.length; i++) {
271
+ resultArray.push(part1.charAt(i));
272
+ if (part2.length > i) {
273
+ resultArray.push(part2.charAt(i));
274
+ }
275
+ }
276
+ return resultArray.join('');
277
277
  }
278
278
 
279
- /**
280
- * @license
281
- * Copyright 2019 Google LLC
282
- *
283
- * Licensed under the Apache License, Version 2.0 (the "License");
284
- * you may not use this file except in compliance with the License.
285
- * You may obtain a copy of the License at
286
- *
287
- * http://www.apache.org/licenses/LICENSE-2.0
288
- *
289
- * Unless required by applicable law or agreed to in writing, software
290
- * distributed under the License is distributed on an "AS IS" BASIS,
291
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
292
- * See the License for the specific language governing permissions and
293
- * limitations under the License.
294
- */
295
- let settingsServiceInstance;
296
- class SettingsService {
297
- constructor() {
298
- // The variable which controls logging of automatic traces and HTTP/S network monitoring.
299
- this.instrumentationEnabled = true;
300
- // The variable which controls logging of custom traces.
301
- this.dataCollectionEnabled = true;
302
- // Configuration flags set through remote config.
303
- this.loggingEnabled = false;
304
- // Sampling rate between 0 and 1.
305
- this.tracesSamplingRate = 1;
306
- this.networkRequestsSamplingRate = 1;
307
- // Address of logging service.
308
- this.logEndPointUrl = 'https://firebaselogging.googleapis.com/v0cc/log?format=json_proto';
309
- // Performance event transport endpoint URL which should be compatible with proto3.
310
- // New Address for transport service, not configurable via Remote Config.
311
- this.flTransportEndpointUrl = mergeStrings('hts/frbslgigp.ogepscmv/ieo/eaylg', 'tp:/ieaeogn-agolai.o/1frlglgc/o');
312
- this.transportKey = mergeStrings('AzSC8r6ReiGqFMyfvgow', 'Iayx0u-XT3vksVM-pIV');
313
- // Source type for performance event logs.
314
- this.logSource = 462;
315
- // Flags which control per session logging of traces and network requests.
316
- this.logTraceAfterSampling = false;
317
- this.logNetworkAfterSampling = false;
318
- // TTL of config retrieved from remote config in hours.
319
- this.configTimeToLive = 12;
320
- }
321
- getFlTransportFullUrl() {
322
- return this.flTransportEndpointUrl.concat('?key=', this.transportKey);
323
- }
324
- static getInstance() {
325
- if (settingsServiceInstance === undefined) {
326
- settingsServiceInstance = new SettingsService();
327
- }
328
- return settingsServiceInstance;
329
- }
279
+ /**
280
+ * @license
281
+ * Copyright 2019 Google LLC
282
+ *
283
+ * Licensed under the Apache License, Version 2.0 (the "License");
284
+ * you may not use this file except in compliance with the License.
285
+ * You may obtain a copy of the License at
286
+ *
287
+ * http://www.apache.org/licenses/LICENSE-2.0
288
+ *
289
+ * Unless required by applicable law or agreed to in writing, software
290
+ * distributed under the License is distributed on an "AS IS" BASIS,
291
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
292
+ * See the License for the specific language governing permissions and
293
+ * limitations under the License.
294
+ */
295
+ let settingsServiceInstance;
296
+ class SettingsService {
297
+ constructor() {
298
+ // The variable which controls logging of automatic traces and HTTP/S network monitoring.
299
+ this.instrumentationEnabled = true;
300
+ // The variable which controls logging of custom traces.
301
+ this.dataCollectionEnabled = true;
302
+ // Configuration flags set through remote config.
303
+ this.loggingEnabled = false;
304
+ // Sampling rate between 0 and 1.
305
+ this.tracesSamplingRate = 1;
306
+ this.networkRequestsSamplingRate = 1;
307
+ // Address of logging service.
308
+ this.logEndPointUrl = 'https://firebaselogging.googleapis.com/v0cc/log?format=json_proto';
309
+ // Performance event transport endpoint URL which should be compatible with proto3.
310
+ // New Address for transport service, not configurable via Remote Config.
311
+ this.flTransportEndpointUrl = mergeStrings('hts/frbslgigp.ogepscmv/ieo/eaylg', 'tp:/ieaeogn-agolai.o/1frlglgc/o');
312
+ this.transportKey = mergeStrings('AzSC8r6ReiGqFMyfvgow', 'Iayx0u-XT3vksVM-pIV');
313
+ // Source type for performance event logs.
314
+ this.logSource = 462;
315
+ // Flags which control per session logging of traces and network requests.
316
+ this.logTraceAfterSampling = false;
317
+ this.logNetworkAfterSampling = false;
318
+ // TTL of config retrieved from remote config in hours.
319
+ this.configTimeToLive = 12;
320
+ }
321
+ getFlTransportFullUrl() {
322
+ return this.flTransportEndpointUrl.concat('?key=', this.transportKey);
323
+ }
324
+ static getInstance() {
325
+ if (settingsServiceInstance === undefined) {
326
+ settingsServiceInstance = new SettingsService();
327
+ }
328
+ return settingsServiceInstance;
329
+ }
330
330
  }
331
331
 
332
- /**
333
- * @license
334
- * Copyright 2020 Google LLC
335
- *
336
- * Licensed under the Apache License, Version 2.0 (the "License");
337
- * you may not use this file except in compliance with the License.
338
- * You may obtain a copy of the License at
339
- *
340
- * http://www.apache.org/licenses/LICENSE-2.0
341
- *
342
- * Unless required by applicable law or agreed to in writing, software
343
- * distributed under the License is distributed on an "AS IS" BASIS,
344
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
345
- * See the License for the specific language governing permissions and
346
- * limitations under the License.
347
- */
348
- var VisibilityState;
349
- (function (VisibilityState) {
350
- VisibilityState[VisibilityState["UNKNOWN"] = 0] = "UNKNOWN";
351
- VisibilityState[VisibilityState["VISIBLE"] = 1] = "VISIBLE";
352
- VisibilityState[VisibilityState["HIDDEN"] = 2] = "HIDDEN";
353
- })(VisibilityState || (VisibilityState = {}));
354
- const RESERVED_ATTRIBUTE_PREFIXES = ['firebase_', 'google_', 'ga_'];
355
- const ATTRIBUTE_FORMAT_REGEX = new RegExp('^[a-zA-Z]\\w*$');
356
- const MAX_ATTRIBUTE_NAME_LENGTH = 40;
357
- const MAX_ATTRIBUTE_VALUE_LENGTH = 100;
358
- function getServiceWorkerStatus() {
359
- const navigator = Api.getInstance().navigator;
360
- if (navigator === null || navigator === void 0 ? void 0 : navigator.serviceWorker) {
361
- if (navigator.serviceWorker.controller) {
362
- return 2 /* ServiceWorkerStatus.CONTROLLED */;
363
- }
364
- else {
365
- return 3 /* ServiceWorkerStatus.UNCONTROLLED */;
366
- }
367
- }
368
- else {
369
- return 1 /* ServiceWorkerStatus.UNSUPPORTED */;
370
- }
371
- }
372
- function getVisibilityState() {
373
- const document = Api.getInstance().document;
374
- const visibilityState = document.visibilityState;
375
- switch (visibilityState) {
376
- case 'visible':
377
- return VisibilityState.VISIBLE;
378
- case 'hidden':
379
- return VisibilityState.HIDDEN;
380
- default:
381
- return VisibilityState.UNKNOWN;
382
- }
383
- }
384
- function getEffectiveConnectionType() {
385
- const navigator = Api.getInstance().navigator;
386
- const navigatorConnection = navigator.connection;
387
- const effectiveType = navigatorConnection && navigatorConnection.effectiveType;
388
- switch (effectiveType) {
389
- case 'slow-2g':
390
- return 1 /* EffectiveConnectionType.CONNECTION_SLOW_2G */;
391
- case '2g':
392
- return 2 /* EffectiveConnectionType.CONNECTION_2G */;
393
- case '3g':
394
- return 3 /* EffectiveConnectionType.CONNECTION_3G */;
395
- case '4g':
396
- return 4 /* EffectiveConnectionType.CONNECTION_4G */;
397
- default:
398
- return 0 /* EffectiveConnectionType.UNKNOWN */;
399
- }
400
- }
401
- function isValidCustomAttributeName(name) {
402
- if (name.length === 0 || name.length > MAX_ATTRIBUTE_NAME_LENGTH) {
403
- return false;
404
- }
405
- const matchesReservedPrefix = RESERVED_ATTRIBUTE_PREFIXES.some(prefix => name.startsWith(prefix));
406
- return !matchesReservedPrefix && !!name.match(ATTRIBUTE_FORMAT_REGEX);
407
- }
408
- function isValidCustomAttributeValue(value) {
409
- return value.length !== 0 && value.length <= MAX_ATTRIBUTE_VALUE_LENGTH;
332
+ /**
333
+ * @license
334
+ * Copyright 2020 Google LLC
335
+ *
336
+ * Licensed under the Apache License, Version 2.0 (the "License");
337
+ * you may not use this file except in compliance with the License.
338
+ * You may obtain a copy of the License at
339
+ *
340
+ * http://www.apache.org/licenses/LICENSE-2.0
341
+ *
342
+ * Unless required by applicable law or agreed to in writing, software
343
+ * distributed under the License is distributed on an "AS IS" BASIS,
344
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
345
+ * See the License for the specific language governing permissions and
346
+ * limitations under the License.
347
+ */
348
+ var VisibilityState;
349
+ (function (VisibilityState) {
350
+ VisibilityState[VisibilityState["UNKNOWN"] = 0] = "UNKNOWN";
351
+ VisibilityState[VisibilityState["VISIBLE"] = 1] = "VISIBLE";
352
+ VisibilityState[VisibilityState["HIDDEN"] = 2] = "HIDDEN";
353
+ })(VisibilityState || (VisibilityState = {}));
354
+ const RESERVED_ATTRIBUTE_PREFIXES = ['firebase_', 'google_', 'ga_'];
355
+ const ATTRIBUTE_FORMAT_REGEX = new RegExp('^[a-zA-Z]\\w*$');
356
+ const MAX_ATTRIBUTE_NAME_LENGTH = 40;
357
+ const MAX_ATTRIBUTE_VALUE_LENGTH = 100;
358
+ function getServiceWorkerStatus() {
359
+ const navigator = Api.getInstance().navigator;
360
+ if (navigator === null || navigator === void 0 ? void 0 : navigator.serviceWorker) {
361
+ if (navigator.serviceWorker.controller) {
362
+ return 2 /* ServiceWorkerStatus.CONTROLLED */;
363
+ }
364
+ else {
365
+ return 3 /* ServiceWorkerStatus.UNCONTROLLED */;
366
+ }
367
+ }
368
+ else {
369
+ return 1 /* ServiceWorkerStatus.UNSUPPORTED */;
370
+ }
371
+ }
372
+ function getVisibilityState() {
373
+ const document = Api.getInstance().document;
374
+ const visibilityState = document.visibilityState;
375
+ switch (visibilityState) {
376
+ case 'visible':
377
+ return VisibilityState.VISIBLE;
378
+ case 'hidden':
379
+ return VisibilityState.HIDDEN;
380
+ default:
381
+ return VisibilityState.UNKNOWN;
382
+ }
383
+ }
384
+ function getEffectiveConnectionType() {
385
+ const navigator = Api.getInstance().navigator;
386
+ const navigatorConnection = navigator.connection;
387
+ const effectiveType = navigatorConnection && navigatorConnection.effectiveType;
388
+ switch (effectiveType) {
389
+ case 'slow-2g':
390
+ return 1 /* EffectiveConnectionType.CONNECTION_SLOW_2G */;
391
+ case '2g':
392
+ return 2 /* EffectiveConnectionType.CONNECTION_2G */;
393
+ case '3g':
394
+ return 3 /* EffectiveConnectionType.CONNECTION_3G */;
395
+ case '4g':
396
+ return 4 /* EffectiveConnectionType.CONNECTION_4G */;
397
+ default:
398
+ return 0 /* EffectiveConnectionType.UNKNOWN */;
399
+ }
400
+ }
401
+ function isValidCustomAttributeName(name) {
402
+ if (name.length === 0 || name.length > MAX_ATTRIBUTE_NAME_LENGTH) {
403
+ return false;
404
+ }
405
+ const matchesReservedPrefix = RESERVED_ATTRIBUTE_PREFIXES.some(prefix => name.startsWith(prefix));
406
+ return !matchesReservedPrefix && !!name.match(ATTRIBUTE_FORMAT_REGEX);
407
+ }
408
+ function isValidCustomAttributeValue(value) {
409
+ return value.length !== 0 && value.length <= MAX_ATTRIBUTE_VALUE_LENGTH;
410
410
  }
411
411
 
412
- /**
413
- * @license
414
- * Copyright 2020 Google LLC
415
- *
416
- * Licensed under the Apache License, Version 2.0 (the "License");
417
- * you may not use this file except in compliance with the License.
418
- * You may obtain a copy of the License at
419
- *
420
- * http://www.apache.org/licenses/LICENSE-2.0
421
- *
422
- * Unless required by applicable law or agreed to in writing, software
423
- * distributed under the License is distributed on an "AS IS" BASIS,
424
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
425
- * See the License for the specific language governing permissions and
426
- * limitations under the License.
427
- */
428
- function getAppId(firebaseApp) {
429
- var _a;
430
- const appId = (_a = firebaseApp.options) === null || _a === void 0 ? void 0 : _a.appId;
431
- if (!appId) {
432
- throw ERROR_FACTORY.create("no app id" /* ErrorCode.NO_APP_ID */);
433
- }
434
- return appId;
435
- }
436
- function getProjectId(firebaseApp) {
437
- var _a;
438
- const projectId = (_a = firebaseApp.options) === null || _a === void 0 ? void 0 : _a.projectId;
439
- if (!projectId) {
440
- throw ERROR_FACTORY.create("no project id" /* ErrorCode.NO_PROJECT_ID */);
441
- }
442
- return projectId;
443
- }
444
- function getApiKey(firebaseApp) {
445
- var _a;
446
- const apiKey = (_a = firebaseApp.options) === null || _a === void 0 ? void 0 : _a.apiKey;
447
- if (!apiKey) {
448
- throw ERROR_FACTORY.create("no api key" /* ErrorCode.NO_API_KEY */);
449
- }
450
- return apiKey;
412
+ /**
413
+ * @license
414
+ * Copyright 2020 Google LLC
415
+ *
416
+ * Licensed under the Apache License, Version 2.0 (the "License");
417
+ * you may not use this file except in compliance with the License.
418
+ * You may obtain a copy of the License at
419
+ *
420
+ * http://www.apache.org/licenses/LICENSE-2.0
421
+ *
422
+ * Unless required by applicable law or agreed to in writing, software
423
+ * distributed under the License is distributed on an "AS IS" BASIS,
424
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
425
+ * See the License for the specific language governing permissions and
426
+ * limitations under the License.
427
+ */
428
+ function getAppId(firebaseApp) {
429
+ var _a;
430
+ const appId = (_a = firebaseApp.options) === null || _a === void 0 ? void 0 : _a.appId;
431
+ if (!appId) {
432
+ throw ERROR_FACTORY.create("no app id" /* ErrorCode.NO_APP_ID */);
433
+ }
434
+ return appId;
435
+ }
436
+ function getProjectId(firebaseApp) {
437
+ var _a;
438
+ const projectId = (_a = firebaseApp.options) === null || _a === void 0 ? void 0 : _a.projectId;
439
+ if (!projectId) {
440
+ throw ERROR_FACTORY.create("no project id" /* ErrorCode.NO_PROJECT_ID */);
441
+ }
442
+ return projectId;
443
+ }
444
+ function getApiKey(firebaseApp) {
445
+ var _a;
446
+ const apiKey = (_a = firebaseApp.options) === null || _a === void 0 ? void 0 : _a.apiKey;
447
+ if (!apiKey) {
448
+ throw ERROR_FACTORY.create("no api key" /* ErrorCode.NO_API_KEY */);
449
+ }
450
+ return apiKey;
451
451
  }
452
452
 
453
- /**
454
- * @license
455
- * Copyright 2020 Google LLC
456
- *
457
- * Licensed under the Apache License, Version 2.0 (the "License");
458
- * you may not use this file except in compliance with the License.
459
- * You may obtain a copy of the License at
460
- *
461
- * http://www.apache.org/licenses/LICENSE-2.0
462
- *
463
- * Unless required by applicable law or agreed to in writing, software
464
- * distributed under the License is distributed on an "AS IS" BASIS,
465
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
466
- * See the License for the specific language governing permissions and
467
- * limitations under the License.
468
- */
469
- const REMOTE_CONFIG_SDK_VERSION = '0.0.1';
470
- // These values will be used if the remote config object is successfully
471
- // retrieved, but the template does not have these fields.
472
- const DEFAULT_CONFIGS = {
473
- loggingEnabled: true
474
- };
475
- const FIS_AUTH_PREFIX = 'FIREBASE_INSTALLATIONS_AUTH';
476
- function getConfig(performanceController, iid) {
477
- const config = getStoredConfig();
478
- if (config) {
479
- processConfig(config);
480
- return Promise.resolve();
481
- }
482
- return getRemoteConfig(performanceController, iid)
483
- .then(processConfig)
484
- .then(config => storeConfig(config),
485
- /** Do nothing for error, use defaults set in settings service. */
486
- () => { });
487
- }
488
- function getStoredConfig() {
489
- const localStorage = Api.getInstance().localStorage;
490
- if (!localStorage) {
491
- return;
492
- }
493
- const expiryString = localStorage.getItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY);
494
- if (!expiryString || !configValid(expiryString)) {
495
- return;
496
- }
497
- const configStringified = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY);
498
- if (!configStringified) {
499
- return;
500
- }
501
- try {
502
- const configResponse = JSON.parse(configStringified);
503
- return configResponse;
504
- }
505
- catch (_a) {
506
- return;
507
- }
508
- }
509
- function storeConfig(config) {
510
- const localStorage = Api.getInstance().localStorage;
511
- if (!config || !localStorage) {
512
- return;
513
- }
514
- localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));
515
- localStorage.setItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY, String(Date.now() +
516
- SettingsService.getInstance().configTimeToLive * 60 * 60 * 1000));
517
- }
518
- const COULD_NOT_GET_CONFIG_MSG = 'Could not fetch config, will use default configs';
519
- function getRemoteConfig(performanceController, iid) {
520
- // Perf needs auth token only to retrieve remote config.
521
- return getAuthTokenPromise(performanceController.installations)
522
- .then(authToken => {
523
- const projectId = getProjectId(performanceController.app);
524
- const apiKey = getApiKey(performanceController.app);
525
- const configEndPoint = `https://firebaseremoteconfig.googleapis.com/v1/projects/${projectId}/namespaces/fireperf:fetch?key=${apiKey}`;
526
- const request = new Request(configEndPoint, {
527
- method: 'POST',
528
- headers: { Authorization: `${FIS_AUTH_PREFIX} ${authToken}` },
529
- /* eslint-disable camelcase */
530
- body: JSON.stringify({
531
- app_instance_id: iid,
532
- app_instance_id_token: authToken,
533
- app_id: getAppId(performanceController.app),
534
- app_version: SDK_VERSION,
535
- sdk_version: REMOTE_CONFIG_SDK_VERSION
536
- })
537
- /* eslint-enable camelcase */
538
- });
539
- return fetch(request).then(response => {
540
- if (response.ok) {
541
- return response.json();
542
- }
543
- // In case response is not ok. This will be caught by catch.
544
- throw ERROR_FACTORY.create("RC response not ok" /* ErrorCode.RC_NOT_OK */);
545
- });
546
- })
547
- .catch(() => {
548
- consoleLogger.info(COULD_NOT_GET_CONFIG_MSG);
549
- return undefined;
550
- });
551
- }
552
- /**
553
- * Processes config coming either from calling RC or from local storage.
554
- * This method only runs if call is successful or config in storage
555
- * is valid.
556
- */
557
- function processConfig(config) {
558
- if (!config) {
559
- return config;
560
- }
561
- const settingsServiceInstance = SettingsService.getInstance();
562
- const entries = config.entries || {};
563
- if (entries.fpr_enabled !== undefined) {
564
- // TODO: Change the assignment of loggingEnabled once the received type is
565
- // known.
566
- settingsServiceInstance.loggingEnabled =
567
- String(entries.fpr_enabled) === 'true';
568
- }
569
- else {
570
- // Config retrieved successfully, but there is no fpr_enabled in template.
571
- // Use secondary configs value.
572
- settingsServiceInstance.loggingEnabled = DEFAULT_CONFIGS.loggingEnabled;
573
- }
574
- if (entries.fpr_log_source) {
575
- settingsServiceInstance.logSource = Number(entries.fpr_log_source);
576
- }
577
- else if (DEFAULT_CONFIGS.logSource) {
578
- settingsServiceInstance.logSource = DEFAULT_CONFIGS.logSource;
579
- }
580
- if (entries.fpr_log_endpoint_url) {
581
- settingsServiceInstance.logEndPointUrl = entries.fpr_log_endpoint_url;
582
- }
583
- else if (DEFAULT_CONFIGS.logEndPointUrl) {
584
- settingsServiceInstance.logEndPointUrl = DEFAULT_CONFIGS.logEndPointUrl;
585
- }
586
- // Key from Remote Config has to be non-empty string, otherwise use local value.
587
- if (entries.fpr_log_transport_key) {
588
- settingsServiceInstance.transportKey = entries.fpr_log_transport_key;
589
- }
590
- else if (DEFAULT_CONFIGS.transportKey) {
591
- settingsServiceInstance.transportKey = DEFAULT_CONFIGS.transportKey;
592
- }
593
- if (entries.fpr_vc_network_request_sampling_rate !== undefined) {
594
- settingsServiceInstance.networkRequestsSamplingRate = Number(entries.fpr_vc_network_request_sampling_rate);
595
- }
596
- else if (DEFAULT_CONFIGS.networkRequestsSamplingRate !== undefined) {
597
- settingsServiceInstance.networkRequestsSamplingRate =
598
- DEFAULT_CONFIGS.networkRequestsSamplingRate;
599
- }
600
- if (entries.fpr_vc_trace_sampling_rate !== undefined) {
601
- settingsServiceInstance.tracesSamplingRate = Number(entries.fpr_vc_trace_sampling_rate);
602
- }
603
- else if (DEFAULT_CONFIGS.tracesSamplingRate !== undefined) {
604
- settingsServiceInstance.tracesSamplingRate =
605
- DEFAULT_CONFIGS.tracesSamplingRate;
606
- }
607
- // Set the per session trace and network logging flags.
608
- settingsServiceInstance.logTraceAfterSampling = shouldLogAfterSampling(settingsServiceInstance.tracesSamplingRate);
609
- settingsServiceInstance.logNetworkAfterSampling = shouldLogAfterSampling(settingsServiceInstance.networkRequestsSamplingRate);
610
- return config;
611
- }
612
- function configValid(expiry) {
613
- return Number(expiry) > Date.now();
614
- }
615
- function shouldLogAfterSampling(samplingRate) {
616
- return Math.random() <= samplingRate;
453
+ /**
454
+ * @license
455
+ * Copyright 2020 Google LLC
456
+ *
457
+ * Licensed under the Apache License, Version 2.0 (the "License");
458
+ * you may not use this file except in compliance with the License.
459
+ * You may obtain a copy of the License at
460
+ *
461
+ * http://www.apache.org/licenses/LICENSE-2.0
462
+ *
463
+ * Unless required by applicable law or agreed to in writing, software
464
+ * distributed under the License is distributed on an "AS IS" BASIS,
465
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
466
+ * See the License for the specific language governing permissions and
467
+ * limitations under the License.
468
+ */
469
+ const REMOTE_CONFIG_SDK_VERSION = '0.0.1';
470
+ // These values will be used if the remote config object is successfully
471
+ // retrieved, but the template does not have these fields.
472
+ const DEFAULT_CONFIGS = {
473
+ loggingEnabled: true
474
+ };
475
+ const FIS_AUTH_PREFIX = 'FIREBASE_INSTALLATIONS_AUTH';
476
+ function getConfig(performanceController, iid) {
477
+ const config = getStoredConfig();
478
+ if (config) {
479
+ processConfig(config);
480
+ return Promise.resolve();
481
+ }
482
+ return getRemoteConfig(performanceController, iid)
483
+ .then(processConfig)
484
+ .then(config => storeConfig(config),
485
+ /** Do nothing for error, use defaults set in settings service. */
486
+ () => { });
487
+ }
488
+ function getStoredConfig() {
489
+ const localStorage = Api.getInstance().localStorage;
490
+ if (!localStorage) {
491
+ return;
492
+ }
493
+ const expiryString = localStorage.getItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY);
494
+ if (!expiryString || !configValid(expiryString)) {
495
+ return;
496
+ }
497
+ const configStringified = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY);
498
+ if (!configStringified) {
499
+ return;
500
+ }
501
+ try {
502
+ const configResponse = JSON.parse(configStringified);
503
+ return configResponse;
504
+ }
505
+ catch (_a) {
506
+ return;
507
+ }
508
+ }
509
+ function storeConfig(config) {
510
+ const localStorage = Api.getInstance().localStorage;
511
+ if (!config || !localStorage) {
512
+ return;
513
+ }
514
+ localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));
515
+ localStorage.setItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY, String(Date.now() +
516
+ SettingsService.getInstance().configTimeToLive * 60 * 60 * 1000));
517
+ }
518
+ const COULD_NOT_GET_CONFIG_MSG = 'Could not fetch config, will use default configs';
519
+ function getRemoteConfig(performanceController, iid) {
520
+ // Perf needs auth token only to retrieve remote config.
521
+ return getAuthTokenPromise(performanceController.installations)
522
+ .then(authToken => {
523
+ const projectId = getProjectId(performanceController.app);
524
+ const apiKey = getApiKey(performanceController.app);
525
+ const configEndPoint = `https://firebaseremoteconfig.googleapis.com/v1/projects/${projectId}/namespaces/fireperf:fetch?key=${apiKey}`;
526
+ const request = new Request(configEndPoint, {
527
+ method: 'POST',
528
+ headers: { Authorization: `${FIS_AUTH_PREFIX} ${authToken}` },
529
+ /* eslint-disable camelcase */
530
+ body: JSON.stringify({
531
+ app_instance_id: iid,
532
+ app_instance_id_token: authToken,
533
+ app_id: getAppId(performanceController.app),
534
+ app_version: SDK_VERSION,
535
+ sdk_version: REMOTE_CONFIG_SDK_VERSION
536
+ })
537
+ /* eslint-enable camelcase */
538
+ });
539
+ return fetch(request).then(response => {
540
+ if (response.ok) {
541
+ return response.json();
542
+ }
543
+ // In case response is not ok. This will be caught by catch.
544
+ throw ERROR_FACTORY.create("RC response not ok" /* ErrorCode.RC_NOT_OK */);
545
+ });
546
+ })
547
+ .catch(() => {
548
+ consoleLogger.info(COULD_NOT_GET_CONFIG_MSG);
549
+ return undefined;
550
+ });
551
+ }
552
+ /**
553
+ * Processes config coming either from calling RC or from local storage.
554
+ * This method only runs if call is successful or config in storage
555
+ * is valid.
556
+ */
557
+ function processConfig(config) {
558
+ if (!config) {
559
+ return config;
560
+ }
561
+ const settingsServiceInstance = SettingsService.getInstance();
562
+ const entries = config.entries || {};
563
+ if (entries.fpr_enabled !== undefined) {
564
+ // TODO: Change the assignment of loggingEnabled once the received type is
565
+ // known.
566
+ settingsServiceInstance.loggingEnabled =
567
+ String(entries.fpr_enabled) === 'true';
568
+ }
569
+ else {
570
+ // Config retrieved successfully, but there is no fpr_enabled in template.
571
+ // Use secondary configs value.
572
+ settingsServiceInstance.loggingEnabled = DEFAULT_CONFIGS.loggingEnabled;
573
+ }
574
+ if (entries.fpr_log_source) {
575
+ settingsServiceInstance.logSource = Number(entries.fpr_log_source);
576
+ }
577
+ else if (DEFAULT_CONFIGS.logSource) {
578
+ settingsServiceInstance.logSource = DEFAULT_CONFIGS.logSource;
579
+ }
580
+ if (entries.fpr_log_endpoint_url) {
581
+ settingsServiceInstance.logEndPointUrl = entries.fpr_log_endpoint_url;
582
+ }
583
+ else if (DEFAULT_CONFIGS.logEndPointUrl) {
584
+ settingsServiceInstance.logEndPointUrl = DEFAULT_CONFIGS.logEndPointUrl;
585
+ }
586
+ // Key from Remote Config has to be non-empty string, otherwise use local value.
587
+ if (entries.fpr_log_transport_key) {
588
+ settingsServiceInstance.transportKey = entries.fpr_log_transport_key;
589
+ }
590
+ else if (DEFAULT_CONFIGS.transportKey) {
591
+ settingsServiceInstance.transportKey = DEFAULT_CONFIGS.transportKey;
592
+ }
593
+ if (entries.fpr_vc_network_request_sampling_rate !== undefined) {
594
+ settingsServiceInstance.networkRequestsSamplingRate = Number(entries.fpr_vc_network_request_sampling_rate);
595
+ }
596
+ else if (DEFAULT_CONFIGS.networkRequestsSamplingRate !== undefined) {
597
+ settingsServiceInstance.networkRequestsSamplingRate =
598
+ DEFAULT_CONFIGS.networkRequestsSamplingRate;
599
+ }
600
+ if (entries.fpr_vc_trace_sampling_rate !== undefined) {
601
+ settingsServiceInstance.tracesSamplingRate = Number(entries.fpr_vc_trace_sampling_rate);
602
+ }
603
+ else if (DEFAULT_CONFIGS.tracesSamplingRate !== undefined) {
604
+ settingsServiceInstance.tracesSamplingRate =
605
+ DEFAULT_CONFIGS.tracesSamplingRate;
606
+ }
607
+ // Set the per session trace and network logging flags.
608
+ settingsServiceInstance.logTraceAfterSampling = shouldLogAfterSampling(settingsServiceInstance.tracesSamplingRate);
609
+ settingsServiceInstance.logNetworkAfterSampling = shouldLogAfterSampling(settingsServiceInstance.networkRequestsSamplingRate);
610
+ return config;
611
+ }
612
+ function configValid(expiry) {
613
+ return Number(expiry) > Date.now();
614
+ }
615
+ function shouldLogAfterSampling(samplingRate) {
616
+ return Math.random() <= samplingRate;
617
617
  }
618
618
 
619
- /**
620
- * @license
621
- * Copyright 2020 Google LLC
622
- *
623
- * Licensed under the Apache License, Version 2.0 (the "License");
624
- * you may not use this file except in compliance with the License.
625
- * You may obtain a copy of the License at
626
- *
627
- * http://www.apache.org/licenses/LICENSE-2.0
628
- *
629
- * Unless required by applicable law or agreed to in writing, software
630
- * distributed under the License is distributed on an "AS IS" BASIS,
631
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
632
- * See the License for the specific language governing permissions and
633
- * limitations under the License.
634
- */
635
- let initializationStatus = 1 /* InitializationStatus.notInitialized */;
636
- let initializationPromise;
637
- function getInitializationPromise(performanceController) {
638
- initializationStatus = 2 /* InitializationStatus.initializationPending */;
639
- initializationPromise =
640
- initializationPromise || initializePerf(performanceController);
641
- return initializationPromise;
642
- }
643
- function isPerfInitialized() {
644
- return initializationStatus === 3 /* InitializationStatus.initialized */;
645
- }
646
- function initializePerf(performanceController) {
647
- return getDocumentReadyComplete()
648
- .then(() => getIidPromise(performanceController.installations))
649
- .then(iid => getConfig(performanceController, iid))
650
- .then(() => changeInitializationStatus(), () => changeInitializationStatus());
651
- }
652
- /**
653
- * Returns a promise which resolves whenever the document readystate is complete or
654
- * immediately if it is called after page load complete.
655
- */
656
- function getDocumentReadyComplete() {
657
- const document = Api.getInstance().document;
658
- return new Promise(resolve => {
659
- if (document && document.readyState !== 'complete') {
660
- const handler = () => {
661
- if (document.readyState === 'complete') {
662
- document.removeEventListener('readystatechange', handler);
663
- resolve();
664
- }
665
- };
666
- document.addEventListener('readystatechange', handler);
667
- }
668
- else {
669
- resolve();
670
- }
671
- });
672
- }
673
- function changeInitializationStatus() {
674
- initializationStatus = 3 /* InitializationStatus.initialized */;
619
+ /**
620
+ * @license
621
+ * Copyright 2020 Google LLC
622
+ *
623
+ * Licensed under the Apache License, Version 2.0 (the "License");
624
+ * you may not use this file except in compliance with the License.
625
+ * You may obtain a copy of the License at
626
+ *
627
+ * http://www.apache.org/licenses/LICENSE-2.0
628
+ *
629
+ * Unless required by applicable law or agreed to in writing, software
630
+ * distributed under the License is distributed on an "AS IS" BASIS,
631
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
632
+ * See the License for the specific language governing permissions and
633
+ * limitations under the License.
634
+ */
635
+ let initializationStatus = 1 /* InitializationStatus.notInitialized */;
636
+ let initializationPromise;
637
+ function getInitializationPromise(performanceController) {
638
+ initializationStatus = 2 /* InitializationStatus.initializationPending */;
639
+ initializationPromise =
640
+ initializationPromise || initializePerf(performanceController);
641
+ return initializationPromise;
642
+ }
643
+ function isPerfInitialized() {
644
+ return initializationStatus === 3 /* InitializationStatus.initialized */;
645
+ }
646
+ function initializePerf(performanceController) {
647
+ return getDocumentReadyComplete()
648
+ .then(() => getIidPromise(performanceController.installations))
649
+ .then(iid => getConfig(performanceController, iid))
650
+ .then(() => changeInitializationStatus(), () => changeInitializationStatus());
651
+ }
652
+ /**
653
+ * Returns a promise which resolves whenever the document readystate is complete or
654
+ * immediately if it is called after page load complete.
655
+ */
656
+ function getDocumentReadyComplete() {
657
+ const document = Api.getInstance().document;
658
+ return new Promise(resolve => {
659
+ if (document && document.readyState !== 'complete') {
660
+ const handler = () => {
661
+ if (document.readyState === 'complete') {
662
+ document.removeEventListener('readystatechange', handler);
663
+ resolve();
664
+ }
665
+ };
666
+ document.addEventListener('readystatechange', handler);
667
+ }
668
+ else {
669
+ resolve();
670
+ }
671
+ });
672
+ }
673
+ function changeInitializationStatus() {
674
+ initializationStatus = 3 /* InitializationStatus.initialized */;
675
675
  }
676
676
 
677
- /**
678
- * @license
679
- * Copyright 2020 Google LLC
680
- *
681
- * Licensed under the Apache License, Version 2.0 (the "License");
682
- * you may not use this file except in compliance with the License.
683
- * You may obtain a copy of the License at
684
- *
685
- * http://www.apache.org/licenses/LICENSE-2.0
686
- *
687
- * Unless required by applicable law or agreed to in writing, software
688
- * distributed under the License is distributed on an "AS IS" BASIS,
689
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
690
- * See the License for the specific language governing permissions and
691
- * limitations under the License.
692
- */
693
- const DEFAULT_SEND_INTERVAL_MS = 10 * 1000;
694
- const INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000;
695
- // If end point does not work, the call will be tried for these many times.
696
- const DEFAULT_REMAINING_TRIES = 3;
697
- const MAX_EVENT_COUNT_PER_REQUEST = 1000;
698
- let remainingTries = DEFAULT_REMAINING_TRIES;
699
- /* eslint-enable camelcase */
700
- let queue = [];
701
- let isTransportSetup = false;
702
- function setupTransportService() {
703
- if (!isTransportSetup) {
704
- processQueue(INITIAL_SEND_TIME_DELAY_MS);
705
- isTransportSetup = true;
706
- }
707
- }
708
- function processQueue(timeOffset) {
709
- setTimeout(() => {
710
- // If there is no remainingTries left, stop retrying.
711
- if (remainingTries === 0) {
712
- return;
713
- }
714
- // If there are no events to process, wait for DEFAULT_SEND_INTERVAL_MS and try again.
715
- if (!queue.length) {
716
- return processQueue(DEFAULT_SEND_INTERVAL_MS);
717
- }
718
- dispatchQueueEvents();
719
- }, timeOffset);
720
- }
721
- function dispatchQueueEvents() {
722
- // Extract events up to the maximum cap of single logRequest from top of "official queue".
723
- // The staged events will be used for current logRequest attempt, remaining events will be kept
724
- // for next attempt.
725
- const staged = queue.splice(0, MAX_EVENT_COUNT_PER_REQUEST);
726
- /* eslint-disable camelcase */
727
- // We will pass the JSON serialized event to the backend.
728
- const log_event = staged.map(evt => ({
729
- source_extension_json_proto3: evt.message,
730
- event_time_ms: String(evt.eventTime)
731
- }));
732
- const data = {
733
- request_time_ms: String(Date.now()),
734
- client_info: {
735
- client_type: 1,
736
- js_client_info: {}
737
- },
738
- log_source: SettingsService.getInstance().logSource,
739
- log_event
740
- };
741
- /* eslint-enable camelcase */
742
- sendEventsToFl(data, staged).catch(() => {
743
- // If the request fails for some reason, add the events that were attempted
744
- // back to the primary queue to retry later.
745
- queue = [...staged, ...queue];
746
- remainingTries--;
747
- consoleLogger.info(`Tries left: ${remainingTries}.`);
748
- processQueue(DEFAULT_SEND_INTERVAL_MS);
749
- });
750
- }
751
- function sendEventsToFl(data, staged) {
752
- return postToFlEndpoint(data)
753
- .then(res => {
754
- if (!res.ok) {
755
- consoleLogger.info('Call to Firebase backend failed.');
756
- }
757
- return res.json();
758
- })
759
- .then(res => {
760
- // Find the next call wait time from the response.
761
- const transportWait = Number(res.nextRequestWaitMillis);
762
- let requestOffset = DEFAULT_SEND_INTERVAL_MS;
763
- if (!isNaN(transportWait)) {
764
- requestOffset = Math.max(transportWait, requestOffset);
765
- }
766
- // Delete request if response include RESPONSE_ACTION_UNKNOWN or DELETE_REQUEST action.
767
- // Otherwise, retry request using normal scheduling if response include RETRY_REQUEST_LATER.
768
- const logResponseDetails = res.logResponseDetails;
769
- if (Array.isArray(logResponseDetails) &&
770
- logResponseDetails.length > 0 &&
771
- logResponseDetails[0].responseAction === 'RETRY_REQUEST_LATER') {
772
- queue = [...staged, ...queue];
773
- consoleLogger.info(`Retry transport request later.`);
774
- }
775
- remainingTries = DEFAULT_REMAINING_TRIES;
776
- // Schedule the next process.
777
- processQueue(requestOffset);
778
- });
779
- }
780
- function postToFlEndpoint(data) {
781
- const flTransportFullUrl = SettingsService.getInstance().getFlTransportFullUrl();
782
- return fetch(flTransportFullUrl, {
783
- method: 'POST',
784
- body: JSON.stringify(data)
785
- });
786
- }
787
- function addToQueue(evt) {
788
- if (!evt.eventTime || !evt.message) {
789
- throw ERROR_FACTORY.create("invalid cc log" /* ErrorCode.INVALID_CC_LOG */);
790
- }
791
- // Add the new event to the queue.
792
- queue = [...queue, evt];
793
- }
794
- /** Log handler for cc service to send the performance logs to the server. */
795
- function transportHandler(
796
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
797
- serializer) {
798
- return (...args) => {
799
- const message = serializer(...args);
800
- addToQueue({
801
- message,
802
- eventTime: Date.now()
803
- });
804
- };
677
+ /**
678
+ * @license
679
+ * Copyright 2020 Google LLC
680
+ *
681
+ * Licensed under the Apache License, Version 2.0 (the "License");
682
+ * you may not use this file except in compliance with the License.
683
+ * You may obtain a copy of the License at
684
+ *
685
+ * http://www.apache.org/licenses/LICENSE-2.0
686
+ *
687
+ * Unless required by applicable law or agreed to in writing, software
688
+ * distributed under the License is distributed on an "AS IS" BASIS,
689
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
690
+ * See the License for the specific language governing permissions and
691
+ * limitations under the License.
692
+ */
693
+ const DEFAULT_SEND_INTERVAL_MS = 10 * 1000;
694
+ const INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000;
695
+ // If end point does not work, the call will be tried for these many times.
696
+ const DEFAULT_REMAINING_TRIES = 3;
697
+ const MAX_EVENT_COUNT_PER_REQUEST = 1000;
698
+ let remainingTries = DEFAULT_REMAINING_TRIES;
699
+ /* eslint-enable camelcase */
700
+ let queue = [];
701
+ let isTransportSetup = false;
702
+ function setupTransportService() {
703
+ if (!isTransportSetup) {
704
+ processQueue(INITIAL_SEND_TIME_DELAY_MS);
705
+ isTransportSetup = true;
706
+ }
707
+ }
708
+ function processQueue(timeOffset) {
709
+ setTimeout(() => {
710
+ // If there is no remainingTries left, stop retrying.
711
+ if (remainingTries === 0) {
712
+ return;
713
+ }
714
+ // If there are no events to process, wait for DEFAULT_SEND_INTERVAL_MS and try again.
715
+ if (!queue.length) {
716
+ return processQueue(DEFAULT_SEND_INTERVAL_MS);
717
+ }
718
+ dispatchQueueEvents();
719
+ }, timeOffset);
720
+ }
721
+ function dispatchQueueEvents() {
722
+ // Extract events up to the maximum cap of single logRequest from top of "official queue".
723
+ // The staged events will be used for current logRequest attempt, remaining events will be kept
724
+ // for next attempt.
725
+ const staged = queue.splice(0, MAX_EVENT_COUNT_PER_REQUEST);
726
+ /* eslint-disable camelcase */
727
+ // We will pass the JSON serialized event to the backend.
728
+ const log_event = staged.map(evt => ({
729
+ source_extension_json_proto3: evt.message,
730
+ event_time_ms: String(evt.eventTime)
731
+ }));
732
+ const data = {
733
+ request_time_ms: String(Date.now()),
734
+ client_info: {
735
+ client_type: 1, // 1 is JS
736
+ js_client_info: {}
737
+ },
738
+ log_source: SettingsService.getInstance().logSource,
739
+ log_event
740
+ };
741
+ /* eslint-enable camelcase */
742
+ sendEventsToFl(data, staged).catch(() => {
743
+ // If the request fails for some reason, add the events that were attempted
744
+ // back to the primary queue to retry later.
745
+ queue = [...staged, ...queue];
746
+ remainingTries--;
747
+ consoleLogger.info(`Tries left: ${remainingTries}.`);
748
+ processQueue(DEFAULT_SEND_INTERVAL_MS);
749
+ });
750
+ }
751
+ function sendEventsToFl(data, staged) {
752
+ return postToFlEndpoint(data)
753
+ .then(res => {
754
+ if (!res.ok) {
755
+ consoleLogger.info('Call to Firebase backend failed.');
756
+ }
757
+ return res.json();
758
+ })
759
+ .then(res => {
760
+ // Find the next call wait time from the response.
761
+ const transportWait = Number(res.nextRequestWaitMillis);
762
+ let requestOffset = DEFAULT_SEND_INTERVAL_MS;
763
+ if (!isNaN(transportWait)) {
764
+ requestOffset = Math.max(transportWait, requestOffset);
765
+ }
766
+ // Delete request if response include RESPONSE_ACTION_UNKNOWN or DELETE_REQUEST action.
767
+ // Otherwise, retry request using normal scheduling if response include RETRY_REQUEST_LATER.
768
+ const logResponseDetails = res.logResponseDetails;
769
+ if (Array.isArray(logResponseDetails) &&
770
+ logResponseDetails.length > 0 &&
771
+ logResponseDetails[0].responseAction === 'RETRY_REQUEST_LATER') {
772
+ queue = [...staged, ...queue];
773
+ consoleLogger.info(`Retry transport request later.`);
774
+ }
775
+ remainingTries = DEFAULT_REMAINING_TRIES;
776
+ // Schedule the next process.
777
+ processQueue(requestOffset);
778
+ });
779
+ }
780
+ function postToFlEndpoint(data) {
781
+ const flTransportFullUrl = SettingsService.getInstance().getFlTransportFullUrl();
782
+ return fetch(flTransportFullUrl, {
783
+ method: 'POST',
784
+ body: JSON.stringify(data)
785
+ });
786
+ }
787
+ function addToQueue(evt) {
788
+ if (!evt.eventTime || !evt.message) {
789
+ throw ERROR_FACTORY.create("invalid cc log" /* ErrorCode.INVALID_CC_LOG */);
790
+ }
791
+ // Add the new event to the queue.
792
+ queue = [...queue, evt];
793
+ }
794
+ /** Log handler for cc service to send the performance logs to the server. */
795
+ function transportHandler(
796
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
797
+ serializer) {
798
+ return (...args) => {
799
+ const message = serializer(...args);
800
+ addToQueue({
801
+ message,
802
+ eventTime: Date.now()
803
+ });
804
+ };
805
805
  }
806
806
 
807
- /**
808
- * @license
809
- * Copyright 2020 Google LLC
810
- *
811
- * Licensed under the Apache License, Version 2.0 (the "License");
812
- * you may not use this file except in compliance with the License.
813
- * You may obtain a copy of the License at
814
- *
815
- * http://www.apache.org/licenses/LICENSE-2.0
816
- *
817
- * Unless required by applicable law or agreed to in writing, software
818
- * distributed under the License is distributed on an "AS IS" BASIS,
819
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
820
- * See the License for the specific language governing permissions and
821
- * limitations under the License.
822
- */
823
- let logger;
824
- // This method is not called before initialization.
825
- function sendLog(resource, resourceType) {
826
- if (!logger) {
827
- logger = transportHandler(serializer);
828
- }
829
- logger(resource, resourceType);
830
- }
831
- function logTrace(trace) {
832
- const settingsService = SettingsService.getInstance();
833
- // Do not log if trace is auto generated and instrumentation is disabled.
834
- if (!settingsService.instrumentationEnabled && trace.isAuto) {
835
- return;
836
- }
837
- // Do not log if trace is custom and data collection is disabled.
838
- if (!settingsService.dataCollectionEnabled && !trace.isAuto) {
839
- return;
840
- }
841
- // Do not log if required apis are not available.
842
- if (!Api.getInstance().requiredApisAvailable()) {
843
- return;
844
- }
845
- // Only log the page load auto traces if page is visible.
846
- if (trace.isAuto && getVisibilityState() !== VisibilityState.VISIBLE) {
847
- return;
848
- }
849
- if (isPerfInitialized()) {
850
- sendTraceLog(trace);
851
- }
852
- else {
853
- // Custom traces can be used before the initialization but logging
854
- // should wait until after.
855
- getInitializationPromise(trace.performanceController).then(() => sendTraceLog(trace), () => sendTraceLog(trace));
856
- }
857
- }
858
- function sendTraceLog(trace) {
859
- if (!getIid()) {
860
- return;
861
- }
862
- const settingsService = SettingsService.getInstance();
863
- if (!settingsService.loggingEnabled ||
864
- !settingsService.logTraceAfterSampling) {
865
- return;
866
- }
867
- setTimeout(() => sendLog(trace, 1 /* ResourceType.Trace */), 0);
868
- }
869
- function logNetworkRequest(networkRequest) {
870
- const settingsService = SettingsService.getInstance();
871
- // Do not log network requests if instrumentation is disabled.
872
- if (!settingsService.instrumentationEnabled) {
873
- return;
874
- }
875
- // Do not log the js sdk's call to transport service domain to avoid unnecessary cycle.
876
- // Need to blacklist both old and new endpoints to avoid migration gap.
877
- const networkRequestUrl = networkRequest.url;
878
- // Blacklist old log endpoint and new transport endpoint.
879
- // Because Performance SDK doesn't instrument requests sent from SDK itself.
880
- const logEndpointUrl = settingsService.logEndPointUrl.split('?')[0];
881
- const flEndpointUrl = settingsService.flTransportEndpointUrl.split('?')[0];
882
- if (networkRequestUrl === logEndpointUrl ||
883
- networkRequestUrl === flEndpointUrl) {
884
- return;
885
- }
886
- if (!settingsService.loggingEnabled ||
887
- !settingsService.logNetworkAfterSampling) {
888
- return;
889
- }
890
- setTimeout(() => sendLog(networkRequest, 0 /* ResourceType.NetworkRequest */), 0);
891
- }
892
- function serializer(resource, resourceType) {
893
- if (resourceType === 0 /* ResourceType.NetworkRequest */) {
894
- return serializeNetworkRequest(resource);
895
- }
896
- return serializeTrace(resource);
897
- }
898
- function serializeNetworkRequest(networkRequest) {
899
- const networkRequestMetric = {
900
- url: networkRequest.url,
901
- http_method: networkRequest.httpMethod || 0,
902
- http_response_code: 200,
903
- response_payload_bytes: networkRequest.responsePayloadBytes,
904
- client_start_time_us: networkRequest.startTimeUs,
905
- time_to_response_initiated_us: networkRequest.timeToResponseInitiatedUs,
906
- time_to_response_completed_us: networkRequest.timeToResponseCompletedUs
907
- };
908
- const perfMetric = {
909
- application_info: getApplicationInfo(networkRequest.performanceController.app),
910
- network_request_metric: networkRequestMetric
911
- };
912
- return JSON.stringify(perfMetric);
913
- }
914
- function serializeTrace(trace) {
915
- const traceMetric = {
916
- name: trace.name,
917
- is_auto: trace.isAuto,
918
- client_start_time_us: trace.startTimeUs,
919
- duration_us: trace.durationUs
920
- };
921
- if (Object.keys(trace.counters).length !== 0) {
922
- traceMetric.counters = trace.counters;
923
- }
924
- const customAttributes = trace.getAttributes();
925
- if (Object.keys(customAttributes).length !== 0) {
926
- traceMetric.custom_attributes = customAttributes;
927
- }
928
- const perfMetric = {
929
- application_info: getApplicationInfo(trace.performanceController.app),
930
- trace_metric: traceMetric
931
- };
932
- return JSON.stringify(perfMetric);
933
- }
934
- function getApplicationInfo(firebaseApp) {
935
- return {
936
- google_app_id: getAppId(firebaseApp),
937
- app_instance_id: getIid(),
938
- web_app_info: {
939
- sdk_version: SDK_VERSION,
940
- page_url: Api.getInstance().getUrl(),
941
- service_worker_status: getServiceWorkerStatus(),
942
- visibility_state: getVisibilityState(),
943
- effective_connection_type: getEffectiveConnectionType()
944
- },
945
- application_process_state: 0
946
- };
947
- }
807
+ /**
808
+ * @license
809
+ * Copyright 2020 Google LLC
810
+ *
811
+ * Licensed under the Apache License, Version 2.0 (the "License");
812
+ * you may not use this file except in compliance with the License.
813
+ * You may obtain a copy of the License at
814
+ *
815
+ * http://www.apache.org/licenses/LICENSE-2.0
816
+ *
817
+ * Unless required by applicable law or agreed to in writing, software
818
+ * distributed under the License is distributed on an "AS IS" BASIS,
819
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
820
+ * See the License for the specific language governing permissions and
821
+ * limitations under the License.
822
+ */
823
+ let logger;
824
+ // This method is not called before initialization.
825
+ function sendLog(resource, resourceType) {
826
+ if (!logger) {
827
+ logger = transportHandler(serializer);
828
+ }
829
+ logger(resource, resourceType);
830
+ }
831
+ function logTrace(trace) {
832
+ const settingsService = SettingsService.getInstance();
833
+ // Do not log if trace is auto generated and instrumentation is disabled.
834
+ if (!settingsService.instrumentationEnabled && trace.isAuto) {
835
+ return;
836
+ }
837
+ // Do not log if trace is custom and data collection is disabled.
838
+ if (!settingsService.dataCollectionEnabled && !trace.isAuto) {
839
+ return;
840
+ }
841
+ // Do not log if required apis are not available.
842
+ if (!Api.getInstance().requiredApisAvailable()) {
843
+ return;
844
+ }
845
+ // Only log the page load auto traces if page is visible.
846
+ if (trace.isAuto && getVisibilityState() !== VisibilityState.VISIBLE) {
847
+ return;
848
+ }
849
+ if (isPerfInitialized()) {
850
+ sendTraceLog(trace);
851
+ }
852
+ else {
853
+ // Custom traces can be used before the initialization but logging
854
+ // should wait until after.
855
+ getInitializationPromise(trace.performanceController).then(() => sendTraceLog(trace), () => sendTraceLog(trace));
856
+ }
857
+ }
858
+ function sendTraceLog(trace) {
859
+ if (!getIid()) {
860
+ return;
861
+ }
862
+ const settingsService = SettingsService.getInstance();
863
+ if (!settingsService.loggingEnabled ||
864
+ !settingsService.logTraceAfterSampling) {
865
+ return;
866
+ }
867
+ setTimeout(() => sendLog(trace, 1 /* ResourceType.Trace */), 0);
868
+ }
869
+ function logNetworkRequest(networkRequest) {
870
+ const settingsService = SettingsService.getInstance();
871
+ // Do not log network requests if instrumentation is disabled.
872
+ if (!settingsService.instrumentationEnabled) {
873
+ return;
874
+ }
875
+ // Do not log the js sdk's call to transport service domain to avoid unnecessary cycle.
876
+ // Need to blacklist both old and new endpoints to avoid migration gap.
877
+ const networkRequestUrl = networkRequest.url;
878
+ // Blacklist old log endpoint and new transport endpoint.
879
+ // Because Performance SDK doesn't instrument requests sent from SDK itself.
880
+ const logEndpointUrl = settingsService.logEndPointUrl.split('?')[0];
881
+ const flEndpointUrl = settingsService.flTransportEndpointUrl.split('?')[0];
882
+ if (networkRequestUrl === logEndpointUrl ||
883
+ networkRequestUrl === flEndpointUrl) {
884
+ return;
885
+ }
886
+ if (!settingsService.loggingEnabled ||
887
+ !settingsService.logNetworkAfterSampling) {
888
+ return;
889
+ }
890
+ setTimeout(() => sendLog(networkRequest, 0 /* ResourceType.NetworkRequest */), 0);
891
+ }
892
+ function serializer(resource, resourceType) {
893
+ if (resourceType === 0 /* ResourceType.NetworkRequest */) {
894
+ return serializeNetworkRequest(resource);
895
+ }
896
+ return serializeTrace(resource);
897
+ }
898
+ function serializeNetworkRequest(networkRequest) {
899
+ const networkRequestMetric = {
900
+ url: networkRequest.url,
901
+ http_method: networkRequest.httpMethod || 0,
902
+ http_response_code: 200,
903
+ response_payload_bytes: networkRequest.responsePayloadBytes,
904
+ client_start_time_us: networkRequest.startTimeUs,
905
+ time_to_response_initiated_us: networkRequest.timeToResponseInitiatedUs,
906
+ time_to_response_completed_us: networkRequest.timeToResponseCompletedUs
907
+ };
908
+ const perfMetric = {
909
+ application_info: getApplicationInfo(networkRequest.performanceController.app),
910
+ network_request_metric: networkRequestMetric
911
+ };
912
+ return JSON.stringify(perfMetric);
913
+ }
914
+ function serializeTrace(trace) {
915
+ const traceMetric = {
916
+ name: trace.name,
917
+ is_auto: trace.isAuto,
918
+ client_start_time_us: trace.startTimeUs,
919
+ duration_us: trace.durationUs
920
+ };
921
+ if (Object.keys(trace.counters).length !== 0) {
922
+ traceMetric.counters = trace.counters;
923
+ }
924
+ const customAttributes = trace.getAttributes();
925
+ if (Object.keys(customAttributes).length !== 0) {
926
+ traceMetric.custom_attributes = customAttributes;
927
+ }
928
+ const perfMetric = {
929
+ application_info: getApplicationInfo(trace.performanceController.app),
930
+ trace_metric: traceMetric
931
+ };
932
+ return JSON.stringify(perfMetric);
933
+ }
934
+ function getApplicationInfo(firebaseApp) {
935
+ return {
936
+ google_app_id: getAppId(firebaseApp),
937
+ app_instance_id: getIid(),
938
+ web_app_info: {
939
+ sdk_version: SDK_VERSION,
940
+ page_url: Api.getInstance().getUrl(),
941
+ service_worker_status: getServiceWorkerStatus(),
942
+ visibility_state: getVisibilityState(),
943
+ effective_connection_type: getEffectiveConnectionType()
944
+ },
945
+ application_process_state: 0
946
+ };
947
+ }
948
948
  /* eslint-enable camelcase */
949
949
 
950
- /**
951
- * @license
952
- * Copyright 2020 Google LLC
953
- *
954
- * Licensed under the Apache License, Version 2.0 (the "License");
955
- * you may not use this file except in compliance with the License.
956
- * You may obtain a copy of the License at
957
- *
958
- * http://www.apache.org/licenses/LICENSE-2.0
959
- *
960
- * Unless required by applicable law or agreed to in writing, software
961
- * distributed under the License is distributed on an "AS IS" BASIS,
962
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
963
- * See the License for the specific language governing permissions and
964
- * limitations under the License.
965
- */
966
- const MAX_METRIC_NAME_LENGTH = 100;
967
- const RESERVED_AUTO_PREFIX = '_';
968
- const oobMetrics = [
969
- FIRST_PAINT_COUNTER_NAME,
970
- FIRST_CONTENTFUL_PAINT_COUNTER_NAME,
971
- FIRST_INPUT_DELAY_COUNTER_NAME
972
- ];
973
- /**
974
- * Returns true if the metric is custom and does not start with reserved prefix, or if
975
- * the metric is one of out of the box page load trace metrics.
976
- */
977
- function isValidMetricName(name, traceName) {
978
- if (name.length === 0 || name.length > MAX_METRIC_NAME_LENGTH) {
979
- return false;
980
- }
981
- return ((traceName &&
982
- traceName.startsWith(OOB_TRACE_PAGE_LOAD_PREFIX) &&
983
- oobMetrics.indexOf(name) > -1) ||
984
- !name.startsWith(RESERVED_AUTO_PREFIX));
985
- }
986
- /**
987
- * Converts the provided value to an integer value to be used in case of a metric.
988
- * @param providedValue Provided number value of the metric that needs to be converted to an integer.
989
- *
990
- * @returns Converted integer number to be set for the metric.
991
- */
992
- function convertMetricValueToInteger(providedValue) {
993
- const valueAsInteger = Math.floor(providedValue);
994
- if (valueAsInteger < providedValue) {
995
- consoleLogger.info(`Metric value should be an Integer, setting the value as : ${valueAsInteger}.`);
996
- }
997
- return valueAsInteger;
950
+ /**
951
+ * @license
952
+ * Copyright 2020 Google LLC
953
+ *
954
+ * Licensed under the Apache License, Version 2.0 (the "License");
955
+ * you may not use this file except in compliance with the License.
956
+ * You may obtain a copy of the License at
957
+ *
958
+ * http://www.apache.org/licenses/LICENSE-2.0
959
+ *
960
+ * Unless required by applicable law or agreed to in writing, software
961
+ * distributed under the License is distributed on an "AS IS" BASIS,
962
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
963
+ * See the License for the specific language governing permissions and
964
+ * limitations under the License.
965
+ */
966
+ const MAX_METRIC_NAME_LENGTH = 100;
967
+ const RESERVED_AUTO_PREFIX = '_';
968
+ const oobMetrics = [
969
+ FIRST_PAINT_COUNTER_NAME,
970
+ FIRST_CONTENTFUL_PAINT_COUNTER_NAME,
971
+ FIRST_INPUT_DELAY_COUNTER_NAME
972
+ ];
973
+ /**
974
+ * Returns true if the metric is custom and does not start with reserved prefix, or if
975
+ * the metric is one of out of the box page load trace metrics.
976
+ */
977
+ function isValidMetricName(name, traceName) {
978
+ if (name.length === 0 || name.length > MAX_METRIC_NAME_LENGTH) {
979
+ return false;
980
+ }
981
+ return ((traceName &&
982
+ traceName.startsWith(OOB_TRACE_PAGE_LOAD_PREFIX) &&
983
+ oobMetrics.indexOf(name) > -1) ||
984
+ !name.startsWith(RESERVED_AUTO_PREFIX));
985
+ }
986
+ /**
987
+ * Converts the provided value to an integer value to be used in case of a metric.
988
+ * @param providedValue Provided number value of the metric that needs to be converted to an integer.
989
+ *
990
+ * @returns Converted integer number to be set for the metric.
991
+ */
992
+ function convertMetricValueToInteger(providedValue) {
993
+ const valueAsInteger = Math.floor(providedValue);
994
+ if (valueAsInteger < providedValue) {
995
+ consoleLogger.info(`Metric value should be an Integer, setting the value as : ${valueAsInteger}.`);
996
+ }
997
+ return valueAsInteger;
998
998
  }
999
999
 
1000
- /**
1001
- * @license
1002
- * Copyright 2020 Google LLC
1003
- *
1004
- * Licensed under the Apache License, Version 2.0 (the "License");
1005
- * you may not use this file except in compliance with the License.
1006
- * You may obtain a copy of the License at
1007
- *
1008
- * http://www.apache.org/licenses/LICENSE-2.0
1009
- *
1010
- * Unless required by applicable law or agreed to in writing, software
1011
- * distributed under the License is distributed on an "AS IS" BASIS,
1012
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1013
- * See the License for the specific language governing permissions and
1014
- * limitations under the License.
1015
- */
1016
- class Trace {
1017
- /**
1018
- * @param performanceController The performance controller running.
1019
- * @param name The name of the trace.
1020
- * @param isAuto If the trace is auto-instrumented.
1021
- * @param traceMeasureName The name of the measure marker in user timing specification. This field
1022
- * is only set when the trace is built for logging when the user directly uses the user timing
1023
- * api (performance.mark and performance.measure).
1024
- */
1025
- constructor(performanceController, name, isAuto = false, traceMeasureName) {
1026
- this.performanceController = performanceController;
1027
- this.name = name;
1028
- this.isAuto = isAuto;
1029
- this.state = 1 /* TraceState.UNINITIALIZED */;
1030
- this.customAttributes = {};
1031
- this.counters = {};
1032
- this.api = Api.getInstance();
1033
- this.randomId = Math.floor(Math.random() * 1000000);
1034
- if (!this.isAuto) {
1035
- this.traceStartMark = `${TRACE_START_MARK_PREFIX}-${this.randomId}-${this.name}`;
1036
- this.traceStopMark = `${TRACE_STOP_MARK_PREFIX}-${this.randomId}-${this.name}`;
1037
- this.traceMeasure =
1038
- traceMeasureName ||
1039
- `${TRACE_MEASURE_PREFIX}-${this.randomId}-${this.name}`;
1040
- if (traceMeasureName) {
1041
- // For the case of direct user timing traces, no start stop will happen. The measure object
1042
- // is already available.
1043
- this.calculateTraceMetrics();
1044
- }
1045
- }
1046
- }
1047
- /**
1048
- * Starts a trace. The measurement of the duration starts at this point.
1049
- */
1050
- start() {
1051
- if (this.state !== 1 /* TraceState.UNINITIALIZED */) {
1052
- throw ERROR_FACTORY.create("trace started" /* ErrorCode.TRACE_STARTED_BEFORE */, {
1053
- traceName: this.name
1054
- });
1055
- }
1056
- this.api.mark(this.traceStartMark);
1057
- this.state = 2 /* TraceState.RUNNING */;
1058
- }
1059
- /**
1060
- * Stops the trace. The measurement of the duration of the trace stops at this point and trace
1061
- * is logged.
1062
- */
1063
- stop() {
1064
- if (this.state !== 2 /* TraceState.RUNNING */) {
1065
- throw ERROR_FACTORY.create("trace stopped" /* ErrorCode.TRACE_STOPPED_BEFORE */, {
1066
- traceName: this.name
1067
- });
1068
- }
1069
- this.state = 3 /* TraceState.TERMINATED */;
1070
- this.api.mark(this.traceStopMark);
1071
- this.api.measure(this.traceMeasure, this.traceStartMark, this.traceStopMark);
1072
- this.calculateTraceMetrics();
1073
- logTrace(this);
1074
- }
1075
- /**
1076
- * Records a trace with predetermined values. If this method is used a trace is created and logged
1077
- * directly. No need to use start and stop methods.
1078
- * @param startTime Trace start time since epoch in millisec
1079
- * @param duration The duration of the trace in millisec
1080
- * @param options An object which can optionally hold maps of custom metrics and custom attributes
1081
- */
1082
- record(startTime, duration, options) {
1083
- if (startTime <= 0) {
1084
- throw ERROR_FACTORY.create("nonpositive trace startTime" /* ErrorCode.NONPOSITIVE_TRACE_START_TIME */, {
1085
- traceName: this.name
1086
- });
1087
- }
1088
- if (duration <= 0) {
1089
- throw ERROR_FACTORY.create("nonpositive trace duration" /* ErrorCode.NONPOSITIVE_TRACE_DURATION */, {
1090
- traceName: this.name
1091
- });
1092
- }
1093
- this.durationUs = Math.floor(duration * 1000);
1094
- this.startTimeUs = Math.floor(startTime * 1000);
1095
- if (options && options.attributes) {
1096
- this.customAttributes = Object.assign({}, options.attributes);
1097
- }
1098
- if (options && options.metrics) {
1099
- for (const metricName of Object.keys(options.metrics)) {
1100
- if (!isNaN(Number(options.metrics[metricName]))) {
1101
- this.counters[metricName] = Math.floor(Number(options.metrics[metricName]));
1102
- }
1103
- }
1104
- }
1105
- logTrace(this);
1106
- }
1107
- /**
1108
- * Increments a custom metric by a certain number or 1 if number not specified. Will create a new
1109
- * custom metric if one with the given name does not exist. The value will be floored down to an
1110
- * integer.
1111
- * @param counter Name of the custom metric
1112
- * @param numAsInteger Increment by value
1113
- */
1114
- incrementMetric(counter, numAsInteger = 1) {
1115
- if (this.counters[counter] === undefined) {
1116
- this.putMetric(counter, numAsInteger);
1117
- }
1118
- else {
1119
- this.putMetric(counter, this.counters[counter] + numAsInteger);
1120
- }
1121
- }
1122
- /**
1123
- * Sets a custom metric to a specified value. Will create a new custom metric if one with the
1124
- * given name does not exist. The value will be floored down to an integer.
1125
- * @param counter Name of the custom metric
1126
- * @param numAsInteger Set custom metric to this value
1127
- */
1128
- putMetric(counter, numAsInteger) {
1129
- if (isValidMetricName(counter, this.name)) {
1130
- this.counters[counter] = convertMetricValueToInteger(numAsInteger !== null && numAsInteger !== void 0 ? numAsInteger : 0);
1131
- }
1132
- else {
1133
- throw ERROR_FACTORY.create("invalid custom metric name" /* ErrorCode.INVALID_CUSTOM_METRIC_NAME */, {
1134
- customMetricName: counter
1135
- });
1136
- }
1137
- }
1138
- /**
1139
- * Returns the value of the custom metric by that name. If a custom metric with that name does
1140
- * not exist will return zero.
1141
- * @param counter
1142
- */
1143
- getMetric(counter) {
1144
- return this.counters[counter] || 0;
1145
- }
1146
- /**
1147
- * Sets a custom attribute of a trace to a certain value.
1148
- * @param attr
1149
- * @param value
1150
- */
1151
- putAttribute(attr, value) {
1152
- const isValidName = isValidCustomAttributeName(attr);
1153
- const isValidValue = isValidCustomAttributeValue(value);
1154
- if (isValidName && isValidValue) {
1155
- this.customAttributes[attr] = value;
1156
- return;
1157
- }
1158
- // Throw appropriate error when the attribute name or value is invalid.
1159
- if (!isValidName) {
1160
- throw ERROR_FACTORY.create("invalid attribute name" /* ErrorCode.INVALID_ATTRIBUTE_NAME */, {
1161
- attributeName: attr
1162
- });
1163
- }
1164
- if (!isValidValue) {
1165
- throw ERROR_FACTORY.create("invalid attribute value" /* ErrorCode.INVALID_ATTRIBUTE_VALUE */, {
1166
- attributeValue: value
1167
- });
1168
- }
1169
- }
1170
- /**
1171
- * Retrieves the value a custom attribute of a trace is set to.
1172
- * @param attr
1173
- */
1174
- getAttribute(attr) {
1175
- return this.customAttributes[attr];
1176
- }
1177
- removeAttribute(attr) {
1178
- if (this.customAttributes[attr] === undefined) {
1179
- return;
1180
- }
1181
- delete this.customAttributes[attr];
1182
- }
1183
- getAttributes() {
1184
- return Object.assign({}, this.customAttributes);
1185
- }
1186
- setStartTime(startTime) {
1187
- this.startTimeUs = startTime;
1188
- }
1189
- setDuration(duration) {
1190
- this.durationUs = duration;
1191
- }
1192
- /**
1193
- * Calculates and assigns the duration and start time of the trace using the measure performance
1194
- * entry.
1195
- */
1196
- calculateTraceMetrics() {
1197
- const perfMeasureEntries = this.api.getEntriesByName(this.traceMeasure);
1198
- const perfMeasureEntry = perfMeasureEntries && perfMeasureEntries[0];
1199
- if (perfMeasureEntry) {
1200
- this.durationUs = Math.floor(perfMeasureEntry.duration * 1000);
1201
- this.startTimeUs = Math.floor((perfMeasureEntry.startTime + this.api.getTimeOrigin()) * 1000);
1202
- }
1203
- }
1204
- /**
1205
- * @param navigationTimings A single element array which contains the navigationTIming object of
1206
- * the page load
1207
- * @param paintTimings A array which contains paintTiming object of the page load
1208
- * @param firstInputDelay First input delay in millisec
1209
- */
1210
- static createOobTrace(performanceController, navigationTimings, paintTimings, firstInputDelay) {
1211
- const route = Api.getInstance().getUrl();
1212
- if (!route) {
1213
- return;
1214
- }
1215
- const trace = new Trace(performanceController, OOB_TRACE_PAGE_LOAD_PREFIX + route, true);
1216
- const timeOriginUs = Math.floor(Api.getInstance().getTimeOrigin() * 1000);
1217
- trace.setStartTime(timeOriginUs);
1218
- // navigationTimings includes only one element.
1219
- if (navigationTimings && navigationTimings[0]) {
1220
- trace.setDuration(Math.floor(navigationTimings[0].duration * 1000));
1221
- trace.putMetric('domInteractive', Math.floor(navigationTimings[0].domInteractive * 1000));
1222
- trace.putMetric('domContentLoadedEventEnd', Math.floor(navigationTimings[0].domContentLoadedEventEnd * 1000));
1223
- trace.putMetric('loadEventEnd', Math.floor(navigationTimings[0].loadEventEnd * 1000));
1224
- }
1225
- const FIRST_PAINT = 'first-paint';
1226
- const FIRST_CONTENTFUL_PAINT = 'first-contentful-paint';
1227
- if (paintTimings) {
1228
- const firstPaint = paintTimings.find(paintObject => paintObject.name === FIRST_PAINT);
1229
- if (firstPaint && firstPaint.startTime) {
1230
- trace.putMetric(FIRST_PAINT_COUNTER_NAME, Math.floor(firstPaint.startTime * 1000));
1231
- }
1232
- const firstContentfulPaint = paintTimings.find(paintObject => paintObject.name === FIRST_CONTENTFUL_PAINT);
1233
- if (firstContentfulPaint && firstContentfulPaint.startTime) {
1234
- trace.putMetric(FIRST_CONTENTFUL_PAINT_COUNTER_NAME, Math.floor(firstContentfulPaint.startTime * 1000));
1235
- }
1236
- if (firstInputDelay) {
1237
- trace.putMetric(FIRST_INPUT_DELAY_COUNTER_NAME, Math.floor(firstInputDelay * 1000));
1238
- }
1239
- }
1240
- logTrace(trace);
1241
- }
1242
- static createUserTimingTrace(performanceController, measureName) {
1243
- const trace = new Trace(performanceController, measureName, false, measureName);
1244
- logTrace(trace);
1245
- }
1000
+ /**
1001
+ * @license
1002
+ * Copyright 2020 Google LLC
1003
+ *
1004
+ * Licensed under the Apache License, Version 2.0 (the "License");
1005
+ * you may not use this file except in compliance with the License.
1006
+ * You may obtain a copy of the License at
1007
+ *
1008
+ * http://www.apache.org/licenses/LICENSE-2.0
1009
+ *
1010
+ * Unless required by applicable law or agreed to in writing, software
1011
+ * distributed under the License is distributed on an "AS IS" BASIS,
1012
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1013
+ * See the License for the specific language governing permissions and
1014
+ * limitations under the License.
1015
+ */
1016
+ class Trace {
1017
+ /**
1018
+ * @param performanceController The performance controller running.
1019
+ * @param name The name of the trace.
1020
+ * @param isAuto If the trace is auto-instrumented.
1021
+ * @param traceMeasureName The name of the measure marker in user timing specification. This field
1022
+ * is only set when the trace is built for logging when the user directly uses the user timing
1023
+ * api (performance.mark and performance.measure).
1024
+ */
1025
+ constructor(performanceController, name, isAuto = false, traceMeasureName) {
1026
+ this.performanceController = performanceController;
1027
+ this.name = name;
1028
+ this.isAuto = isAuto;
1029
+ this.state = 1 /* TraceState.UNINITIALIZED */;
1030
+ this.customAttributes = {};
1031
+ this.counters = {};
1032
+ this.api = Api.getInstance();
1033
+ this.randomId = Math.floor(Math.random() * 1000000);
1034
+ if (!this.isAuto) {
1035
+ this.traceStartMark = `${TRACE_START_MARK_PREFIX}-${this.randomId}-${this.name}`;
1036
+ this.traceStopMark = `${TRACE_STOP_MARK_PREFIX}-${this.randomId}-${this.name}`;
1037
+ this.traceMeasure =
1038
+ traceMeasureName ||
1039
+ `${TRACE_MEASURE_PREFIX}-${this.randomId}-${this.name}`;
1040
+ if (traceMeasureName) {
1041
+ // For the case of direct user timing traces, no start stop will happen. The measure object
1042
+ // is already available.
1043
+ this.calculateTraceMetrics();
1044
+ }
1045
+ }
1046
+ }
1047
+ /**
1048
+ * Starts a trace. The measurement of the duration starts at this point.
1049
+ */
1050
+ start() {
1051
+ if (this.state !== 1 /* TraceState.UNINITIALIZED */) {
1052
+ throw ERROR_FACTORY.create("trace started" /* ErrorCode.TRACE_STARTED_BEFORE */, {
1053
+ traceName: this.name
1054
+ });
1055
+ }
1056
+ this.api.mark(this.traceStartMark);
1057
+ this.state = 2 /* TraceState.RUNNING */;
1058
+ }
1059
+ /**
1060
+ * Stops the trace. The measurement of the duration of the trace stops at this point and trace
1061
+ * is logged.
1062
+ */
1063
+ stop() {
1064
+ if (this.state !== 2 /* TraceState.RUNNING */) {
1065
+ throw ERROR_FACTORY.create("trace stopped" /* ErrorCode.TRACE_STOPPED_BEFORE */, {
1066
+ traceName: this.name
1067
+ });
1068
+ }
1069
+ this.state = 3 /* TraceState.TERMINATED */;
1070
+ this.api.mark(this.traceStopMark);
1071
+ this.api.measure(this.traceMeasure, this.traceStartMark, this.traceStopMark);
1072
+ this.calculateTraceMetrics();
1073
+ logTrace(this);
1074
+ }
1075
+ /**
1076
+ * Records a trace with predetermined values. If this method is used a trace is created and logged
1077
+ * directly. No need to use start and stop methods.
1078
+ * @param startTime Trace start time since epoch in millisec
1079
+ * @param duration The duration of the trace in millisec
1080
+ * @param options An object which can optionally hold maps of custom metrics and custom attributes
1081
+ */
1082
+ record(startTime, duration, options) {
1083
+ if (startTime <= 0) {
1084
+ throw ERROR_FACTORY.create("nonpositive trace startTime" /* ErrorCode.NONPOSITIVE_TRACE_START_TIME */, {
1085
+ traceName: this.name
1086
+ });
1087
+ }
1088
+ if (duration <= 0) {
1089
+ throw ERROR_FACTORY.create("nonpositive trace duration" /* ErrorCode.NONPOSITIVE_TRACE_DURATION */, {
1090
+ traceName: this.name
1091
+ });
1092
+ }
1093
+ this.durationUs = Math.floor(duration * 1000);
1094
+ this.startTimeUs = Math.floor(startTime * 1000);
1095
+ if (options && options.attributes) {
1096
+ this.customAttributes = Object.assign({}, options.attributes);
1097
+ }
1098
+ if (options && options.metrics) {
1099
+ for (const metricName of Object.keys(options.metrics)) {
1100
+ if (!isNaN(Number(options.metrics[metricName]))) {
1101
+ this.counters[metricName] = Math.floor(Number(options.metrics[metricName]));
1102
+ }
1103
+ }
1104
+ }
1105
+ logTrace(this);
1106
+ }
1107
+ /**
1108
+ * Increments a custom metric by a certain number or 1 if number not specified. Will create a new
1109
+ * custom metric if one with the given name does not exist. The value will be floored down to an
1110
+ * integer.
1111
+ * @param counter Name of the custom metric
1112
+ * @param numAsInteger Increment by value
1113
+ */
1114
+ incrementMetric(counter, numAsInteger = 1) {
1115
+ if (this.counters[counter] === undefined) {
1116
+ this.putMetric(counter, numAsInteger);
1117
+ }
1118
+ else {
1119
+ this.putMetric(counter, this.counters[counter] + numAsInteger);
1120
+ }
1121
+ }
1122
+ /**
1123
+ * Sets a custom metric to a specified value. Will create a new custom metric if one with the
1124
+ * given name does not exist. The value will be floored down to an integer.
1125
+ * @param counter Name of the custom metric
1126
+ * @param numAsInteger Set custom metric to this value
1127
+ */
1128
+ putMetric(counter, numAsInteger) {
1129
+ if (isValidMetricName(counter, this.name)) {
1130
+ this.counters[counter] = convertMetricValueToInteger(numAsInteger !== null && numAsInteger !== void 0 ? numAsInteger : 0);
1131
+ }
1132
+ else {
1133
+ throw ERROR_FACTORY.create("invalid custom metric name" /* ErrorCode.INVALID_CUSTOM_METRIC_NAME */, {
1134
+ customMetricName: counter
1135
+ });
1136
+ }
1137
+ }
1138
+ /**
1139
+ * Returns the value of the custom metric by that name. If a custom metric with that name does
1140
+ * not exist will return zero.
1141
+ * @param counter
1142
+ */
1143
+ getMetric(counter) {
1144
+ return this.counters[counter] || 0;
1145
+ }
1146
+ /**
1147
+ * Sets a custom attribute of a trace to a certain value.
1148
+ * @param attr
1149
+ * @param value
1150
+ */
1151
+ putAttribute(attr, value) {
1152
+ const isValidName = isValidCustomAttributeName(attr);
1153
+ const isValidValue = isValidCustomAttributeValue(value);
1154
+ if (isValidName && isValidValue) {
1155
+ this.customAttributes[attr] = value;
1156
+ return;
1157
+ }
1158
+ // Throw appropriate error when the attribute name or value is invalid.
1159
+ if (!isValidName) {
1160
+ throw ERROR_FACTORY.create("invalid attribute name" /* ErrorCode.INVALID_ATTRIBUTE_NAME */, {
1161
+ attributeName: attr
1162
+ });
1163
+ }
1164
+ if (!isValidValue) {
1165
+ throw ERROR_FACTORY.create("invalid attribute value" /* ErrorCode.INVALID_ATTRIBUTE_VALUE */, {
1166
+ attributeValue: value
1167
+ });
1168
+ }
1169
+ }
1170
+ /**
1171
+ * Retrieves the value a custom attribute of a trace is set to.
1172
+ * @param attr
1173
+ */
1174
+ getAttribute(attr) {
1175
+ return this.customAttributes[attr];
1176
+ }
1177
+ removeAttribute(attr) {
1178
+ if (this.customAttributes[attr] === undefined) {
1179
+ return;
1180
+ }
1181
+ delete this.customAttributes[attr];
1182
+ }
1183
+ getAttributes() {
1184
+ return Object.assign({}, this.customAttributes);
1185
+ }
1186
+ setStartTime(startTime) {
1187
+ this.startTimeUs = startTime;
1188
+ }
1189
+ setDuration(duration) {
1190
+ this.durationUs = duration;
1191
+ }
1192
+ /**
1193
+ * Calculates and assigns the duration and start time of the trace using the measure performance
1194
+ * entry.
1195
+ */
1196
+ calculateTraceMetrics() {
1197
+ const perfMeasureEntries = this.api.getEntriesByName(this.traceMeasure);
1198
+ const perfMeasureEntry = perfMeasureEntries && perfMeasureEntries[0];
1199
+ if (perfMeasureEntry) {
1200
+ this.durationUs = Math.floor(perfMeasureEntry.duration * 1000);
1201
+ this.startTimeUs = Math.floor((perfMeasureEntry.startTime + this.api.getTimeOrigin()) * 1000);
1202
+ }
1203
+ }
1204
+ /**
1205
+ * @param navigationTimings A single element array which contains the navigationTIming object of
1206
+ * the page load
1207
+ * @param paintTimings A array which contains paintTiming object of the page load
1208
+ * @param firstInputDelay First input delay in millisec
1209
+ */
1210
+ static createOobTrace(performanceController, navigationTimings, paintTimings, firstInputDelay) {
1211
+ const route = Api.getInstance().getUrl();
1212
+ if (!route) {
1213
+ return;
1214
+ }
1215
+ const trace = new Trace(performanceController, OOB_TRACE_PAGE_LOAD_PREFIX + route, true);
1216
+ const timeOriginUs = Math.floor(Api.getInstance().getTimeOrigin() * 1000);
1217
+ trace.setStartTime(timeOriginUs);
1218
+ // navigationTimings includes only one element.
1219
+ if (navigationTimings && navigationTimings[0]) {
1220
+ trace.setDuration(Math.floor(navigationTimings[0].duration * 1000));
1221
+ trace.putMetric('domInteractive', Math.floor(navigationTimings[0].domInteractive * 1000));
1222
+ trace.putMetric('domContentLoadedEventEnd', Math.floor(navigationTimings[0].domContentLoadedEventEnd * 1000));
1223
+ trace.putMetric('loadEventEnd', Math.floor(navigationTimings[0].loadEventEnd * 1000));
1224
+ }
1225
+ const FIRST_PAINT = 'first-paint';
1226
+ const FIRST_CONTENTFUL_PAINT = 'first-contentful-paint';
1227
+ if (paintTimings) {
1228
+ const firstPaint = paintTimings.find(paintObject => paintObject.name === FIRST_PAINT);
1229
+ if (firstPaint && firstPaint.startTime) {
1230
+ trace.putMetric(FIRST_PAINT_COUNTER_NAME, Math.floor(firstPaint.startTime * 1000));
1231
+ }
1232
+ const firstContentfulPaint = paintTimings.find(paintObject => paintObject.name === FIRST_CONTENTFUL_PAINT);
1233
+ if (firstContentfulPaint && firstContentfulPaint.startTime) {
1234
+ trace.putMetric(FIRST_CONTENTFUL_PAINT_COUNTER_NAME, Math.floor(firstContentfulPaint.startTime * 1000));
1235
+ }
1236
+ if (firstInputDelay) {
1237
+ trace.putMetric(FIRST_INPUT_DELAY_COUNTER_NAME, Math.floor(firstInputDelay * 1000));
1238
+ }
1239
+ }
1240
+ logTrace(trace);
1241
+ }
1242
+ static createUserTimingTrace(performanceController, measureName) {
1243
+ const trace = new Trace(performanceController, measureName, false, measureName);
1244
+ logTrace(trace);
1245
+ }
1246
1246
  }
1247
1247
 
1248
- /**
1249
- * @license
1250
- * Copyright 2020 Google LLC
1251
- *
1252
- * Licensed under the Apache License, Version 2.0 (the "License");
1253
- * you may not use this file except in compliance with the License.
1254
- * You may obtain a copy of the License at
1255
- *
1256
- * http://www.apache.org/licenses/LICENSE-2.0
1257
- *
1258
- * Unless required by applicable law or agreed to in writing, software
1259
- * distributed under the License is distributed on an "AS IS" BASIS,
1260
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1261
- * See the License for the specific language governing permissions and
1262
- * limitations under the License.
1263
- */
1264
- function createNetworkRequestEntry(performanceController, entry) {
1265
- const performanceEntry = entry;
1266
- if (!performanceEntry || performanceEntry.responseStart === undefined) {
1267
- return;
1268
- }
1269
- const timeOrigin = Api.getInstance().getTimeOrigin();
1270
- const startTimeUs = Math.floor((performanceEntry.startTime + timeOrigin) * 1000);
1271
- const timeToResponseInitiatedUs = performanceEntry.responseStart
1272
- ? Math.floor((performanceEntry.responseStart - performanceEntry.startTime) * 1000)
1273
- : undefined;
1274
- const timeToResponseCompletedUs = Math.floor((performanceEntry.responseEnd - performanceEntry.startTime) * 1000);
1275
- // Remove the query params from logged network request url.
1276
- const url = performanceEntry.name && performanceEntry.name.split('?')[0];
1277
- const networkRequest = {
1278
- performanceController,
1279
- url,
1280
- responsePayloadBytes: performanceEntry.transferSize,
1281
- startTimeUs,
1282
- timeToResponseInitiatedUs,
1283
- timeToResponseCompletedUs
1284
- };
1285
- logNetworkRequest(networkRequest);
1248
+ /**
1249
+ * @license
1250
+ * Copyright 2020 Google LLC
1251
+ *
1252
+ * Licensed under the Apache License, Version 2.0 (the "License");
1253
+ * you may not use this file except in compliance with the License.
1254
+ * You may obtain a copy of the License at
1255
+ *
1256
+ * http://www.apache.org/licenses/LICENSE-2.0
1257
+ *
1258
+ * Unless required by applicable law or agreed to in writing, software
1259
+ * distributed under the License is distributed on an "AS IS" BASIS,
1260
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1261
+ * See the License for the specific language governing permissions and
1262
+ * limitations under the License.
1263
+ */
1264
+ function createNetworkRequestEntry(performanceController, entry) {
1265
+ const performanceEntry = entry;
1266
+ if (!performanceEntry || performanceEntry.responseStart === undefined) {
1267
+ return;
1268
+ }
1269
+ const timeOrigin = Api.getInstance().getTimeOrigin();
1270
+ const startTimeUs = Math.floor((performanceEntry.startTime + timeOrigin) * 1000);
1271
+ const timeToResponseInitiatedUs = performanceEntry.responseStart
1272
+ ? Math.floor((performanceEntry.responseStart - performanceEntry.startTime) * 1000)
1273
+ : undefined;
1274
+ const timeToResponseCompletedUs = Math.floor((performanceEntry.responseEnd - performanceEntry.startTime) * 1000);
1275
+ // Remove the query params from logged network request url.
1276
+ const url = performanceEntry.name && performanceEntry.name.split('?')[0];
1277
+ const networkRequest = {
1278
+ performanceController,
1279
+ url,
1280
+ responsePayloadBytes: performanceEntry.transferSize,
1281
+ startTimeUs,
1282
+ timeToResponseInitiatedUs,
1283
+ timeToResponseCompletedUs
1284
+ };
1285
+ logNetworkRequest(networkRequest);
1286
1286
  }
1287
1287
 
1288
- /**
1289
- * @license
1290
- * Copyright 2020 Google LLC
1291
- *
1292
- * Licensed under the Apache License, Version 2.0 (the "License");
1293
- * you may not use this file except in compliance with the License.
1294
- * You may obtain a copy of the License at
1295
- *
1296
- * http://www.apache.org/licenses/LICENSE-2.0
1297
- *
1298
- * Unless required by applicable law or agreed to in writing, software
1299
- * distributed under the License is distributed on an "AS IS" BASIS,
1300
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1301
- * See the License for the specific language governing permissions and
1302
- * limitations under the License.
1303
- */
1304
- const FID_WAIT_TIME_MS = 5000;
1305
- function setupOobResources(performanceController) {
1306
- // Do not initialize unless iid is available.
1307
- if (!getIid()) {
1308
- return;
1309
- }
1310
- // The load event might not have fired yet, and that means performance navigation timing
1311
- // object has a duration of 0. The setup should run after all current tasks in js queue.
1312
- setTimeout(() => setupOobTraces(performanceController), 0);
1313
- setTimeout(() => setupNetworkRequests(performanceController), 0);
1314
- setTimeout(() => setupUserTimingTraces(performanceController), 0);
1315
- }
1316
- function setupNetworkRequests(performanceController) {
1317
- const api = Api.getInstance();
1318
- const resources = api.getEntriesByType('resource');
1319
- for (const resource of resources) {
1320
- createNetworkRequestEntry(performanceController, resource);
1321
- }
1322
- api.setupObserver('resource', entry => createNetworkRequestEntry(performanceController, entry));
1323
- }
1324
- function setupOobTraces(performanceController) {
1325
- const api = Api.getInstance();
1326
- const navigationTimings = api.getEntriesByType('navigation');
1327
- const paintTimings = api.getEntriesByType('paint');
1328
- // If First Input Delay polyfill is added to the page, report the fid value.
1329
- // https://github.com/GoogleChromeLabs/first-input-delay
1330
- if (api.onFirstInputDelay) {
1331
- // If the fid call back is not called for certain time, continue without it.
1332
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1333
- let timeoutId = setTimeout(() => {
1334
- Trace.createOobTrace(performanceController, navigationTimings, paintTimings);
1335
- timeoutId = undefined;
1336
- }, FID_WAIT_TIME_MS);
1337
- api.onFirstInputDelay((fid) => {
1338
- if (timeoutId) {
1339
- clearTimeout(timeoutId);
1340
- Trace.createOobTrace(performanceController, navigationTimings, paintTimings, fid);
1341
- }
1342
- });
1343
- }
1344
- else {
1345
- Trace.createOobTrace(performanceController, navigationTimings, paintTimings);
1346
- }
1347
- }
1348
- function setupUserTimingTraces(performanceController) {
1349
- const api = Api.getInstance();
1350
- // Run through the measure performance entries collected up to this point.
1351
- const measures = api.getEntriesByType('measure');
1352
- for (const measure of measures) {
1353
- createUserTimingTrace(performanceController, measure);
1354
- }
1355
- // Setup an observer to capture the measures from this point on.
1356
- api.setupObserver('measure', entry => createUserTimingTrace(performanceController, entry));
1357
- }
1358
- function createUserTimingTrace(performanceController, measure) {
1359
- const measureName = measure.name;
1360
- // Do not create a trace, if the user timing marks and measures are created by the sdk itself.
1361
- if (measureName.substring(0, TRACE_MEASURE_PREFIX.length) ===
1362
- TRACE_MEASURE_PREFIX) {
1363
- return;
1364
- }
1365
- Trace.createUserTimingTrace(performanceController, measureName);
1288
+ /**
1289
+ * @license
1290
+ * Copyright 2020 Google LLC
1291
+ *
1292
+ * Licensed under the Apache License, Version 2.0 (the "License");
1293
+ * you may not use this file except in compliance with the License.
1294
+ * You may obtain a copy of the License at
1295
+ *
1296
+ * http://www.apache.org/licenses/LICENSE-2.0
1297
+ *
1298
+ * Unless required by applicable law or agreed to in writing, software
1299
+ * distributed under the License is distributed on an "AS IS" BASIS,
1300
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1301
+ * See the License for the specific language governing permissions and
1302
+ * limitations under the License.
1303
+ */
1304
+ const FID_WAIT_TIME_MS = 5000;
1305
+ function setupOobResources(performanceController) {
1306
+ // Do not initialize unless iid is available.
1307
+ if (!getIid()) {
1308
+ return;
1309
+ }
1310
+ // The load event might not have fired yet, and that means performance navigation timing
1311
+ // object has a duration of 0. The setup should run after all current tasks in js queue.
1312
+ setTimeout(() => setupOobTraces(performanceController), 0);
1313
+ setTimeout(() => setupNetworkRequests(performanceController), 0);
1314
+ setTimeout(() => setupUserTimingTraces(performanceController), 0);
1315
+ }
1316
+ function setupNetworkRequests(performanceController) {
1317
+ const api = Api.getInstance();
1318
+ const resources = api.getEntriesByType('resource');
1319
+ for (const resource of resources) {
1320
+ createNetworkRequestEntry(performanceController, resource);
1321
+ }
1322
+ api.setupObserver('resource', entry => createNetworkRequestEntry(performanceController, entry));
1323
+ }
1324
+ function setupOobTraces(performanceController) {
1325
+ const api = Api.getInstance();
1326
+ const navigationTimings = api.getEntriesByType('navigation');
1327
+ const paintTimings = api.getEntriesByType('paint');
1328
+ // If First Input Delay polyfill is added to the page, report the fid value.
1329
+ // https://github.com/GoogleChromeLabs/first-input-delay
1330
+ if (api.onFirstInputDelay) {
1331
+ // If the fid call back is not called for certain time, continue without it.
1332
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1333
+ let timeoutId = setTimeout(() => {
1334
+ Trace.createOobTrace(performanceController, navigationTimings, paintTimings);
1335
+ timeoutId = undefined;
1336
+ }, FID_WAIT_TIME_MS);
1337
+ api.onFirstInputDelay((fid) => {
1338
+ if (timeoutId) {
1339
+ clearTimeout(timeoutId);
1340
+ Trace.createOobTrace(performanceController, navigationTimings, paintTimings, fid);
1341
+ }
1342
+ });
1343
+ }
1344
+ else {
1345
+ Trace.createOobTrace(performanceController, navigationTimings, paintTimings);
1346
+ }
1347
+ }
1348
+ function setupUserTimingTraces(performanceController) {
1349
+ const api = Api.getInstance();
1350
+ // Run through the measure performance entries collected up to this point.
1351
+ const measures = api.getEntriesByType('measure');
1352
+ for (const measure of measures) {
1353
+ createUserTimingTrace(performanceController, measure);
1354
+ }
1355
+ // Setup an observer to capture the measures from this point on.
1356
+ api.setupObserver('measure', entry => createUserTimingTrace(performanceController, entry));
1357
+ }
1358
+ function createUserTimingTrace(performanceController, measure) {
1359
+ const measureName = measure.name;
1360
+ // Do not create a trace, if the user timing marks and measures are created by the sdk itself.
1361
+ if (measureName.substring(0, TRACE_MEASURE_PREFIX.length) ===
1362
+ TRACE_MEASURE_PREFIX) {
1363
+ return;
1364
+ }
1365
+ Trace.createUserTimingTrace(performanceController, measureName);
1366
1366
  }
1367
1367
 
1368
- /**
1369
- * @license
1370
- * Copyright 2020 Google LLC
1371
- *
1372
- * Licensed under the Apache License, Version 2.0 (the "License");
1373
- * you may not use this file except in compliance with the License.
1374
- * You may obtain a copy of the License at
1375
- *
1376
- * http://www.apache.org/licenses/LICENSE-2.0
1377
- *
1378
- * Unless required by applicable law or agreed to in writing, software
1379
- * distributed under the License is distributed on an "AS IS" BASIS,
1380
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1381
- * See the License for the specific language governing permissions and
1382
- * limitations under the License.
1383
- */
1384
- class PerformanceController {
1385
- constructor(app, installations) {
1386
- this.app = app;
1387
- this.installations = installations;
1388
- this.initialized = false;
1389
- }
1390
- /**
1391
- * This method *must* be called internally as part of creating a
1392
- * PerformanceController instance.
1393
- *
1394
- * Currently it's not possible to pass the settings object through the
1395
- * constructor using Components, so this method exists to be called with the
1396
- * desired settings, to ensure nothing is collected without the user's
1397
- * consent.
1398
- */
1399
- _init(settings) {
1400
- if (this.initialized) {
1401
- return;
1402
- }
1403
- if ((settings === null || settings === void 0 ? void 0 : settings.dataCollectionEnabled) !== undefined) {
1404
- this.dataCollectionEnabled = settings.dataCollectionEnabled;
1405
- }
1406
- if ((settings === null || settings === void 0 ? void 0 : settings.instrumentationEnabled) !== undefined) {
1407
- this.instrumentationEnabled = settings.instrumentationEnabled;
1408
- }
1409
- if (Api.getInstance().requiredApisAvailable()) {
1410
- validateIndexedDBOpenable()
1411
- .then(isAvailable => {
1412
- if (isAvailable) {
1413
- setupTransportService();
1414
- getInitializationPromise(this).then(() => setupOobResources(this), () => setupOobResources(this));
1415
- this.initialized = true;
1416
- }
1417
- })
1418
- .catch(error => {
1419
- consoleLogger.info(`Environment doesn't support IndexedDB: ${error}`);
1420
- });
1421
- }
1422
- else {
1423
- consoleLogger.info('Firebase Performance cannot start if the browser does not support ' +
1424
- '"Fetch" and "Promise", or cookies are disabled.');
1425
- }
1426
- }
1427
- set instrumentationEnabled(val) {
1428
- SettingsService.getInstance().instrumentationEnabled = val;
1429
- }
1430
- get instrumentationEnabled() {
1431
- return SettingsService.getInstance().instrumentationEnabled;
1432
- }
1433
- set dataCollectionEnabled(val) {
1434
- SettingsService.getInstance().dataCollectionEnabled = val;
1435
- }
1436
- get dataCollectionEnabled() {
1437
- return SettingsService.getInstance().dataCollectionEnabled;
1438
- }
1368
+ /**
1369
+ * @license
1370
+ * Copyright 2020 Google LLC
1371
+ *
1372
+ * Licensed under the Apache License, Version 2.0 (the "License");
1373
+ * you may not use this file except in compliance with the License.
1374
+ * You may obtain a copy of the License at
1375
+ *
1376
+ * http://www.apache.org/licenses/LICENSE-2.0
1377
+ *
1378
+ * Unless required by applicable law or agreed to in writing, software
1379
+ * distributed under the License is distributed on an "AS IS" BASIS,
1380
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1381
+ * See the License for the specific language governing permissions and
1382
+ * limitations under the License.
1383
+ */
1384
+ class PerformanceController {
1385
+ constructor(app, installations) {
1386
+ this.app = app;
1387
+ this.installations = installations;
1388
+ this.initialized = false;
1389
+ }
1390
+ /**
1391
+ * This method *must* be called internally as part of creating a
1392
+ * PerformanceController instance.
1393
+ *
1394
+ * Currently it's not possible to pass the settings object through the
1395
+ * constructor using Components, so this method exists to be called with the
1396
+ * desired settings, to ensure nothing is collected without the user's
1397
+ * consent.
1398
+ */
1399
+ _init(settings) {
1400
+ if (this.initialized) {
1401
+ return;
1402
+ }
1403
+ if ((settings === null || settings === void 0 ? void 0 : settings.dataCollectionEnabled) !== undefined) {
1404
+ this.dataCollectionEnabled = settings.dataCollectionEnabled;
1405
+ }
1406
+ if ((settings === null || settings === void 0 ? void 0 : settings.instrumentationEnabled) !== undefined) {
1407
+ this.instrumentationEnabled = settings.instrumentationEnabled;
1408
+ }
1409
+ if (Api.getInstance().requiredApisAvailable()) {
1410
+ validateIndexedDBOpenable()
1411
+ .then(isAvailable => {
1412
+ if (isAvailable) {
1413
+ setupTransportService();
1414
+ getInitializationPromise(this).then(() => setupOobResources(this), () => setupOobResources(this));
1415
+ this.initialized = true;
1416
+ }
1417
+ })
1418
+ .catch(error => {
1419
+ consoleLogger.info(`Environment doesn't support IndexedDB: ${error}`);
1420
+ });
1421
+ }
1422
+ else {
1423
+ consoleLogger.info('Firebase Performance cannot start if the browser does not support ' +
1424
+ '"Fetch" and "Promise", or cookies are disabled.');
1425
+ }
1426
+ }
1427
+ set instrumentationEnabled(val) {
1428
+ SettingsService.getInstance().instrumentationEnabled = val;
1429
+ }
1430
+ get instrumentationEnabled() {
1431
+ return SettingsService.getInstance().instrumentationEnabled;
1432
+ }
1433
+ set dataCollectionEnabled(val) {
1434
+ SettingsService.getInstance().dataCollectionEnabled = val;
1435
+ }
1436
+ get dataCollectionEnabled() {
1437
+ return SettingsService.getInstance().dataCollectionEnabled;
1438
+ }
1439
1439
  }
1440
1440
 
1441
- /**
1442
- * The Firebase Performance Monitoring Web SDK.
1443
- * This SDK does not work in a Node.js environment.
1444
- *
1445
- * @packageDocumentation
1446
- */
1447
- const DEFAULT_ENTRY_NAME = '[DEFAULT]';
1448
- /**
1449
- * Returns a {@link FirebasePerformance} instance for the given app.
1450
- * @param app - The {@link @firebase/app#FirebaseApp} to use.
1451
- * @public
1452
- */
1453
- function getPerformance(app = getApp()) {
1454
- app = getModularInstance(app);
1455
- const provider = _getProvider(app, 'performance');
1456
- const perfInstance = provider.getImmediate();
1457
- return perfInstance;
1458
- }
1459
- /**
1460
- * Returns a {@link FirebasePerformance} instance for the given app. Can only be called once.
1461
- * @param app - The {@link @firebase/app#FirebaseApp} to use.
1462
- * @param settings - Optional settings for the {@link FirebasePerformance} instance.
1463
- * @public
1464
- */
1465
- function initializePerformance(app, settings) {
1466
- app = getModularInstance(app);
1467
- const provider = _getProvider(app, 'performance');
1468
- // throw if an instance was already created.
1469
- // It could happen if initializePerformance() is called more than once, or getPerformance() is called first.
1470
- if (provider.isInitialized()) {
1471
- const existingInstance = provider.getImmediate();
1472
- const initialSettings = provider.getOptions();
1473
- if (deepEqual(initialSettings, settings !== null && settings !== void 0 ? settings : {})) {
1474
- return existingInstance;
1475
- }
1476
- else {
1477
- throw ERROR_FACTORY.create("already initialized" /* ErrorCode.ALREADY_INITIALIZED */);
1478
- }
1479
- }
1480
- const perfInstance = provider.initialize({
1481
- options: settings
1482
- });
1483
- return perfInstance;
1484
- }
1485
- /**
1486
- * Returns a new `PerformanceTrace` instance.
1487
- * @param performance - The {@link FirebasePerformance} instance to use.
1488
- * @param name - The name of the trace.
1489
- * @public
1490
- */
1491
- function trace(performance, name) {
1492
- performance = getModularInstance(performance);
1493
- return new Trace(performance, name);
1494
- }
1495
- const factory = (container, { options: settings }) => {
1496
- // Dependencies
1497
- const app = container.getProvider('app').getImmediate();
1498
- const installations = container
1499
- .getProvider('installations-internal')
1500
- .getImmediate();
1501
- if (app.name !== DEFAULT_ENTRY_NAME) {
1502
- throw ERROR_FACTORY.create("FB not default" /* ErrorCode.FB_NOT_DEFAULT */);
1503
- }
1504
- if (typeof window === 'undefined') {
1505
- throw ERROR_FACTORY.create("no window" /* ErrorCode.NO_WINDOW */);
1506
- }
1507
- setupApi(window);
1508
- const perfInstance = new PerformanceController(app, installations);
1509
- perfInstance._init(settings);
1510
- return perfInstance;
1511
- };
1512
- function registerPerformance() {
1513
- _registerComponent(new Component('performance', factory, "PUBLIC" /* ComponentType.PUBLIC */));
1514
- registerVersion(name, version);
1515
- // BUILD_TARGET will be replaced by values like esm2017, cjs2017, etc during the compilation
1516
- registerVersion(name, version, 'esm2017');
1517
- }
1441
+ /**
1442
+ * The Firebase Performance Monitoring Web SDK.
1443
+ * This SDK does not work in a Node.js environment.
1444
+ *
1445
+ * @packageDocumentation
1446
+ */
1447
+ const DEFAULT_ENTRY_NAME = '[DEFAULT]';
1448
+ /**
1449
+ * Returns a {@link FirebasePerformance} instance for the given app.
1450
+ * @param app - The {@link @firebase/app#FirebaseApp} to use.
1451
+ * @public
1452
+ */
1453
+ function getPerformance(app = getApp()) {
1454
+ app = getModularInstance(app);
1455
+ const provider = _getProvider(app, 'performance');
1456
+ const perfInstance = provider.getImmediate();
1457
+ return perfInstance;
1458
+ }
1459
+ /**
1460
+ * Returns a {@link FirebasePerformance} instance for the given app. Can only be called once.
1461
+ * @param app - The {@link @firebase/app#FirebaseApp} to use.
1462
+ * @param settings - Optional settings for the {@link FirebasePerformance} instance.
1463
+ * @public
1464
+ */
1465
+ function initializePerformance(app, settings) {
1466
+ app = getModularInstance(app);
1467
+ const provider = _getProvider(app, 'performance');
1468
+ // throw if an instance was already created.
1469
+ // It could happen if initializePerformance() is called more than once, or getPerformance() is called first.
1470
+ if (provider.isInitialized()) {
1471
+ const existingInstance = provider.getImmediate();
1472
+ const initialSettings = provider.getOptions();
1473
+ if (deepEqual(initialSettings, settings !== null && settings !== void 0 ? settings : {})) {
1474
+ return existingInstance;
1475
+ }
1476
+ else {
1477
+ throw ERROR_FACTORY.create("already initialized" /* ErrorCode.ALREADY_INITIALIZED */);
1478
+ }
1479
+ }
1480
+ const perfInstance = provider.initialize({
1481
+ options: settings
1482
+ });
1483
+ return perfInstance;
1484
+ }
1485
+ /**
1486
+ * Returns a new `PerformanceTrace` instance.
1487
+ * @param performance - The {@link FirebasePerformance} instance to use.
1488
+ * @param name - The name of the trace.
1489
+ * @public
1490
+ */
1491
+ function trace(performance, name) {
1492
+ performance = getModularInstance(performance);
1493
+ return new Trace(performance, name);
1494
+ }
1495
+ const factory = (container, { options: settings }) => {
1496
+ // Dependencies
1497
+ const app = container.getProvider('app').getImmediate();
1498
+ const installations = container
1499
+ .getProvider('installations-internal')
1500
+ .getImmediate();
1501
+ if (app.name !== DEFAULT_ENTRY_NAME) {
1502
+ throw ERROR_FACTORY.create("FB not default" /* ErrorCode.FB_NOT_DEFAULT */);
1503
+ }
1504
+ if (typeof window === 'undefined') {
1505
+ throw ERROR_FACTORY.create("no window" /* ErrorCode.NO_WINDOW */);
1506
+ }
1507
+ setupApi(window);
1508
+ const perfInstance = new PerformanceController(app, installations);
1509
+ perfInstance._init(settings);
1510
+ return perfInstance;
1511
+ };
1512
+ function registerPerformance() {
1513
+ _registerComponent(new Component('performance', factory, "PUBLIC" /* ComponentType.PUBLIC */));
1514
+ registerVersion(name, version);
1515
+ // BUILD_TARGET will be replaced by values like esm2017, cjs2017, etc during the compilation
1516
+ registerVersion(name, version, 'esm2017');
1517
+ }
1518
1518
  registerPerformance();
1519
1519
 
1520
1520
  export { getPerformance, initializePerformance, trace };