@newrelic/browser-agent 1.239.1 → 1.241.0

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 (178) hide show
  1. package/README.md +4 -0
  2. package/dist/cjs/cdn/pro.js +3 -2
  3. package/dist/cjs/cdn/spa.js +4 -3
  4. package/dist/cjs/common/config/state/init.js +25 -17
  5. package/dist/cjs/common/constants/env.cdn.js +1 -1
  6. package/dist/cjs/common/constants/env.npm.js +1 -1
  7. package/dist/cjs/common/constants/runtime.js +9 -5
  8. package/dist/cjs/common/harvest/harvest.js +5 -3
  9. package/dist/cjs/common/vitals/constants.js +17 -0
  10. package/dist/cjs/common/vitals/cumulative-layout-shift.js +27 -0
  11. package/dist/cjs/common/vitals/first-contentful-paint.js +49 -0
  12. package/dist/cjs/common/vitals/first-input-delay.js +32 -0
  13. package/dist/{esm/features/page_view_timing → cjs/common/vitals}/first-paint.js +19 -17
  14. package/dist/cjs/common/vitals/interaction-to-next-paint.js +29 -0
  15. package/dist/cjs/common/vitals/largest-contentful-paint.js +41 -0
  16. package/dist/cjs/common/vitals/long-task.js +64 -0
  17. package/dist/cjs/common/vitals/time-to-first-byte.js +36 -0
  18. package/dist/cjs/common/vitals/vital-metric.js +71 -0
  19. package/dist/cjs/features/ajax/aggregate/index.js +4 -1
  20. package/dist/cjs/features/metrics/aggregate/index.js +17 -7
  21. package/dist/cjs/features/page_view_event/aggregate/index.js +18 -40
  22. package/dist/cjs/features/page_view_event/constants.js +2 -8
  23. package/dist/cjs/features/page_view_event/instrument/index.js +0 -22
  24. package/dist/cjs/features/page_view_timing/aggregate/index.js +36 -147
  25. package/dist/cjs/features/page_view_timing/instrument/index.js +0 -3
  26. package/dist/cjs/features/session_replay/aggregate/index.js +81 -35
  27. package/dist/cjs/features/session_trace/aggregate/index.js +13 -1
  28. package/dist/cjs/features/spa/aggregate/index.js +4 -3
  29. package/dist/cjs/loaders/agent.js +3 -0
  30. package/dist/cjs/loaders/api/api.js +2 -0
  31. package/dist/cjs/loaders/api/apiAsync.js +4 -2
  32. package/dist/cjs/loaders/browser-agent.js +2 -1
  33. package/dist/cjs/loaders/configure/configure.js +13 -1
  34. package/dist/cjs/loaders/configure/public-path.js +13 -0
  35. package/dist/cjs/loaders/configure/public-path.npm.js +10 -0
  36. package/dist/esm/cdn/pro.js +2 -1
  37. package/dist/esm/cdn/spa.js +2 -1
  38. package/dist/esm/common/config/state/init.js +25 -17
  39. package/dist/esm/common/constants/env.cdn.js +1 -1
  40. package/dist/esm/common/constants/env.npm.js +1 -1
  41. package/dist/esm/common/constants/runtime.js +5 -3
  42. package/dist/esm/common/harvest/harvest.js +6 -4
  43. package/dist/esm/common/vitals/constants.js +10 -0
  44. package/dist/esm/common/vitals/cumulative-layout-shift.js +20 -0
  45. package/dist/esm/common/vitals/first-contentful-paint.js +41 -0
  46. package/dist/esm/common/vitals/first-input-delay.js +25 -0
  47. package/dist/{cjs/features/page_view_timing → esm/common/vitals}/first-paint.js +12 -24
  48. package/dist/esm/common/vitals/interaction-to-next-paint.js +22 -0
  49. package/dist/esm/common/vitals/largest-contentful-paint.js +34 -0
  50. package/dist/esm/common/vitals/long-task.js +57 -0
  51. package/dist/esm/common/vitals/time-to-first-byte.js +29 -0
  52. package/dist/esm/common/vitals/vital-metric.js +64 -0
  53. package/dist/esm/features/ajax/aggregate/index.js +4 -1
  54. package/dist/esm/features/metrics/aggregate/index.js +18 -8
  55. package/dist/esm/features/page_view_event/aggregate/index.js +20 -42
  56. package/dist/esm/features/page_view_event/constants.js +1 -4
  57. package/dist/esm/features/page_view_event/instrument/index.js +0 -22
  58. package/dist/esm/features/page_view_timing/aggregate/index.js +37 -148
  59. package/dist/esm/features/page_view_timing/instrument/index.js +0 -3
  60. package/dist/esm/features/session_replay/aggregate/index.js +81 -35
  61. package/dist/esm/features/session_trace/aggregate/index.js +13 -1
  62. package/dist/esm/features/spa/aggregate/index.js +4 -3
  63. package/dist/esm/loaders/agent.js +2 -0
  64. package/dist/esm/loaders/api/api.js +2 -0
  65. package/dist/esm/loaders/api/apiAsync.js +5 -3
  66. package/dist/esm/loaders/browser-agent.js +2 -1
  67. package/dist/esm/loaders/configure/configure.js +13 -1
  68. package/dist/esm/loaders/configure/public-path.js +6 -0
  69. package/dist/esm/loaders/configure/public-path.npm.js +3 -0
  70. package/dist/types/common/config/state/init.d.ts.map +1 -1
  71. package/dist/types/common/constants/runtime.d.ts +3 -1
  72. package/dist/types/common/constants/runtime.d.ts.map +1 -1
  73. package/dist/types/common/harvest/harvest.d.ts +0 -1
  74. package/dist/types/common/harvest/harvest.d.ts.map +1 -1
  75. package/dist/types/common/vitals/constants.d.ts +11 -0
  76. package/dist/types/common/vitals/constants.d.ts.map +1 -0
  77. package/dist/types/common/vitals/cumulative-layout-shift.d.ts +3 -0
  78. package/dist/types/common/vitals/cumulative-layout-shift.d.ts.map +1 -0
  79. package/dist/types/common/vitals/first-contentful-paint.d.ts +3 -0
  80. package/dist/types/common/vitals/first-contentful-paint.d.ts.map +1 -0
  81. package/dist/types/common/vitals/first-input-delay.d.ts +3 -0
  82. package/dist/types/common/vitals/first-input-delay.d.ts.map +1 -0
  83. package/dist/types/common/vitals/first-paint.d.ts +3 -0
  84. package/dist/types/common/vitals/first-paint.d.ts.map +1 -0
  85. package/dist/types/common/vitals/interaction-to-next-paint.d.ts +3 -0
  86. package/dist/types/common/vitals/interaction-to-next-paint.d.ts.map +1 -0
  87. package/dist/types/common/vitals/largest-contentful-paint.d.ts +3 -0
  88. package/dist/types/common/vitals/largest-contentful-paint.d.ts.map +1 -0
  89. package/dist/types/common/vitals/long-task.d.ts +3 -0
  90. package/dist/types/common/vitals/long-task.d.ts.map +1 -0
  91. package/dist/types/common/vitals/time-to-first-byte.d.ts +3 -0
  92. package/dist/types/common/vitals/time-to-first-byte.d.ts.map +1 -0
  93. package/dist/types/common/vitals/vital-metric.d.ts +18 -0
  94. package/dist/types/common/vitals/vital-metric.d.ts.map +1 -0
  95. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  96. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  97. package/dist/types/features/page_view_event/aggregate/index.d.ts +3 -2
  98. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  99. package/dist/types/features/page_view_event/constants.d.ts +0 -3
  100. package/dist/types/features/page_view_event/constants.d.ts.map +1 -1
  101. package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
  102. package/dist/types/features/page_view_timing/aggregate/index.d.ts +1 -3
  103. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  104. package/dist/types/features/page_view_timing/instrument/index.d.ts.map +1 -1
  105. package/dist/types/features/session_replay/aggregate/index.d.ts +16 -4
  106. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  107. package/dist/types/features/session_trace/aggregate/index.d.ts +9 -1
  108. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  109. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  110. package/dist/types/loaders/agent.d.ts.map +1 -1
  111. package/dist/types/loaders/api/api.d.ts.map +1 -1
  112. package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
  113. package/dist/types/loaders/browser-agent.d.ts.map +1 -1
  114. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  115. package/dist/types/loaders/configure/public-path.d.ts +2 -0
  116. package/dist/types/loaders/configure/public-path.d.ts.map +1 -0
  117. package/dist/types/loaders/configure/public-path.npm.d.ts +2 -0
  118. package/dist/types/loaders/configure/public-path.npm.d.ts.map +1 -0
  119. package/package.json +2 -3
  120. package/src/cdn/pro.js +2 -0
  121. package/src/cdn/spa.js +2 -0
  122. package/src/common/config/state/init.js +21 -17
  123. package/src/common/constants/runtime.js +7 -3
  124. package/src/common/constants/runtime.test.js +8 -0
  125. package/src/common/harvest/harvest-scheduler.test.js +2 -2
  126. package/src/common/harvest/harvest.js +6 -4
  127. package/src/common/harvest/harvest.test.js +17 -0
  128. package/src/common/vitals/__mocks__/web-vitals.js +19 -0
  129. package/src/common/vitals/constants.js +10 -0
  130. package/src/common/vitals/cumulative-layout-shift.js +13 -0
  131. package/src/common/vitals/cumulative-layout-shift.test.js +71 -0
  132. package/src/common/vitals/first-contentful-paint.js +31 -0
  133. package/src/common/vitals/first-contentful-paint.test.js +124 -0
  134. package/src/common/vitals/first-input-delay.js +20 -0
  135. package/src/common/vitals/first-input-delay.test.js +88 -0
  136. package/src/{features/page_view_timing → common/vitals}/first-paint.js +11 -17
  137. package/src/common/vitals/first-paint.test.js +127 -0
  138. package/src/common/vitals/interaction-to-next-paint.js +13 -0
  139. package/src/common/vitals/interaction-to-next-paint.test.js +74 -0
  140. package/src/common/vitals/largest-contentful-paint.js +29 -0
  141. package/src/common/vitals/largest-contentful-paint.test.js +94 -0
  142. package/src/common/vitals/long-task.js +52 -0
  143. package/src/common/vitals/long-task.test.js +122 -0
  144. package/src/common/vitals/time-to-first-byte.js +21 -0
  145. package/src/common/vitals/time-to-first-byte.test.js +147 -0
  146. package/src/common/vitals/vital-metric.js +60 -0
  147. package/src/common/vitals/vital-metric.test.js +171 -0
  148. package/src/features/ajax/aggregate/index.js +5 -1
  149. package/src/features/metrics/aggregate/index.js +11 -4
  150. package/src/features/page_view_event/aggregate/index.js +20 -43
  151. package/src/features/page_view_event/constants.js +0 -3
  152. package/src/features/page_view_event/instrument/index.js +0 -21
  153. package/src/features/page_view_timing/aggregate/index.component-test.js +86 -0
  154. package/src/features/page_view_timing/aggregate/index.js +31 -108
  155. package/src/features/page_view_timing/instrument/index.js +0 -3
  156. package/src/features/session_replay/aggregate/index.component-test.js +10 -10
  157. package/src/features/session_replay/aggregate/index.js +62 -29
  158. package/src/features/session_trace/aggregate/index.js +15 -1
  159. package/src/features/spa/aggregate/index.js +4 -3
  160. package/src/loaders/agent.js +2 -0
  161. package/src/loaders/api/api.js +2 -0
  162. package/src/loaders/api/apiAsync.js +5 -4
  163. package/src/loaders/browser-agent.js +3 -1
  164. package/src/loaders/configure/configure.js +15 -7
  165. package/src/loaders/configure/public-path.js +6 -0
  166. package/src/loaders/configure/public-path.npm.js +4 -0
  167. package/dist/cjs/common/metrics/paint-metrics.js +0 -13
  168. package/dist/cjs/features/page_view_timing/long-tasks.js +0 -75
  169. package/dist/esm/common/metrics/paint-metrics.js +0 -6
  170. package/dist/esm/features/page_view_timing/long-tasks.js +0 -69
  171. package/dist/types/common/metrics/paint-metrics.d.ts +0 -2
  172. package/dist/types/common/metrics/paint-metrics.d.ts.map +0 -1
  173. package/dist/types/features/page_view_timing/first-paint.d.ts +0 -2
  174. package/dist/types/features/page_view_timing/first-paint.d.ts.map +0 -1
  175. package/dist/types/features/page_view_timing/long-tasks.d.ts +0 -2
  176. package/dist/types/features/page_view_timing/long-tasks.d.ts.map +0 -1
  177. package/src/common/metrics/paint-metrics.js +0 -6
  178. package/src/features/page_view_timing/long-tasks.js +0 -60
@@ -33,13 +33,16 @@ class Aggregate extends _aggregateBase.AggregateBase {
33
33
  this.singleChecks(); // checks that are run only one time, at script load
34
34
  this.eachSessionChecks(); // the start of every time user engages with page
35
35
 
36
- // *cli, Mar 23 - Per NR-94597, this feature should only harvest ONCE at the (potential) EoL time of the page.
37
- scheduler = new _harvestScheduler.HarvestScheduler('jserrors', {
38
- onUnload: () => this.unload()
39
- }, this);
40
- scheduler.harvest.on('jserrors', () => ({
41
- body: this.aggregator.take(['cm', 'sm'])
42
- }));
36
+ this.ee.on("drain-".concat(this.featureName), () => {
37
+ // *cli, Mar 23 - Per NR-94597, this feature should only harvest ONCE at the (potential) EoL time of the page.
38
+ scheduler = new _harvestScheduler.HarvestScheduler('jserrors', {
39
+ onUnload: () => this.unload()
40
+ }, this);
41
+ scheduler.harvest.on('jserrors', () => ({
42
+ body: this.aggregator.take(['cm', 'sm'])
43
+ }));
44
+ }); // this is needed to ensure EoL is "on" and sent
45
+
43
46
  this.drain();
44
47
  }
45
48
  storeSupportabilityMetrics(name, value) {
@@ -93,6 +96,13 @@ class Aggregate extends _aggregateBase.AggregateBase {
93
96
  const rules = (0, _obfuscate.getRules)(this.agentIdentifier);
94
97
  if (rules.length > 0) this.storeSupportabilityMetrics('Generic/Obfuscate/Detected');
95
98
  if (rules.length > 0 && !(0, _obfuscate.validateRules)(rules)) this.storeSupportabilityMetrics('Generic/Obfuscate/Invalid');
99
+
100
+ // Check if proxy for either chunks or beacon is being used
101
+ const {
102
+ proxy
103
+ } = (0, _config.getConfiguration)(this.agentIdentifier);
104
+ if (proxy.assets) this.storeSupportabilityMetrics('Config/AssetsUrl/Changed');
105
+ if (proxy.beacon) this.storeSupportabilityMetrics('Config/BeaconUrl/Changed');
96
106
  }
97
107
  eachSessionChecks() {
98
108
  if (!_runtime.isBrowserScope) return;
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Aggregate = void 0;
7
- var _handle = require("../../../common/event-emitter/handle");
8
- var _features = require("../../../loaders/features/features");
9
7
  var _runtime = require("../../../common/constants/runtime");
10
- var _webVitals = require("web-vitals");
11
8
  var _navTiming = require("../../../common/timing/nav-timing");
12
9
  var _stringify = require("../../../common/util/stringify");
13
- var _paintMetrics = require("../../../common/metrics/paint-metrics");
14
10
  var _config = require("../../../common/config/config");
15
11
  var _harvest = require("../../../common/harvest/harvest");
16
12
  var CONSTANTS = _interopRequireWildcard(require("../constants"));
@@ -18,44 +14,37 @@ var _initializedFeatures = require("./initialized-features");
18
14
  var _featureFlags = require("../../../common/util/feature-flags");
19
15
  var _console = require("../../../common/util/console");
20
16
  var _aggregateBase = require("../../utils/aggregate-base");
17
+ var _firstContentfulPaint = require("../../../common/vitals/first-contentful-paint");
18
+ var _firstPaint = require("../../../common/vitals/first-paint");
19
+ var _timeToFirstByte = require("../../../common/vitals/time-to-first-byte");
21
20
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
22
21
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
23
22
  class Aggregate extends _aggregateBase.AggregateBase {
24
23
  static featureName = CONSTANTS.FEATURE_NAME;
25
24
  constructor(agentIdentifier, aggregator) {
26
25
  super(agentIdentifier, aggregator, CONSTANTS.FEATURE_NAME);
27
- if (typeof PerformanceNavigationTiming !== 'undefined' && !_runtime.isiOS) {
28
- this.alreadySent = false; // we don't support timings on BFCache restores
29
- const agentRuntime = (0, _config.getRuntime)(agentIdentifier); // we'll store timing values on the runtime obj to be read by the aggregate module
26
+ this.timeToFirstByte = 0;
27
+ this.firstByteToWindowLoad = 0; // our "frontend" duration
28
+ this.firstByteToDomContent = 0; // our "dom processing" duration
30
29
 
31
- /* Time To First Byte
32
- This listener must record these values *before* PVE's aggregate sends RUM. */
33
- (0, _webVitals.onTTFB)(_ref => {
30
+ if (_runtime.isBrowserScope) {
31
+ _timeToFirstByte.timeToFirstByte.subscribe(_ref => {
34
32
  let {
35
33
  value,
36
34
  entries
37
35
  } = _ref;
38
- if (this.alreadySent) return;
39
- this.alreadySent = true;
40
- agentRuntime[CONSTANTS.TTFB] = Math.round(value); // this is our "backend" duration; web-vitals will ensure it's lower bounded at 0
41
-
42
- // Similar to what vitals does for ttfb, we have to factor in activation-start when calculating relative timings:
43
36
  const navEntry = entries[0];
44
- const respOrActivStart = Math.max(navEntry.responseStart, navEntry.activationStart || 0);
45
- agentRuntime[CONSTANTS.FBTWL] = Math.max(Math.round(navEntry.loadEventEnd - respOrActivStart), 0); // our "frontend" duration
46
- (0, _handle.handle)('timing', ['load', Math.round(navEntry.loadEventEnd)], undefined, _features.FEATURE_NAMES.pageViewTiming, this.ee);
47
- agentRuntime[CONSTANTS.FBTDC] = Math.max(Math.round(navEntry.domContentLoadedEventEnd - respOrActivStart), 0); // our "dom processing" duration
37
+ this.timeToFirstByte = Math.max(value, this.timeToFirstByte);
38
+ this.firstByteToWindowLoad = Math.max(Math.round(navEntry.loadEventEnd - this.timeToFirstByte), this.firstByteToWindowLoad); // our "frontend" duration
39
+ this.firstByteToDomContent = Math.max(Math.round(navEntry.domContentLoadedEventEnd - this.timeToFirstByte), this.firstByteToDomContent); // our "dom processing" duration
48
40
 
49
41
  this.sendRum();
50
42
  });
51
43
  } else {
52
- this.sendRum(); // timings either already in runtime from instrument or is meant to get 0'd.
44
+ // worker agent build does not get TTFB values, use default 0 values
45
+ this.sendRum();
53
46
  }
54
47
  }
55
-
56
- getScheme() {
57
- return (0, _config.getConfigurationValue)(this.agentIdentifier, 'ssl') === false ? 'http' : 'https';
58
- }
59
48
  sendRum() {
60
49
  const info = (0, _config.getInfo)(this.agentIdentifier);
61
50
  const agentRuntime = (0, _config.getRuntime)(this.agentIdentifier);
@@ -72,13 +61,13 @@ class Aggregate extends _aggregateBase.AggregateBase {
72
61
  // Following PR #428, which demands that all agents send RUM call, these need to be sent even outside of the main window context where PerformanceTiming
73
62
  // or PerformanceNavigationTiming do not exists. Hence, they'll be filled in by 0s instead in, for example, worker threads that still init the PVE module.
74
63
  this.aggregator.store('measures', 'be', {
75
- value: _runtime.isBrowserScope ? agentRuntime[CONSTANTS.TTFB] : 0
64
+ value: this.timeToFirstByte
76
65
  });
77
66
  this.aggregator.store('measures', 'fe', {
78
- value: _runtime.isBrowserScope ? agentRuntime[CONSTANTS.FBTWL] : 0
67
+ value: this.firstByteToWindowLoad
79
68
  });
80
69
  this.aggregator.store('measures', 'dc', {
81
- value: _runtime.isBrowserScope ? agentRuntime[CONSTANTS.FBTDC] : 0
70
+ value: this.firstByteToDomContent
82
71
  });
83
72
  const queryParameters = {
84
73
  tt: info.ttGuid,
@@ -119,19 +108,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
119
108
  queryParameters.perf = (0, _stringify.stringify)(perf);
120
109
  }
121
110
  }
122
- try {
123
- // PVTiming sends these too, albeit using web-vitals and slightly different; it's unknown why they're duplicated, but PVT should be the truth
124
- var entries = _runtime.globalScope.performance.getEntriesByType('paint');
125
- entries.forEach(function (entry) {
126
- if (!entry.startTime || entry.startTime <= 0) return;
127
- if (entry.name === 'first-paint') {
128
- queryParameters.fp = String(Math.floor(entry.startTime));
129
- } else if (entry.name === 'first-contentful-paint') {
130
- queryParameters.fcp = String(Math.floor(entry.startTime));
131
- }
132
- _paintMetrics.paintMetrics[entry.name] = Math.floor(entry.startTime); // this is consumed by Spa module
133
- });
134
- } catch (e) {}
111
+ queryParameters.fp = _firstPaint.firstPaint.current.value;
112
+ queryParameters.fcp = _firstContentfulPaint.firstContentfulPaint.current.value;
135
113
  harvester.send({
136
114
  endpoint: 'rum',
137
115
  payload: {
@@ -3,13 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.TTFB = exports.FEATURE_NAME = exports.FBTWL = exports.FBTDC = void 0;
6
+ exports.FEATURE_NAME = void 0;
7
7
  var _features = require("../../loaders/features/features");
8
8
  const FEATURE_NAME = _features.FEATURE_NAMES.pageViewEvent;
9
- exports.FEATURE_NAME = FEATURE_NAME;
10
- const TTFB = 'firstbyte';
11
- exports.TTFB = TTFB;
12
- const FBTDC = 'domcontent';
13
- exports.FBTDC = FBTDC;
14
- const FBTWL = 'windowload';
15
- exports.FBTWL = FBTWL;
9
+ exports.FEATURE_NAME = FEATURE_NAME;
@@ -4,14 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Instrument = void 0;
7
- var _handle = require("../../../common/event-emitter/handle");
8
- var _runtime = require("../../../common/constants/runtime");
9
7
  var _instrumentBase = require("../../utils/instrument-base");
10
8
  var CONSTANTS = _interopRequireWildcard(require("../constants"));
11
- var _features = require("../../../loaders/features/features");
12
- var _config = require("../../../common/config/config");
13
- var _load = require("../../../common/window/load");
14
- var _now = require("../../../common/timing/now");
15
9
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
16
10
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
11
  class Instrument extends _instrumentBase.InstrumentBase {
@@ -19,22 +13,6 @@ class Instrument extends _instrumentBase.InstrumentBase {
19
13
  constructor(agentIdentifier, aggregator) {
20
14
  let auto = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
21
15
  super(agentIdentifier, aggregator, CONSTANTS.FEATURE_NAME, auto);
22
- if ((typeof PerformanceNavigationTiming === 'undefined' || _runtime.isiOS) && typeof PerformanceTiming !== 'undefined') {
23
- // For majority browser versions in which PNT exists, we can get load timings later from the nav entry (in the aggregate portion). At minimum, PT should exist for main window.
24
- // *cli Mar'23 - iOS 15.2 & 15.4 testing in Sauce still fails with onTTFB. Hence, all iOS will fallback to this for now. Unknown if this is similar in nature to iOSBelow16 bug.
25
- const agentRuntime = (0, _config.getRuntime)(agentIdentifier);
26
- agentRuntime[CONSTANTS.TTFB] = Math.max(Date.now() - agentRuntime.offset, 0);
27
- (0, _load.onDOMContentLoaded)(() => {
28
- agentRuntime[CONSTANTS.FBTDC] = Math.max((0, _now.now)() - agentRuntime[CONSTANTS.TTFB], 0);
29
- });
30
- (0, _load.onWindowLoad)(() => {
31
- const timeNow = (0, _now.now)();
32
- agentRuntime[CONSTANTS.FBTWL] = Math.max(timeNow - agentRuntime[CONSTANTS.TTFB], 0);
33
- (0, _handle.handle)('timing', ['load', timeNow], undefined, _features.FEATURE_NAMES.pageViewTiming, this.ee);
34
- });
35
- }
36
- // Else, inference: inside worker or some other env where these events are irrelevant. They'll get filled in with 0s in RUM call.
37
-
38
16
  this.importAggregator();
39
17
  }
40
18
  }
@@ -4,20 +4,23 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Aggregate = void 0;
7
- var _webVitals = require("web-vitals");
8
- var _firstPaint = require("../first-paint");
9
- var _longTasks = require("../long-tasks");
10
- var _runtime = require("../../../common/constants/runtime");
11
7
  var _belSerializer = require("../../../common/serialize/bel-serializer");
12
8
  var _mapOwn = require("../../../common/util/map-own");
13
9
  var _harvestScheduler = require("../../../common/harvest/harvest-scheduler");
14
10
  var _registerHandler = require("../../../common/event-emitter/register-handler");
15
- var _cleanUrl = require("../../../common/url/clean-url");
16
11
  var _handle = require("../../../common/event-emitter/handle");
17
12
  var _config = require("../../../common/config/config");
18
13
  var _constants = require("../constants");
19
14
  var _features = require("../../../loaders/features/features");
20
15
  var _aggregateBase = require("../../utils/aggregate-base");
16
+ var _cumulativeLayoutShift = require("../../../common/vitals/cumulative-layout-shift");
17
+ var _firstContentfulPaint = require("../../../common/vitals/first-contentful-paint");
18
+ var _firstInputDelay = require("../../../common/vitals/first-input-delay");
19
+ var _firstPaint = require("../../../common/vitals/first-paint");
20
+ var _interactionToNextPaint = require("../../../common/vitals/interaction-to-next-paint");
21
+ var _largestContentfulPaint = require("../../../common/vitals/largest-contentful-paint");
22
+ var _timeToFirstByte = require("../../../common/vitals/time-to-first-byte");
23
+ var _longTask = require("../../../common/vitals/long-task");
21
24
  /*
22
25
  * Copyright 2020 New Relic Corporation. All rights reserved.
23
26
  * SPDX-License-Identifier: Apache-2.0
@@ -25,6 +28,14 @@ var _aggregateBase = require("../../utils/aggregate-base");
25
28
 
26
29
  class Aggregate extends _aggregateBase.AggregateBase {
27
30
  static featureName = _constants.FEATURE_NAME;
31
+ #handleVitalMetric = _ref => {
32
+ let {
33
+ name,
34
+ value,
35
+ attrs
36
+ } = _ref;
37
+ this.addTiming(name, value, attrs);
38
+ };
28
39
  constructor(agentIdentifier, aggregator) {
29
40
  var _this;
30
41
  super(agentIdentifier, aggregator, _constants.FEATURE_NAME);
@@ -32,163 +43,41 @@ class Aggregate extends _aggregateBase.AggregateBase {
32
43
  this.timings = [];
33
44
  this.timingsSent = [];
34
45
  this.curSessEndRecorded = false;
35
- this.cls = null; // this should be null unless set to a numeric value by web-vitals so that we differentiate if CLS is supported
36
-
37
- /* ! This is the section that used to be in the loader portion: ! */
38
- /* ------------------------------------------------------------ */
39
- const pageStartedHidden = (0, _config.getRuntime)(agentIdentifier).initHidden; // our attempt at recapturing initial vis state since this code runs post-load time
40
- this.alreadySent = new Set(); // since we don't support timings on BFCache restores, this tracks and helps cap metrics that web-vitals report more than once
41
-
42
- /* PerformancePaintTiming API - BFC is not yet supported. */
43
- (0, _firstPaint.onFirstPaint)(_ref => {
44
- let {
45
- name,
46
- value
47
- } = _ref;
48
- if (pageStartedHidden) return;
49
- this.addTiming(name.toLowerCase(), Math.floor(value));
50
- });
51
-
52
- /* First Contentful Paint - As of WV v3, it still imperfectly tries to detect document vis state asap and isn't supposed to report if page starts hidden. */
53
- if (_runtime.iOSBelow16) {
54
- try {
55
- if (!pageStartedHidden) {
56
- // see ios-version.js for detail on this following bug case; tldr: buffered flag doesn't work but getEntriesByType does
57
- const paintEntries = performance.getEntriesByType('paint');
58
- paintEntries.forEach(entry => {
59
- if (entry.name === 'first-contentful-paint') {
60
- this.addTiming('fcp', Math.floor(entry.startTime));
61
- }
62
- });
63
- }
64
- } catch (e) {}
65
- } else {
66
- (0, _webVitals.onFCP)(_ref2 => {
67
- let {
68
- name,
69
- value
70
- } = _ref2;
71
- if (pageStartedHidden || this.alreadySent.has(name)) return;
72
- this.alreadySent.add(name);
73
- this.addTiming(name.toLowerCase(), value);
74
- });
75
- }
76
-
77
- /* First Input Delay (+"First Interaction") - As of WV v3, it still imperfectly tries to detect document vis state asap and isn't supposed to report if page starts hidden. */
78
- (0, _webVitals.onFID)(_ref3 => {
79
- let {
80
- name,
81
- value,
82
- entries
83
- } = _ref3;
84
- if (pageStartedHidden || this.alreadySent.has(name) || entries.length === 0) return;
85
- this.alreadySent.add(name);
86
-
87
- // CWV will only report one (THE) first-input entry to us; fid isn't reported if there are no user interactions occurs before the *first* page hiding.
88
- const fiEntry = entries[0];
89
- const attributes = {
90
- type: fiEntry.name,
91
- fid: Math.round(value)
92
- };
93
- this.addConnectionAttributes(attributes);
94
- this.addTiming('fi', Math.round(fiEntry.startTime), attributes);
95
- });
96
-
97
- /* Largest Contentful Paint - As of WV v3, it still imperfectly tries to detect document vis state asap and isn't supposed to report if page starts hidden. */
98
- (0, _webVitals.onLCP)(_ref4 => {
46
+ _firstPaint.firstPaint.subscribe(this.#handleVitalMetric);
47
+ _firstContentfulPaint.firstContentfulPaint.subscribe(this.#handleVitalMetric);
48
+ _firstInputDelay.firstInputDelay.subscribe(this.#handleVitalMetric);
49
+ _largestContentfulPaint.largestContentfulPaint.subscribe(this.#handleVitalMetric);
50
+ _interactionToNextPaint.interactionToNextPaint.subscribe(this.#handleVitalMetric);
51
+ _timeToFirstByte.timeToFirstByte.subscribe(_ref2 => {
99
52
  let {
100
- name,
101
- value,
102
53
  entries
103
- } = _ref4;
104
- if (pageStartedHidden || this.alreadySent.has(name)) return;
105
- this.alreadySent.add(name);
106
- const attributes = {};
107
- if (entries.length > 0) {
108
- // CWV will only ever report one (THE) lcp entry to us; lcp is also only reported *once* on earlier(user interaction, page hidden).
109
- const lcpEntry = entries[entries.length - 1]; // this looks weird if we only expect one, but this is how cwv-attribution gets it so to be sure...
110
- attributes.size = lcpEntry.size;
111
- attributes.eid = lcpEntry.id;
112
- if (lcpEntry.url) {
113
- attributes.elUrl = (0, _cleanUrl.cleanURL)(lcpEntry.url);
114
- }
115
- if (lcpEntry.element?.tagName) {
116
- attributes.elTag = lcpEntry.element.tagName;
117
- }
118
- }
119
- this.addConnectionAttributes(attributes);
120
- this.addTiming(name.toLowerCase(), value, attributes);
121
- });
122
-
123
- /* Cumulative Layout Shift - We don't have to limit this callback since cls is stored as a state and only sent as attribute on other timings.
124
- reportAllChanges ensures our tracked cls has the most recent rolling value to attach to 'unload' and 'pagehide'. */
125
- (0, _webVitals.onCLS)(_ref5 => {
126
- let {
127
- value
128
- } = _ref5;
129
- this.cls = value;
130
- }, {
131
- reportAllChanges: true
132
- });
133
-
134
- /* Interaction-to-Next-Paint */
135
- (0, _webVitals.onINP)(_ref6 => {
136
- let {
137
- name,
138
- value,
139
- id
140
- } = _ref6;
141
- return this.addTiming(name.toLowerCase(), value, {
142
- metricId: id
143
- });
54
+ } = _ref2;
55
+ this.addTiming('load', Math.round(entries[0].loadEventEnd));
144
56
  });
145
-
146
- /* PerformanceLongTaskTiming API */
147
- if ((0, _config.getConfigurationValue)(this.agentIdentifier, 'page_view_timing.long_task') === true) {
148
- (0, _longTasks.onLongTask)(_ref7 => {
149
- let {
150
- name,
151
- value,
152
- info
153
- } = _ref7;
154
- return this.addTiming(name.toLowerCase(), value, info);
155
- }); // lt context is passed as 'info'=attrs in the timing node
156
- }
157
- /* ------------------------------------End of ex-loader section */
57
+ if ((0, _config.getConfigurationValue)(this.agentIdentifier, 'page_view_timing.long_task') === true) _longTask.longTask.subscribe(this.#handleVitalMetric);
158
58
 
159
59
  /* It's important that CWV api, like "onLCP", is called before this scheduler is initialized. The reason is because they listen to the same
160
60
  on vis change or pagehide events, and we'd want ex. onLCP to record the timing (win the race) before we try to send "final harvest". */
161
- this.scheduler = new _harvestScheduler.HarvestScheduler('events', {
162
- onFinished: function () {
163
- return _this.onHarvestFinished(...arguments);
164
- },
165
- getPayload: function () {
166
- return _this.prepareHarvest(...arguments);
167
- }
168
- }, this);
169
- (0, _registerHandler.registerHandler)('timing', (name, value, attrs) => this.addTiming(name, value, attrs), this.featureName, this.ee); // notice CLS is added to all timings via 4th param
61
+
170
62
  (0, _registerHandler.registerHandler)('docHidden', msTimestamp => this.endCurrentSession(msTimestamp), this.featureName, this.ee);
171
63
  (0, _registerHandler.registerHandler)('winPagehide', msTimestamp => this.recordPageUnload(msTimestamp), this.featureName, this.ee);
172
64
  const initialHarvestSeconds = (0, _config.getConfigurationValue)(this.agentIdentifier, 'page_view_timing.initialHarvestSeconds') || 10;
173
65
  const harvestTimeSeconds = (0, _config.getConfigurationValue)(this.agentIdentifier, 'page_view_timing.harvestTimeSeconds') || 30;
174
66
  // send initial data sooner, then start regular
175
67
  this.ee.on("drain-".concat(this.featureName), () => {
68
+ this.scheduler = new _harvestScheduler.HarvestScheduler('events', {
69
+ onFinished: function () {
70
+ return _this.onHarvestFinished(...arguments);
71
+ },
72
+ getPayload: function () {
73
+ return _this.prepareHarvest(...arguments);
74
+ }
75
+ }, this);
176
76
  this.scheduler.startTimer(harvestTimeSeconds, initialHarvestSeconds);
177
77
  });
178
78
  this.drain();
179
79
  }
180
80
 
181
- // takes an attributes object and appends connection attributes if available
182
- addConnectionAttributes(attributes) {
183
- var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection; // to date, both window & worker shares the same support for connection
184
- if (!connection) return;
185
- if (connection.type) attributes['net-type'] = connection.type;
186
- if (connection.effectiveType) attributes['net-etype'] = connection.effectiveType;
187
- if (connection.rtt) attributes['net-rtt'] = connection.rtt;
188
- if (connection.downlink) attributes['net-dlink'] = connection.downlink;
189
- return attributes;
190
- }
191
-
192
81
  /**
193
82
  * Add the time of _document visibilitychange to hidden_ to the next PVT harvest == NRDB pageHide attr.
194
83
  * @param {number} timestamp
@@ -225,8 +114,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
225
114
  Mitigation: We've set initial CLS to null so that it's omitted from timings like 'pageHide' in that edge case. It should only be included if onCLS callback was executed at least once.
226
115
  Future: onCLS value changes should be reported directly & CLS separated into its own timing node so it's not beholden to 'pageHide' firing. It'd also be possible to report the real final CLS.
227
116
  */
228
- if (this.cls !== null) {
229
- attrs.cls = this.cls;
117
+ if (_cumulativeLayoutShift.cumulativeLayoutShift.current.value >= 0) {
118
+ attrs.cls = _cumulativeLayoutShift.cumulativeLayoutShift.current.value;
230
119
  }
231
120
  this.timings.push({
232
121
  name,
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.Instrument = void 0;
7
7
  var _handle = require("../../../common/event-emitter/handle");
8
- var _config = require("../../../common/config/config");
9
8
  var _pageVisibility = require("../../../common/window/page-visibility");
10
9
  var _eventListenerOpts = require("../../../common/event-listener/event-listener-opts");
11
10
  var _now = require("../../../common/timing/now");
@@ -24,9 +23,7 @@ class Instrument extends _instrumentBase.InstrumentBase {
24
23
  super(agentIdentifier, aggregator, _constants.FEATURE_NAME, auto);
25
24
  if (!_runtime.isBrowserScope) return; // CWV is irrelevant outside web context
26
25
 
27
- // Document visibility state becomes hidden; this should run as soon as possible in page life.
28
26
  // While we try to replicate web-vital's visibilitywatcher logic in an effort to defer that library to post-pageload, this isn't perfect and doesn't consider prerendering.
29
- (0, _config.getRuntime)(agentIdentifier).initHidden = Boolean(document.visibilityState === 'hidden');
30
27
  (0, _pageVisibility.subscribeToVisibilityChange)(() => (0, _handle.handle)('docHidden', [(0, _now.now)()], undefined, _constants.FEATURE_NAME, this.ee), true);
31
28
 
32
29
  // Window fires its pagehide event (typically on navigation--this occurrence is a *subset* of vis change); don't defer this unless it's guarantee it cannot happen before load(?)