@newrelic/browser-agent 1.291.1 → 1.292.0-rc.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 (37) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/common/constants/env.cdn.js +1 -1
  3. package/dist/cjs/common/constants/env.npm.js +1 -1
  4. package/dist/cjs/common/drain/drain.js +7 -0
  5. package/dist/cjs/common/window/load.js +5 -0
  6. package/dist/cjs/features/page_view_event/instrument/index.js +36 -0
  7. package/dist/cjs/features/soft_navigations/aggregate/initial-page-load-interaction.js +1 -0
  8. package/dist/cjs/features/spa/aggregate/interaction.js +2 -1
  9. package/dist/cjs/loaders/api/finished.js +7 -5
  10. package/dist/cjs/loaders/api-base.js +1 -1
  11. package/dist/esm/common/constants/env.cdn.js +1 -1
  12. package/dist/esm/common/constants/env.npm.js +1 -1
  13. package/dist/esm/common/drain/drain.js +7 -0
  14. package/dist/esm/common/window/load.js +4 -0
  15. package/dist/esm/features/page_view_event/instrument/index.js +36 -0
  16. package/dist/esm/features/soft_navigations/aggregate/initial-page-load-interaction.js +1 -0
  17. package/dist/esm/features/spa/aggregate/interaction.js +2 -1
  18. package/dist/esm/loaders/api/finished.js +7 -5
  19. package/dist/esm/loaders/api-base.js +1 -1
  20. package/dist/types/common/drain/drain.d.ts.map +1 -1
  21. package/dist/types/common/window/load.d.ts +1 -0
  22. package/dist/types/common/window/load.d.ts.map +1 -1
  23. package/dist/types/features/page_view_event/instrument/index.d.ts +1 -0
  24. package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
  25. package/dist/types/features/soft_navigations/aggregate/initial-page-load-interaction.d.ts +1 -0
  26. package/dist/types/features/soft_navigations/aggregate/initial-page-load-interaction.d.ts.map +1 -1
  27. package/dist/types/features/spa/aggregate/interaction.d.ts.map +1 -1
  28. package/dist/types/loaders/api/finished.d.ts.map +1 -1
  29. package/dist/types/loaders/api-base.d.ts +1 -1
  30. package/package.json +2 -2
  31. package/src/common/drain/drain.js +8 -0
  32. package/src/common/window/load.js +5 -0
  33. package/src/features/page_view_event/instrument/index.js +41 -0
  34. package/src/features/soft_navigations/aggregate/initial-page-load-interaction.js +1 -0
  35. package/src/features/spa/aggregate/interaction.js +2 -1
  36. package/src/loaders/api/finished.js +7 -5
  37. package/src/loaders/api-base.js +1 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,19 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.292.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.291.1...v1.292.0) (2025-06-16)
7
+
8
+
9
+ ### Features
10
+
11
+ * Add more inspection events ([#1494](https://github.com/newrelic/newrelic-browser-agent/issues/1494)) ([def89c4](https://github.com/newrelic/newrelic-browser-agent/commit/def89c4ab5850a3d8f8dc03b424a473bd5eb4bb5))
12
+ * Update BrowserInteraction previousUrl definition ([#1499](https://github.com/newrelic/newrelic-browser-agent/issues/1499)) ([93f0fd0](https://github.com/newrelic/newrelic-browser-agent/commit/93f0fd0076e1e1fcc2b353d766a7a95c0f524e76))
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * Fix .finished API timeSinceLoad value ([#1503](https://github.com/newrelic/newrelic-browser-agent/issues/1503)) ([363a898](https://github.com/newrelic/newrelic-browser-agent/commit/363a898fce43c9c53a881f1d3b4a16ca7ced70f8))
18
+
6
19
  ## [1.291.1](https://github.com/newrelic/newrelic-browser-agent/compare/v1.291.0...v1.291.1) (2025-06-06)
7
20
 
8
21
 
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.DIST_METHOD = exports.BUILD_EN
17
17
  /**
18
18
  * Exposes the version of the agent
19
19
  */
20
- const VERSION = exports.VERSION = "1.291.1";
20
+ const VERSION = exports.VERSION = "1.292.0-rc.0";
21
21
 
22
22
  /**
23
23
  * Exposes the build type of the agent
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.DIST_METHOD = exports.BUILD_EN
17
17
  /**
18
18
  * Exposes the version of the agent
19
19
  */
20
- const VERSION = exports.VERSION = "1.291.1";
20
+ const VERSION = exports.VERSION = "1.292.0-rc.0";
21
21
 
22
22
  /**
23
23
  * Exposes the build type of the agent
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.deregisterDrain = deregisterDrain;
7
7
  exports.drain = drain;
8
8
  exports.registerDrain = registerDrain;
9
+ var _globalEvent = require("../../common/dispatch/global-event");
9
10
  var _contextualEe = require("../event-emitter/contextual-ee");
10
11
  var _registerHandler = require("../event-emitter/register-handler");
11
12
  var _features = require("../../loaders/features/features");
@@ -100,6 +101,12 @@ function drainGroup(agentIdentifier, group, activateGroup = true) {
100
101
  const baseEE = agentIdentifier ? _contextualEe.ee.get(agentIdentifier) : _contextualEe.ee;
101
102
  const handlers = _registerHandler.registerHandler.handlers; // other storage in registerHandler
102
103
  if (baseEE.aborted || !baseEE.backlog || !handlers) return;
104
+ (0, _globalEvent.dispatchGlobalEvent)({
105
+ agentIdentifier,
106
+ type: 'lifecycle',
107
+ name: 'drain',
108
+ feature: group
109
+ });
103
110
 
104
111
  // Only activated features being drained should run queued listeners on buffered events. Deactivated features only need to release memory.
105
112
  if (activateGroup) {
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.checkState = checkState;
7
7
  exports.onDOMContentLoaded = onDOMContentLoaded;
8
+ exports.onPopstateChange = onPopstateChange;
8
9
  exports.onWindowLoad = onWindowLoad;
9
10
  var _eventListenerOpts = require("../event-listener/event-listener-opts");
10
11
  /**
@@ -22,4 +23,8 @@ function onWindowLoad(cb, useCapture) {
22
23
  function onDOMContentLoaded(cb) {
23
24
  if (checkState()) return cb();
24
25
  (0, _eventListenerOpts.documentAddEventListener)('DOMContentLoaded', cb);
26
+ }
27
+ function onPopstateChange(cb) {
28
+ if (checkState()) return cb();
29
+ (0, _eventListenerOpts.windowAddEventListener)('popstate', cb);
25
30
  }
@@ -8,6 +8,9 @@ var _handle = require("../../../common/event-emitter/handle");
8
8
  var _setPageViewName = require("../../../loaders/api/setPageViewName");
9
9
  var _instrumentBase = require("../../utils/instrument-base");
10
10
  var CONSTANTS = _interopRequireWildcard(require("../constants"));
11
+ var _constants2 = require("../../../common/session/constants");
12
+ var _globalEvent = require("../../../common/dispatch/global-event");
13
+ var _load = require("../../../common/window/load");
11
14
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
15
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /**
13
16
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
@@ -18,6 +21,9 @@ class Instrument extends _instrumentBase.InstrumentBase {
18
21
  constructor(agentRef) {
19
22
  super(agentRef, CONSTANTS.FEATURE_NAME);
20
23
 
24
+ /** setup inspection events for window lifecycle */
25
+ this.setupInspectionEvents(agentRef.agentIdentifier);
26
+
21
27
  /** feature specific APIs */
22
28
  (0, _setPageViewName.setupSetPageViewNameAPI)(agentRef);
23
29
 
@@ -25,6 +31,36 @@ class Instrument extends _instrumentBase.InstrumentBase {
25
31
  this.ee.on('api-send-rum', (attrs, target) => (0, _handle.handle)('send-rum', [attrs, target], undefined, this.featureName, this.ee));
26
32
  this.importAggregator(agentRef, () => Promise.resolve().then(() => _interopRequireWildcard(require(/* webpackChunkName: "page_view_event-aggregate" */'../aggregate'))));
27
33
  }
34
+ setupInspectionEvents(agentIdentifier) {
35
+ const dispatch = (evt, name) => {
36
+ if (!evt) return;
37
+ (0, _globalEvent.dispatchGlobalEvent)({
38
+ agentIdentifier,
39
+ timeStamp: evt.timeStamp,
40
+ loaded: evt.target.readyState === 'complete',
41
+ type: 'window',
42
+ name,
43
+ data: evt.target.location + ''
44
+ });
45
+ };
46
+ (0, _load.onDOMContentLoaded)(evt => {
47
+ dispatch(evt, 'DOMContentLoaded');
48
+ });
49
+ (0, _load.onWindowLoad)(evt => {
50
+ dispatch(evt, 'load');
51
+ });
52
+ (0, _load.onPopstateChange)(evt => {
53
+ dispatch(evt, 'navigate');
54
+ });
55
+ this.ee.on(_constants2.SESSION_EVENTS.UPDATE, (_, data) => {
56
+ (0, _globalEvent.dispatchGlobalEvent)({
57
+ agentIdentifier,
58
+ type: 'lifecycle',
59
+ name: 'session',
60
+ data
61
+ });
62
+ });
63
+ }
28
64
  }
29
65
  exports.Instrument = Instrument;
30
66
  const PageViewEvent = exports.PageViewEvent = Instrument;
@@ -20,6 +20,7 @@ class InitialPageLoadInteraction extends _interaction.Interaction {
20
20
  super(agentRef, _constants.IPL_TRIGGER_NAME, 0, null);
21
21
  this.queueTime = agentRef.info.queueTime;
22
22
  this.appTime = agentRef.info.applicationTime;
23
+ this.oldURL = document.referrer;
23
24
  }
24
25
  get firstPaint() {
25
26
  return _firstPaint.firstPaint.current.value;
@@ -33,7 +33,8 @@ function Interaction(eventName, timestamp, url, routeName, onFinished, agentRef)
33
33
  attrs.trigger = eventName;
34
34
  attrs.initialPageURL = _runtime.initialLocation;
35
35
  attrs.oldRoute = routeName;
36
- attrs.newURL = attrs.oldURL = url;
36
+ attrs.newURL = url;
37
+ attrs.oldURL = eventName === 'initialPageLoad' ? document.referrer : url;
37
38
  attrs.custom = {};
38
39
  attrs.store = {};
39
40
  }
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.setupFinishedAPI = setupFinishedAPI;
7
7
  var _runtime = require("../../common/constants/runtime");
8
8
  var _handle = require("../../common/event-emitter/handle");
9
- var _now = require("../../common/timing/now");
9
+ var _console = require("../../common/util/console");
10
10
  var _constants = require("../../features/metrics/constants");
11
11
  var _features = require("../features/features");
12
12
  var _constants2 = require("./constants");
@@ -17,15 +17,17 @@ var _sharedHandlers = require("./sharedHandlers");
17
17
  */
18
18
 
19
19
  function setupFinishedAPI(agent) {
20
- (0, _sharedHandlers.setupAPI)(_constants2.FINISHED, function (time = (0, _now.now)()) {
20
+ (0, _sharedHandlers.setupAPI)(_constants2.FINISHED, function (unixTime = Date.now()) {
21
+ const relativeTime = unixTime - _runtime.originTime;
22
+ if (relativeTime < 0) (0, _console.warn)(62, unixTime);
21
23
  (0, _handle.handle)(_constants.CUSTOM_METRIC_CHANNEL, [_constants2.FINISHED, {
22
- time
24
+ time: relativeTime
23
25
  }], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
24
26
  agent.addToTrace({
25
27
  name: _constants2.FINISHED,
26
- start: time + _runtime.originTime,
28
+ start: unixTime,
27
29
  origin: 'nr'
28
30
  });
29
- (0, _handle.handle)(_constants2.prefix + _constants2.ADD_PAGE_ACTION, [time, _constants2.FINISHED], undefined, _features.FEATURE_NAMES.genericEvents, agent.ee);
31
+ (0, _handle.handle)(_constants2.prefix + _constants2.ADD_PAGE_ACTION, [relativeTime, _constants2.FINISHED], undefined, _features.FEATURE_NAMES.genericEvents, agent.ee);
30
32
  }, agent);
31
33
  }
@@ -149,7 +149,7 @@ class ApiBase {
149
149
  /**
150
150
  * Records an additional time point as "finished" in a session trace and adds a page action.
151
151
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/finished/}
152
- * @param {number} [timeStamp] Defaults to the current time of the call. If used, this marks the time that the page is "finished" according to your own criteria.
152
+ * @param {number} [timeStamp] integer (UNIX time) - Defaults to the current time of the call. If used, this marks the time that the page is "finished" according to your own criteria.
153
153
  */
154
154
  finished(timeStamp) {
155
155
  return this.#callMethod(_constants.FINISHED, timeStamp);
@@ -11,7 +11,7 @@
11
11
  /**
12
12
  * Exposes the version of the agent
13
13
  */
14
- export const VERSION = "1.291.1";
14
+ export const VERSION = "1.292.0-rc.0";
15
15
 
16
16
  /**
17
17
  * Exposes the build type of the agent
@@ -11,7 +11,7 @@
11
11
  /**
12
12
  * Exposes the version of the agent
13
13
  */
14
- export const VERSION = "1.291.1";
14
+ export const VERSION = "1.292.0-rc.0";
15
15
 
16
16
  /**
17
17
  * Exposes the build type of the agent
@@ -3,6 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
+ import { dispatchGlobalEvent } from '../../common/dispatch/global-event';
6
7
  import { ee } from '../event-emitter/contextual-ee';
7
8
  import { registerHandler as defaultRegister } from '../event-emitter/register-handler';
8
9
  import { featurePriority } from '../../loaders/features/features';
@@ -92,6 +93,12 @@ function drainGroup(agentIdentifier, group, activateGroup = true) {
92
93
  const baseEE = agentIdentifier ? ee.get(agentIdentifier) : ee;
93
94
  const handlers = defaultRegister.handlers; // other storage in registerHandler
94
95
  if (baseEE.aborted || !baseEE.backlog || !handlers) return;
96
+ dispatchGlobalEvent({
97
+ agentIdentifier,
98
+ type: 'lifecycle',
99
+ name: 'drain',
100
+ feature: group
101
+ });
95
102
 
96
103
  // Only activated features being drained should run queued listeners on buffered events. Deactivated features only need to release memory.
97
104
  if (activateGroup) {
@@ -13,4 +13,8 @@ export function onWindowLoad(cb, useCapture) {
13
13
  export function onDOMContentLoaded(cb) {
14
14
  if (checkState()) return cb();
15
15
  documentAddEventListener('DOMContentLoaded', cb);
16
+ }
17
+ export function onPopstateChange(cb) {
18
+ if (checkState()) return cb();
19
+ windowAddEventListener('popstate', cb);
16
20
  }
@@ -6,11 +6,17 @@ import { handle } from '../../../common/event-emitter/handle';
6
6
  import { setupSetPageViewNameAPI } from '../../../loaders/api/setPageViewName';
7
7
  import { InstrumentBase } from '../../utils/instrument-base';
8
8
  import * as CONSTANTS from '../constants';
9
+ import { SESSION_EVENTS } from '../../../common/session/constants';
10
+ import { dispatchGlobalEvent } from '../../../common/dispatch/global-event';
11
+ import { onDOMContentLoaded, onPopstateChange, onWindowLoad } from '../../../common/window/load';
9
12
  export class Instrument extends InstrumentBase {
10
13
  static featureName = CONSTANTS.FEATURE_NAME;
11
14
  constructor(agentRef) {
12
15
  super(agentRef, CONSTANTS.FEATURE_NAME);
13
16
 
17
+ /** setup inspection events for window lifecycle */
18
+ this.setupInspectionEvents(agentRef.agentIdentifier);
19
+
14
20
  /** feature specific APIs */
15
21
  setupSetPageViewNameAPI(agentRef);
16
22
 
@@ -18,5 +24,35 @@ export class Instrument extends InstrumentBase {
18
24
  this.ee.on('api-send-rum', (attrs, target) => handle('send-rum', [attrs, target], undefined, this.featureName, this.ee));
19
25
  this.importAggregator(agentRef, () => import(/* webpackChunkName: "page_view_event-aggregate" */'../aggregate'));
20
26
  }
27
+ setupInspectionEvents(agentIdentifier) {
28
+ const dispatch = (evt, name) => {
29
+ if (!evt) return;
30
+ dispatchGlobalEvent({
31
+ agentIdentifier,
32
+ timeStamp: evt.timeStamp,
33
+ loaded: evt.target.readyState === 'complete',
34
+ type: 'window',
35
+ name,
36
+ data: evt.target.location + ''
37
+ });
38
+ };
39
+ onDOMContentLoaded(evt => {
40
+ dispatch(evt, 'DOMContentLoaded');
41
+ });
42
+ onWindowLoad(evt => {
43
+ dispatch(evt, 'load');
44
+ });
45
+ onPopstateChange(evt => {
46
+ dispatch(evt, 'navigate');
47
+ });
48
+ this.ee.on(SESSION_EVENTS.UPDATE, (_, data) => {
49
+ dispatchGlobalEvent({
50
+ agentIdentifier,
51
+ type: 'lifecycle',
52
+ name: 'session',
53
+ data
54
+ });
55
+ });
56
+ }
21
57
  }
22
58
  export const PageViewEvent = Instrument;
@@ -13,6 +13,7 @@ export class InitialPageLoadInteraction extends Interaction {
13
13
  super(agentRef, IPL_TRIGGER_NAME, 0, null);
14
14
  this.queueTime = agentRef.info.queueTime;
15
15
  this.appTime = agentRef.info.applicationTime;
16
+ this.oldURL = document.referrer;
16
17
  }
17
18
  get firstPaint() {
18
19
  return firstPaint.current.value;
@@ -26,7 +26,8 @@ export function Interaction(eventName, timestamp, url, routeName, onFinished, ag
26
26
  attrs.trigger = eventName;
27
27
  attrs.initialPageURL = initialLocation;
28
28
  attrs.oldRoute = routeName;
29
- attrs.newURL = attrs.oldURL = url;
29
+ attrs.newURL = url;
30
+ attrs.oldURL = eventName === 'initialPageLoad' ? document.referrer : url;
30
31
  attrs.custom = {};
31
32
  attrs.store = {};
32
33
  }
@@ -4,21 +4,23 @@
4
4
  */
5
5
  import { originTime } from '../../common/constants/runtime';
6
6
  import { handle } from '../../common/event-emitter/handle';
7
- import { now } from '../../common/timing/now';
7
+ import { warn } from '../../common/util/console';
8
8
  import { CUSTOM_METRIC_CHANNEL } from '../../features/metrics/constants';
9
9
  import { FEATURE_NAMES } from '../features/features';
10
10
  import { ADD_PAGE_ACTION, FINISHED, prefix } from './constants';
11
11
  import { setupAPI } from './sharedHandlers';
12
12
  export function setupFinishedAPI(agent) {
13
- setupAPI(FINISHED, function (time = now()) {
13
+ setupAPI(FINISHED, function (unixTime = Date.now()) {
14
+ const relativeTime = unixTime - originTime;
15
+ if (relativeTime < 0) warn(62, unixTime);
14
16
  handle(CUSTOM_METRIC_CHANNEL, [FINISHED, {
15
- time
17
+ time: relativeTime
16
18
  }], undefined, FEATURE_NAMES.metrics, agent.ee);
17
19
  agent.addToTrace({
18
20
  name: FINISHED,
19
- start: time + originTime,
21
+ start: unixTime,
20
22
  origin: 'nr'
21
23
  });
22
- handle(prefix + ADD_PAGE_ACTION, [time, FINISHED], undefined, FEATURE_NAMES.genericEvents, agent.ee);
24
+ handle(prefix + ADD_PAGE_ACTION, [relativeTime, FINISHED], undefined, FEATURE_NAMES.genericEvents, agent.ee);
23
25
  }, agent);
24
26
  }
@@ -143,7 +143,7 @@ export class ApiBase {
143
143
  /**
144
144
  * Records an additional time point as "finished" in a session trace and adds a page action.
145
145
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/finished/}
146
- * @param {number} [timeStamp] Defaults to the current time of the call. If used, this marks the time that the page is "finished" according to your own criteria.
146
+ * @param {number} [timeStamp] integer (UNIX time) - Defaults to the current time of the call. If used, this marks the time that the page is "finished" according to your own criteria.
147
147
  */
148
148
  finished(timeStamp) {
149
149
  return this.#callMethod(FINISHED, timeStamp);
@@ -1 +1 @@
1
- {"version":3,"file":"drain.d.ts","sourceRoot":"","sources":["../../../../src/common/drain/drain.js"],"names":[],"mappings":"AAYA;;;;;;;GAOG;AACH,+CAHW,MAAM,SACN,MAAM,QAQhB;AAED;;;;GAIG;AACH,iDAHW,GAAC,SACD,GAAC,QAOX;AAYD;;;;;;GAMG;AACH,wCAJW,MAAM,gBACN,MAAM,UACN,OAAO,QAajB"}
1
+ {"version":3,"file":"drain.d.ts","sourceRoot":"","sources":["../../../../src/common/drain/drain.js"],"names":[],"mappings":"AAaA;;;;;;;GAOG;AACH,+CAHW,MAAM,SACN,MAAM,QAQhB;AAED;;;;GAIG;AACH,iDAHW,GAAC,SACD,GAAC,QAOX;AAYD;;;;;;GAMG;AACH,wCAJW,MAAM,gBACN,MAAM,UACN,OAAO,QAajB"}
@@ -1,4 +1,5 @@
1
1
  export function checkState(): boolean;
2
2
  export function onWindowLoad(cb: any, useCapture: any): any;
3
3
  export function onDOMContentLoaded(cb: any): any;
4
+ export function onPopstateChange(cb: any): any;
4
5
  //# sourceMappingURL=load.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../../src/common/window/load.js"],"names":[],"mappings":"AAMA,sCAEC;AAED,4DAGC;AAED,iDAGC"}
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../../src/common/window/load.js"],"names":[],"mappings":"AAMA,sCAEC;AAED,4DAGC;AAED,iDAGC;AAED,+CAGC"}
@@ -1,6 +1,7 @@
1
1
  export class Instrument extends InstrumentBase {
2
2
  static featureName: string;
3
3
  constructor(agentRef: any);
4
+ setupInspectionEvents(agentIdentifier: any): void;
4
5
  }
5
6
  export const PageViewEvent: typeof Instrument;
6
7
  import { InstrumentBase } from '../../utils/instrument-base';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/instrument/index.js"],"names":[],"mappings":"AASA;IACE,2BAA2C;IAC3C,2BAUC;CACF;AAED,8CAAuC;+BAlBR,6BAA6B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/instrument/index.js"],"names":[],"mappings":"AAYA;IACE,2BAA2C;IAC3C,2BAaC;IAED,kDAiCC;CACF;AAED,8CAAuC;+BA3DR,6BAA6B"}
@@ -1,5 +1,6 @@
1
1
  export class InitialPageLoadInteraction extends Interaction {
2
2
  constructor(agentRef: any);
3
+ oldURL: string;
3
4
  get firstPaint(): any;
4
5
  get firstContentfulPaint(): any;
5
6
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"initial-page-load-interaction.d.ts","sourceRoot":"","sources":["../../../../../src/features/soft_navigations/aggregate/initial-page-load-interaction.js"],"names":[],"mappings":"AAWA;IACE,2BAIC;IAED,sBAAqD;IACrD,gCAAyE;IAEzE;;;OAGG;IACH,oCA6BC;CACF;4BAlD2B,eAAe"}
1
+ {"version":3,"file":"initial-page-load-interaction.d.ts","sourceRoot":"","sources":["../../../../../src/features/soft_navigations/aggregate/initial-page-load-interaction.js"],"names":[],"mappings":"AAWA;IACE,2BAKC;IADC,eAA+B;IAGjC,sBAAqD;IACrD,gCAAyE;IAEzE;;;OAGG;IACH,oCA6BC;CACF;4BAnD2B,eAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"interaction.d.ts","sourceRoot":"","sources":["../../../../../src/features/spa/aggregate/interaction.js"],"names":[],"mappings":"AAaA,4HAwBC;;IAxBD,sGAwBC;IAvBC,cAAwB;IAGxB,WAA4C;IAC5C,eAA0B;IAC1B,cAAc;IACd,kBAAkB;IAClB,iBAAuB;IACvB,wBAA2B;IAC3B,YAAyC;IAA3B,gBAA2B;IACzC,gBAAkB;IAClB,gBAA4B;IAC5B,cAAiB;IAEN,sBAAqE;;gCAtBlD,oBAAoB"}
1
+ {"version":3,"file":"interaction.d.ts","sourceRoot":"","sources":["../../../../../src/features/spa/aggregate/interaction.js"],"names":[],"mappings":"AAaA,4HAyBC;;IAzBD,sGAyBC;IAxBC,cAAwB;IAGxB,WAA4C;IAC5C,eAA0B;IAC1B,cAAc;IACd,kBAAkB;IAClB,iBAAuB;IACvB,wBAA2B;IAC3B,YAAyC;IAA3B,gBAA2B;IACzC,gBAAkB;IAClB,gBAA4B;IAC5B,cAAiB;IAEN,sBAAqE;;gCAtBlD,oBAAoB"}
@@ -1 +1 @@
1
- {"version":3,"file":"finished.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/finished.js"],"names":[],"mappings":"AAYA,mDAMC"}
1
+ {"version":3,"file":"finished.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/finished.js"],"names":[],"mappings":"AAYA,mDAQC"}
@@ -103,7 +103,7 @@ export class ApiBase {
103
103
  /**
104
104
  * Records an additional time point as "finished" in a session trace and adds a page action.
105
105
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/finished/}
106
- * @param {number} [timeStamp] Defaults to the current time of the call. If used, this marks the time that the page is "finished" according to your own criteria.
106
+ * @param {number} [timeStamp] integer (UNIX time) - Defaults to the current time of the call. If used, this marks the time that the page is "finished" according to your own criteria.
107
107
  */
108
108
  finished(timeStamp?: number): any;
109
109
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newrelic/browser-agent",
3
- "version": "1.291.1",
3
+ "version": "1.292.0-rc.0",
4
4
  "private": false,
5
5
  "author": "New Relic Browser Agent Team <browser-agent@newrelic.com>",
6
6
  "description": "New Relic Browser Agent",
@@ -294,4 +294,4 @@
294
294
  "README.md",
295
295
  "CHANGELOG.md"
296
296
  ]
297
- }
297
+ }
@@ -3,6 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
+ import { dispatchGlobalEvent } from '../../common/dispatch/global-event'
6
7
  import { ee } from '../event-emitter/contextual-ee'
7
8
  import { registerHandler as defaultRegister } from '../event-emitter/register-handler'
8
9
  import { featurePriority } from '../../loaders/features/features'
@@ -92,6 +93,13 @@ function drainGroup (agentIdentifier, group, activateGroup = true) {
92
93
  const handlers = defaultRegister.handlers // other storage in registerHandler
93
94
  if (baseEE.aborted || !baseEE.backlog || !handlers) return
94
95
 
96
+ dispatchGlobalEvent({
97
+ agentIdentifier,
98
+ type: 'lifecycle',
99
+ name: 'drain',
100
+ feature: group
101
+ })
102
+
95
103
  // Only activated features being drained should run queued listeners on buffered events. Deactivated features only need to release memory.
96
104
  if (activateGroup) {
97
105
  const bufferedEventsInGroup = baseEE.backlog[group]
@@ -17,3 +17,8 @@ export function onDOMContentLoaded (cb) {
17
17
  if (checkState()) return cb()
18
18
  documentAddEventListener('DOMContentLoaded', cb)
19
19
  }
20
+
21
+ export function onPopstateChange (cb) {
22
+ if (checkState()) return cb()
23
+ windowAddEventListener('popstate', cb)
24
+ }
@@ -6,12 +6,18 @@ import { handle } from '../../../common/event-emitter/handle'
6
6
  import { setupSetPageViewNameAPI } from '../../../loaders/api/setPageViewName'
7
7
  import { InstrumentBase } from '../../utils/instrument-base'
8
8
  import * as CONSTANTS from '../constants'
9
+ import { SESSION_EVENTS } from '../../../common/session/constants'
10
+ import { dispatchGlobalEvent } from '../../../common/dispatch/global-event'
11
+ import { onDOMContentLoaded, onPopstateChange, onWindowLoad } from '../../../common/window/load'
9
12
 
10
13
  export class Instrument extends InstrumentBase {
11
14
  static featureName = CONSTANTS.FEATURE_NAME
12
15
  constructor (agentRef) {
13
16
  super(agentRef, CONSTANTS.FEATURE_NAME)
14
17
 
18
+ /** setup inspection events for window lifecycle */
19
+ this.setupInspectionEvents(agentRef.agentIdentifier)
20
+
15
21
  /** feature specific APIs */
16
22
  setupSetPageViewNameAPI(agentRef)
17
23
 
@@ -20,6 +26,41 @@ export class Instrument extends InstrumentBase {
20
26
 
21
27
  this.importAggregator(agentRef, () => import(/* webpackChunkName: "page_view_event-aggregate" */ '../aggregate'))
22
28
  }
29
+
30
+ setupInspectionEvents (agentIdentifier) {
31
+ const dispatch = (evt, name) => {
32
+ if (!evt) return
33
+ dispatchGlobalEvent({
34
+ agentIdentifier,
35
+ timeStamp: evt.timeStamp,
36
+ loaded: evt.target.readyState === 'complete',
37
+ type: 'window',
38
+ name,
39
+ data: evt.target.location + ''
40
+ })
41
+ }
42
+
43
+ onDOMContentLoaded((evt) => {
44
+ dispatch(evt, 'DOMContentLoaded')
45
+ })
46
+
47
+ onWindowLoad((evt) => {
48
+ dispatch(evt, 'load')
49
+ })
50
+
51
+ onPopstateChange((evt) => {
52
+ dispatch(evt, 'navigate')
53
+ })
54
+
55
+ this.ee.on(SESSION_EVENTS.UPDATE, (_, data) => {
56
+ dispatchGlobalEvent({
57
+ agentIdentifier,
58
+ type: 'lifecycle',
59
+ name: 'session',
60
+ data
61
+ })
62
+ })
63
+ }
23
64
  }
24
65
 
25
66
  export const PageViewEvent = Instrument
@@ -14,6 +14,7 @@ export class InitialPageLoadInteraction extends Interaction {
14
14
  super(agentRef, IPL_TRIGGER_NAME, 0, null)
15
15
  this.queueTime = agentRef.info.queueTime
16
16
  this.appTime = agentRef.info.applicationTime
17
+ this.oldURL = document.referrer
17
18
  }
18
19
 
19
20
  get firstPaint () { return firstPaint.current.value }
@@ -32,7 +32,8 @@ export function Interaction (eventName, timestamp, url, routeName, onFinished, a
32
32
  attrs.trigger = eventName
33
33
  attrs.initialPageURL = initialLocation
34
34
  attrs.oldRoute = routeName
35
- attrs.newURL = attrs.oldURL = url
35
+ attrs.newURL = url
36
+ attrs.oldURL = eventName === 'initialPageLoad' ? document.referrer : url
36
37
  attrs.custom = {}
37
38
  attrs.store = {}
38
39
  }
@@ -4,16 +4,18 @@
4
4
  */
5
5
  import { originTime } from '../../common/constants/runtime'
6
6
  import { handle } from '../../common/event-emitter/handle'
7
- import { now } from '../../common/timing/now'
7
+ import { warn } from '../../common/util/console'
8
8
  import { CUSTOM_METRIC_CHANNEL } from '../../features/metrics/constants'
9
9
  import { FEATURE_NAMES } from '../features/features'
10
10
  import { ADD_PAGE_ACTION, FINISHED, prefix } from './constants'
11
11
  import { setupAPI } from './sharedHandlers'
12
12
 
13
13
  export function setupFinishedAPI (agent) {
14
- setupAPI(FINISHED, function (time = now()) {
15
- handle(CUSTOM_METRIC_CHANNEL, [FINISHED, { time }], undefined, FEATURE_NAMES.metrics, agent.ee)
16
- agent.addToTrace({ name: FINISHED, start: time + originTime, origin: 'nr' })
17
- handle(prefix + ADD_PAGE_ACTION, [time, FINISHED], undefined, FEATURE_NAMES.genericEvents, agent.ee)
14
+ setupAPI(FINISHED, function (unixTime = Date.now()) {
15
+ const relativeTime = unixTime - originTime
16
+ if (relativeTime < 0) warn(62, unixTime)
17
+ handle(CUSTOM_METRIC_CHANNEL, [FINISHED, { time: relativeTime }], undefined, FEATURE_NAMES.metrics, agent.ee)
18
+ agent.addToTrace({ name: FINISHED, start: unixTime, origin: 'nr' })
19
+ handle(prefix + ADD_PAGE_ACTION, [relativeTime, FINISHED], undefined, FEATURE_NAMES.genericEvents, agent.ee)
18
20
  }, agent)
19
21
  }
@@ -144,7 +144,7 @@ export class ApiBase {
144
144
  /**
145
145
  * Records an additional time point as "finished" in a session trace and adds a page action.
146
146
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/finished/}
147
- * @param {number} [timeStamp] Defaults to the current time of the call. If used, this marks the time that the page is "finished" according to your own criteria.
147
+ * @param {number} [timeStamp] integer (UNIX time) - Defaults to the current time of the call. If used, this marks the time that the page is "finished" according to your own criteria.
148
148
  */
149
149
  finished (timeStamp) {
150
150
  return this.#callMethod(FINISHED, timeStamp)