@newrelic/browser-agent 1.290.1 → 1.291.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.
- package/CHANGELOG.md +13 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/harvest/harvester.js +0 -7
- package/dist/cjs/common/session/session-entity.js +5 -5
- package/dist/cjs/common/util/console.js +12 -0
- package/dist/cjs/features/generic_events/aggregate/index.js +16 -0
- package/dist/cjs/features/generic_events/instrument/index.js +2 -0
- package/dist/cjs/features/session_replay/aggregate/index.js +3 -0
- package/dist/cjs/features/session_replay/shared/recorder.js +0 -4
- package/dist/cjs/features/session_trace/aggregate/index.js +6 -2
- package/dist/cjs/features/session_trace/aggregate/trace/storage.js +0 -7
- package/dist/cjs/loaders/api/constants.js +3 -2
- package/dist/cjs/loaders/api/measure.js +60 -0
- package/dist/cjs/loaders/api-base.js +11 -0
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/harvest/harvester.js +0 -7
- package/dist/esm/common/session/session-entity.js +5 -5
- package/dist/esm/common/util/console.js +13 -0
- package/dist/esm/features/generic_events/aggregate/index.js +16 -0
- package/dist/esm/features/generic_events/instrument/index.js +2 -0
- package/dist/esm/features/session_replay/aggregate/index.js +3 -0
- package/dist/esm/features/session_replay/shared/recorder.js +0 -4
- package/dist/esm/features/session_trace/aggregate/index.js +6 -2
- package/dist/esm/features/session_trace/aggregate/trace/storage.js +0 -7
- package/dist/esm/loaders/api/constants.js +2 -1
- package/dist/esm/loaders/api/measure.js +53 -0
- package/dist/esm/loaders/api-base.js +12 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/harvest/harvester.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts +0 -1
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/util/console.d.ts +0 -4
- package/dist/types/common/util/console.d.ts.map +1 -1
- package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/trace/storage.d.ts +0 -1
- package/dist/types/features/session_trace/aggregate/trace/storage.d.ts.map +1 -1
- package/dist/types/loaders/api/constants.d.ts +1 -0
- package/dist/types/loaders/api/constants.d.ts.map +1 -1
- package/dist/types/loaders/api/measure.d.ts +2 -0
- package/dist/types/loaders/api/measure.d.ts.map +1 -0
- package/dist/types/loaders/api-base.d.ts +13 -0
- package/dist/types/loaders/api-base.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/common/harvest/harvester.js +0 -5
- package/src/common/session/session-entity.js +5 -6
- package/src/common/util/console.js +13 -0
- package/src/features/generic_events/aggregate/index.js +15 -0
- package/src/features/generic_events/instrument/index.js +2 -0
- package/src/features/session_replay/aggregate/index.js +4 -0
- package/src/features/session_replay/shared/recorder.js +0 -4
- package/src/features/session_trace/aggregate/index.js +6 -2
- package/src/features/session_trace/aggregate/trace/storage.js +0 -8
- package/src/loaders/api/constants.js +1 -0
- package/src/loaders/api/measure.js +53 -0
- package/src/loaders/api-base.js +12 -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.291.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.290.1...v1.291.0) (2025-05-30)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Create the measure API ([#1476](https://github.com/newrelic/newrelic-browser-agent/issues/1476)) ([f944b76](https://github.com/newrelic/newrelic-browser-agent/commit/f944b76c2137e6d75e47e692ded4ba5f04bb4b6d))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* Fix race between end of session and features aborting ([#1487](https://github.com/newrelic/newrelic-browser-agent/issues/1487)) ([531f8d4](https://github.com/newrelic/newrelic-browser-agent/commit/531f8d4228f6c7ead8e2342c8a8dd25c651e9ec6))
|
|
17
|
+
* Harvest first session trace payload immediately ([#1483](https://github.com/newrelic/newrelic-browser-agent/issues/1483)) ([50f4ace](https://github.com/newrelic/newrelic-browser-agent/commit/50f4acea3e27c6b5e65d02ffb46af02b351e4500))
|
|
18
|
+
|
|
6
19
|
## [1.290.1](https://github.com/newrelic/newrelic-browser-agent/compare/v1.290.0...v1.290.1) (2025-05-21)
|
|
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.
|
|
20
|
+
const VERSION = exports.VERSION = "1.291.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.
|
|
20
|
+
const VERSION = exports.VERSION = "1.291.0";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Exposes the build type of the agent
|
|
@@ -10,7 +10,6 @@ var _env = require("../constants/env.npm");
|
|
|
10
10
|
var _runtime = require("../constants/runtime");
|
|
11
11
|
var _handle = require("../event-emitter/handle");
|
|
12
12
|
var _eventListenerOpts = require("../event-listener/event-listener-opts");
|
|
13
|
-
var _constants2 = require("../session/constants");
|
|
14
13
|
var _now = require("../timing/now");
|
|
15
14
|
var _eol = require("../unload/eol");
|
|
16
15
|
var _cleanUrl = require("../url/clean-url");
|
|
@@ -43,12 +42,6 @@ class Harvester {
|
|
|
43
42
|
}));
|
|
44
43
|
/* This callback should run in bubble phase, so that that CWV api, like "onLCP", is called before the final harvest so that emitted timings are part of last outgoing. */
|
|
45
44
|
}, false);
|
|
46
|
-
|
|
47
|
-
/* Flush all buffered data if session resets and give up retries. This should be synchronous to ensure that the correct `session` value is sent.
|
|
48
|
-
Since session-reset generates a new session ID and the ID is grabbed at send-time, any delays or retries would cause the payload to be sent under the wrong session ID. */
|
|
49
|
-
agentRef.ee.on(_constants2.SESSION_EVENTS.RESET, () => this.initializedAggregates.forEach(aggregateInst => this.triggerHarvestFor(aggregateInst, {
|
|
50
|
-
forceNoRetry: true
|
|
51
|
-
})));
|
|
52
45
|
}
|
|
53
46
|
startTimer(harvestInterval = this.agentRef.init.harvest.interval) {
|
|
54
47
|
if (this.#started) return;
|
|
@@ -240,7 +240,10 @@ class SessionEntity {
|
|
|
240
240
|
// * stop recording (stn and sr)...
|
|
241
241
|
// * delete the session and start over
|
|
242
242
|
try {
|
|
243
|
-
if (this.initialized)
|
|
243
|
+
if (this.initialized) {
|
|
244
|
+
this.ee.emit(_constants.SESSION_EVENTS.RESET);
|
|
245
|
+
this.state.numOfResets++;
|
|
246
|
+
}
|
|
244
247
|
this.storage.remove(this.lookupKey);
|
|
245
248
|
this.inactiveTimer?.abort?.();
|
|
246
249
|
this.expiresTimer?.clear?.();
|
|
@@ -251,7 +254,7 @@ class SessionEntity {
|
|
|
251
254
|
storage: this.storage,
|
|
252
255
|
expiresMs: this.expiresMs,
|
|
253
256
|
inactiveMs: this.inactiveMs,
|
|
254
|
-
numOfResets:
|
|
257
|
+
numOfResets: this.state.numOfResets
|
|
255
258
|
});
|
|
256
259
|
return this.read();
|
|
257
260
|
} catch (e) {
|
|
@@ -270,9 +273,6 @@ class SessionEntity {
|
|
|
270
273
|
inactiveAt: this.getFutureTimestamp(this.inactiveMs)
|
|
271
274
|
});
|
|
272
275
|
}
|
|
273
|
-
isAfterSessionExpiry(timestamp) {
|
|
274
|
-
return this.state.numOfResets > 0 || typeof timestamp === 'number' && typeof this.state.expiresAt === 'number' && timestamp >= this.state.expiresAt;
|
|
275
|
-
}
|
|
276
276
|
|
|
277
277
|
/**
|
|
278
278
|
* @param {number} timestamp
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.warn = warn;
|
|
7
|
+
var _globalEvent = require("../dispatch/global-event");
|
|
7
8
|
/**
|
|
8
9
|
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
9
10
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -20,4 +21,15 @@ exports.warn = warn;
|
|
|
20
21
|
function warn(code, secondary) {
|
|
21
22
|
if (typeof console.debug !== 'function') return;
|
|
22
23
|
console.debug("New Relic Warning: https://github.com/newrelic/newrelic-browser-agent/blob/main/docs/warning-codes.md#".concat(code), secondary);
|
|
24
|
+
(0, _globalEvent.dispatchGlobalEvent)({
|
|
25
|
+
agentIdentifier: null,
|
|
26
|
+
drained: null,
|
|
27
|
+
type: 'data',
|
|
28
|
+
name: 'warn',
|
|
29
|
+
feature: 'warn',
|
|
30
|
+
data: {
|
|
31
|
+
code,
|
|
32
|
+
secondary
|
|
33
|
+
}
|
|
34
|
+
});
|
|
23
35
|
}
|
|
@@ -224,6 +224,22 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
224
224
|
}
|
|
225
225
|
}, this.featureName, this.ee);
|
|
226
226
|
}
|
|
227
|
+
(0, _registerHandler.registerHandler)('api-measure', (args, n) => {
|
|
228
|
+
const {
|
|
229
|
+
start,
|
|
230
|
+
duration,
|
|
231
|
+
customAttributes
|
|
232
|
+
} = args;
|
|
233
|
+
const event = {
|
|
234
|
+
...customAttributes,
|
|
235
|
+
eventType: 'BrowserPerformance',
|
|
236
|
+
timestamp: Math.floor(agentRef.runtime.timeKeeper.correctRelativeTimestamp(start)),
|
|
237
|
+
entryName: n,
|
|
238
|
+
entryDuration: duration,
|
|
239
|
+
entryType: 'measure'
|
|
240
|
+
};
|
|
241
|
+
this.addEvent(event);
|
|
242
|
+
}, this.featureName, this.ee);
|
|
227
243
|
agentRef.runtime.harvester.triggerHarvestFor(this);
|
|
228
244
|
this.drain();
|
|
229
245
|
});
|
|
@@ -12,6 +12,7 @@ var _addPageAction = require("../../../loaders/api/addPageAction");
|
|
|
12
12
|
var _finished = require("../../../loaders/api/finished");
|
|
13
13
|
var _recordCustomEvent = require("../../../loaders/api/recordCustomEvent");
|
|
14
14
|
var _register = require("../../../loaders/api/register");
|
|
15
|
+
var _measure = require("../../../loaders/api/measure");
|
|
15
16
|
var _instrumentBase = require("../../utils/instrument-base");
|
|
16
17
|
var _constants = require("../constants");
|
|
17
18
|
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); }
|
|
@@ -31,6 +32,7 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
31
32
|
(0, _recordCustomEvent.setupRecordCustomEventAPI)(agentRef);
|
|
32
33
|
(0, _finished.setupFinishedAPI)(agentRef);
|
|
33
34
|
(0, _register.setupRegisterAPI)(agentRef);
|
|
35
|
+
(0, _measure.setupMeasureAPI)(agentRef);
|
|
34
36
|
if (_runtime.isBrowserScope) {
|
|
35
37
|
if (agentRef.init.user_actions.enabled) {
|
|
36
38
|
_constants.OBSERVED_EVENTS.forEach(eventType => (0, _eventListenerOpts.windowAddEventListener)(eventType, evt => (0, _handle.handle)('ua', [evt], undefined, this.featureName, this.ee), true));
|
|
@@ -281,6 +281,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
281
281
|
this.recorder.clearBuffer();
|
|
282
282
|
if (recorderEvents.type === 'preloaded') this.agentRef.runtime.harvester.triggerHarvestFor(this);
|
|
283
283
|
payloadOutput.payload = payload;
|
|
284
|
+
if (!this.agentRef.runtime.session.state.traceHarvestStarted) {
|
|
285
|
+
(0, _console.warn)(59, JSON.stringify(this.agentRef.runtime.session.state));
|
|
286
|
+
}
|
|
284
287
|
return [payloadOutput];
|
|
285
288
|
}
|
|
286
289
|
getCorrectedTimestamp(node) {
|
|
@@ -168,10 +168,6 @@ class Recorder {
|
|
|
168
168
|
/** Store a payload in the buffer (this.#events). This should be the callback to the recording lib noticing a mutation */
|
|
169
169
|
store(event, isCheckout) {
|
|
170
170
|
if (!event) return;
|
|
171
|
-
if (this.parent.agentRef.runtime.session?.isAfterSessionExpiry(event.timestamp)) {
|
|
172
|
-
(0, _handle.handle)(_constants3.SUPPORTABILITY_METRIC_CHANNEL, ['Session/Expired/SessionReplay/Seen'], undefined, _features.FEATURE_NAMES.metrics, this.ee);
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
171
|
if (!(this.parent instanceof _aggregateBase.AggregateBase) && this.#preloaded.length) this.currentBufferTarget = this.#preloaded[this.#preloaded.length - 1];else this.currentBufferTarget = this.#events;
|
|
176
172
|
if (this.parent.blocked) return;
|
|
177
173
|
if (this.parent.timeKeeper?.ready && !event.__newrelic) {
|
|
@@ -13,6 +13,7 @@ var _runtime = require("../../../common/constants/runtime");
|
|
|
13
13
|
var _constants2 = require("../../../common/session/constants");
|
|
14
14
|
var _traverse = require("../../../common/util/traverse");
|
|
15
15
|
var _cleanUrl = require("../../../common/url/clean-url");
|
|
16
|
+
var _console = require("../../../common/util/console");
|
|
16
17
|
/**
|
|
17
18
|
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
18
19
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -98,9 +99,11 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
98
99
|
sessionTraceMode: this.mode
|
|
99
100
|
});
|
|
100
101
|
this.drain();
|
|
102
|
+
/** try to harvest immediately. This will not send if the trace is not running in FULL mode due to the pre-harvest checks. */
|
|
103
|
+
this.agentRef.runtime.harvester.triggerHarvestFor(this);
|
|
101
104
|
}
|
|
102
105
|
preHarvestChecks() {
|
|
103
|
-
if (this.mode !== _constants2.MODE.FULL) return; // only allow harvest if running in full mode
|
|
106
|
+
if (this.blocked || this.mode !== _constants2.MODE.FULL) return; // only allow harvest if running in full mode
|
|
104
107
|
if (!this.timeKeeper?.ready) return; // this should likely never happen, but just to be safe, we should never harvest if we cant correct time
|
|
105
108
|
if (!this.agentRef.runtime.session) return; // session entity is required for trace to run and continue running
|
|
106
109
|
if (this.sessionId !== this.agentRef.runtime.session.state.value || this.ptid !== this.agentRef.runtime.ptid) {
|
|
@@ -194,7 +197,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
/** Stop running for the remainder of the page lifecycle */
|
|
197
|
-
abort() {
|
|
200
|
+
abort(code) {
|
|
201
|
+
(0, _console.warn)(60, code);
|
|
198
202
|
this.blocked = true;
|
|
199
203
|
this.mode = _constants2.MODE.OFF;
|
|
200
204
|
this.agentRef.runtime.session.write({
|
|
@@ -53,9 +53,6 @@ class TraceStorage {
|
|
|
53
53
|
constructor(parent) {
|
|
54
54
|
this.parent = parent;
|
|
55
55
|
}
|
|
56
|
-
isAfterSessionExpiry(entryTimestamp) {
|
|
57
|
-
return this.parent.agentRef.runtime?.session?.isAfterSessionExpiry((this.parent.timeKeeper?.ready && this.parent.timeKeeper.convertRelativeTimestamp(entryTimestamp)) ?? undefined);
|
|
58
|
-
}
|
|
59
56
|
|
|
60
57
|
/** Central function called by all the other store__ & addToTrace API to append a trace node. */
|
|
61
58
|
storeSTN(stn) {
|
|
@@ -66,10 +63,6 @@ class TraceStorage {
|
|
|
66
63
|
const openedSpace = this.trimSTNs(ERROR_MODE_SECONDS_WINDOW); // but maybe we could make some space by discarding irrelevant nodes if we're in sessioned Error mode
|
|
67
64
|
if (openedSpace === 0) return;
|
|
68
65
|
}
|
|
69
|
-
if (this.isAfterSessionExpiry(stn.s)) {
|
|
70
|
-
this.parent.reportSupportabilityMetric('Session/Expired/SessionTrace/Seen');
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
66
|
if (this.trace[stn.n]) this.trace[stn.n].push(stn);else this.trace[stn.n] = [stn];
|
|
74
67
|
if (stn.s < this.earliestTimeStamp) this.earliestTimeStamp = stn.s;
|
|
75
68
|
if (stn.s > this.latestTimeStamp) this.latestTimeStamp = stn.s;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.spaPrefix = exports.prefix = exports.WRAP_LOGGER = exports.START = exports.SET_USER_ID = exports.SET_PAGE_VIEW_NAME = exports.SET_ERROR_HANDLER = exports.SET_CUSTOM_ATTRIBUTE = exports.SET_CURRENT_ROUTE_NAME = exports.SET_APPLICATION_VERSION = exports.REGISTER = exports.RECORD_REPLAY = exports.RECORD_CUSTOM_EVENT = exports.PAUSE_REPLAY = exports.NOTICE_ERROR = exports.LOG = exports.INTERACTION = exports.FINISHED = exports.ADD_TO_TRACE = exports.ADD_RELEASE = exports.ADD_PAGE_ACTION = void 0;
|
|
6
|
+
exports.spaPrefix = exports.prefix = exports.WRAP_LOGGER = exports.START = exports.SET_USER_ID = exports.SET_PAGE_VIEW_NAME = exports.SET_ERROR_HANDLER = exports.SET_CUSTOM_ATTRIBUTE = exports.SET_CURRENT_ROUTE_NAME = exports.SET_APPLICATION_VERSION = exports.REGISTER = exports.RECORD_REPLAY = exports.RECORD_CUSTOM_EVENT = exports.PAUSE_REPLAY = exports.NOTICE_ERROR = exports.MEASURE = exports.LOG = exports.INTERACTION = exports.FINISHED = exports.ADD_TO_TRACE = exports.ADD_RELEASE = exports.ADD_PAGE_ACTION = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
9
9
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -28,4 +28,5 @@ const SET_ERROR_HANDLER = exports.SET_ERROR_HANDLER = 'setErrorHandler';
|
|
|
28
28
|
const SET_PAGE_VIEW_NAME = exports.SET_PAGE_VIEW_NAME = 'setPageViewName';
|
|
29
29
|
const SET_USER_ID = exports.SET_USER_ID = 'setUserId';
|
|
30
30
|
const START = exports.START = 'start';
|
|
31
|
-
const WRAP_LOGGER = exports.WRAP_LOGGER = 'wrapLogger';
|
|
31
|
+
const WRAP_LOGGER = exports.WRAP_LOGGER = 'wrapLogger';
|
|
32
|
+
const MEASURE = exports.MEASURE = 'measure';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.setupMeasureAPI = setupMeasureAPI;
|
|
7
|
+
var _handle = require("../../common/event-emitter/handle");
|
|
8
|
+
var _now = require("../../common/timing/now");
|
|
9
|
+
var _console = require("../../common/util/console");
|
|
10
|
+
var _features = require("../features/features");
|
|
11
|
+
var _constants = require("./constants");
|
|
12
|
+
var _sharedHandlers = require("./sharedHandlers");
|
|
13
|
+
/**
|
|
14
|
+
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
function setupMeasureAPI(agent) {
|
|
19
|
+
(0, _sharedHandlers.setupAPI)(_constants.MEASURE, function (name, options) {
|
|
20
|
+
const n = (0, _now.now)();
|
|
21
|
+
const {
|
|
22
|
+
start,
|
|
23
|
+
end,
|
|
24
|
+
customAttributes
|
|
25
|
+
} = options || {};
|
|
26
|
+
const returnObj = {
|
|
27
|
+
customAttributes: customAttributes || {}
|
|
28
|
+
};
|
|
29
|
+
if (typeof returnObj.customAttributes !== 'object' || typeof name !== 'string' || name.length === 0) {
|
|
30
|
+
(0, _console.warn)(57);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* getValueFromTiming - Helper function to extract a numeric value from a supplied option.
|
|
36
|
+
* @param {Number|PerformanceMark} [timing] The timing value
|
|
37
|
+
* @param {Number} [d] The default value to return if timing is invalid
|
|
38
|
+
* @returns {Number} The timing value or the default value
|
|
39
|
+
*/
|
|
40
|
+
const getValueFromTiming = (timing, d) => {
|
|
41
|
+
if (timing == null) return d;
|
|
42
|
+
if (typeof timing === 'number') return timing;
|
|
43
|
+
if (timing instanceof PerformanceMark) return timing.startTime;
|
|
44
|
+
return Number.NaN;
|
|
45
|
+
};
|
|
46
|
+
returnObj.start = getValueFromTiming(start, 0);
|
|
47
|
+
returnObj.end = getValueFromTiming(end, n);
|
|
48
|
+
if (Number.isNaN(returnObj.start) || Number.isNaN(returnObj.end)) {
|
|
49
|
+
(0, _console.warn)(57);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
returnObj.duration = returnObj.end - returnObj.start;
|
|
53
|
+
if (returnObj.duration < 0) {
|
|
54
|
+
(0, _console.warn)(58);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
(0, _handle.handle)(_constants.prefix + _constants.MEASURE, [returnObj, name], undefined, _features.FEATURE_NAMES.genericEvents, agent.ee);
|
|
58
|
+
return returnObj;
|
|
59
|
+
}, agent);
|
|
60
|
+
}
|
|
@@ -220,5 +220,16 @@ class ApiBase {
|
|
|
220
220
|
wrapLogger(parent, functionName, options) {
|
|
221
221
|
return this.#callMethod(_constants.WRAP_LOGGER, parent, functionName, options);
|
|
222
222
|
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Measures a task that is recorded as a BrowserPerformance event.
|
|
226
|
+
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/measure/}
|
|
227
|
+
* @param {string} name The name of the task
|
|
228
|
+
* @param {object?} options An object used to control the way the measure API operates
|
|
229
|
+
* @returns {{start: number, end: number, duration: number, customAttributes: object}} Measurement details
|
|
230
|
+
*/
|
|
231
|
+
measure(name, options) {
|
|
232
|
+
return this.#callMethod(_constants.MEASURE, name, options);
|
|
233
|
+
}
|
|
223
234
|
}
|
|
224
235
|
exports.ApiBase = ApiBase;
|
|
@@ -8,7 +8,6 @@ import { VERSION } from "../constants/env.npm";
|
|
|
8
8
|
import { globalScope, isWorkerScope } from '../constants/runtime';
|
|
9
9
|
import { handle } from '../event-emitter/handle';
|
|
10
10
|
import { eventListenerOpts } from '../event-listener/event-listener-opts';
|
|
11
|
-
import { SESSION_EVENTS } from '../session/constants';
|
|
12
11
|
import { now } from '../timing/now';
|
|
13
12
|
import { subscribeToEOL } from '../unload/eol';
|
|
14
13
|
import { cleanURL } from '../url/clean-url';
|
|
@@ -36,12 +35,6 @@ export class Harvester {
|
|
|
36
35
|
}));
|
|
37
36
|
/* This callback should run in bubble phase, so that that CWV api, like "onLCP", is called before the final harvest so that emitted timings are part of last outgoing. */
|
|
38
37
|
}, false);
|
|
39
|
-
|
|
40
|
-
/* Flush all buffered data if session resets and give up retries. This should be synchronous to ensure that the correct `session` value is sent.
|
|
41
|
-
Since session-reset generates a new session ID and the ID is grabbed at send-time, any delays or retries would cause the payload to be sent under the wrong session ID. */
|
|
42
|
-
agentRef.ee.on(SESSION_EVENTS.RESET, () => this.initializedAggregates.forEach(aggregateInst => this.triggerHarvestFor(aggregateInst, {
|
|
43
|
-
forceNoRetry: true
|
|
44
|
-
})));
|
|
45
38
|
}
|
|
46
39
|
startTimer(harvestInterval = this.agentRef.init.harvest.interval) {
|
|
47
40
|
if (this.#started) return;
|
|
@@ -234,7 +234,10 @@ export class SessionEntity {
|
|
|
234
234
|
// * stop recording (stn and sr)...
|
|
235
235
|
// * delete the session and start over
|
|
236
236
|
try {
|
|
237
|
-
if (this.initialized)
|
|
237
|
+
if (this.initialized) {
|
|
238
|
+
this.ee.emit(SESSION_EVENTS.RESET);
|
|
239
|
+
this.state.numOfResets++;
|
|
240
|
+
}
|
|
238
241
|
this.storage.remove(this.lookupKey);
|
|
239
242
|
this.inactiveTimer?.abort?.();
|
|
240
243
|
this.expiresTimer?.clear?.();
|
|
@@ -245,7 +248,7 @@ export class SessionEntity {
|
|
|
245
248
|
storage: this.storage,
|
|
246
249
|
expiresMs: this.expiresMs,
|
|
247
250
|
inactiveMs: this.inactiveMs,
|
|
248
|
-
numOfResets:
|
|
251
|
+
numOfResets: this.state.numOfResets
|
|
249
252
|
});
|
|
250
253
|
return this.read();
|
|
251
254
|
} catch (e) {
|
|
@@ -264,9 +267,6 @@ export class SessionEntity {
|
|
|
264
267
|
inactiveAt: this.getFutureTimestamp(this.inactiveMs)
|
|
265
268
|
});
|
|
266
269
|
}
|
|
267
|
-
isAfterSessionExpiry(timestamp) {
|
|
268
|
-
return this.state.numOfResets > 0 || typeof timestamp === 'number' && typeof this.state.expiresAt === 'number' && timestamp >= this.state.expiresAt;
|
|
269
|
-
}
|
|
270
270
|
|
|
271
271
|
/**
|
|
272
272
|
* @param {number} timestamp
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { dispatchGlobalEvent } from '../dispatch/global-event';
|
|
7
|
+
|
|
6
8
|
/* eslint no-console: ["error", { allow: ["debug"] }] */
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -14,4 +16,15 @@
|
|
|
14
16
|
export function warn(code, secondary) {
|
|
15
17
|
if (typeof console.debug !== 'function') return;
|
|
16
18
|
console.debug("New Relic Warning: https://github.com/newrelic/newrelic-browser-agent/blob/main/docs/warning-codes.md#".concat(code), secondary);
|
|
19
|
+
dispatchGlobalEvent({
|
|
20
|
+
agentIdentifier: null,
|
|
21
|
+
drained: null,
|
|
22
|
+
type: 'data',
|
|
23
|
+
name: 'warn',
|
|
24
|
+
feature: 'warn',
|
|
25
|
+
data: {
|
|
26
|
+
code,
|
|
27
|
+
secondary
|
|
28
|
+
}
|
|
29
|
+
});
|
|
17
30
|
}
|
|
@@ -217,6 +217,22 @@ export class Aggregate extends AggregateBase {
|
|
|
217
217
|
}
|
|
218
218
|
}, this.featureName, this.ee);
|
|
219
219
|
}
|
|
220
|
+
registerHandler('api-measure', (args, n) => {
|
|
221
|
+
const {
|
|
222
|
+
start,
|
|
223
|
+
duration,
|
|
224
|
+
customAttributes
|
|
225
|
+
} = args;
|
|
226
|
+
const event = {
|
|
227
|
+
...customAttributes,
|
|
228
|
+
eventType: 'BrowserPerformance',
|
|
229
|
+
timestamp: Math.floor(agentRef.runtime.timeKeeper.correctRelativeTimestamp(start)),
|
|
230
|
+
entryName: n,
|
|
231
|
+
entryDuration: duration,
|
|
232
|
+
entryType: 'measure'
|
|
233
|
+
};
|
|
234
|
+
this.addEvent(event);
|
|
235
|
+
}, this.featureName, this.ee);
|
|
220
236
|
agentRef.runtime.harvester.triggerHarvestFor(this);
|
|
221
237
|
this.drain();
|
|
222
238
|
});
|
|
@@ -11,6 +11,7 @@ import { setupAddPageActionAPI } from '../../../loaders/api/addPageAction';
|
|
|
11
11
|
import { setupFinishedAPI } from '../../../loaders/api/finished';
|
|
12
12
|
import { setupRecordCustomEventAPI } from '../../../loaders/api/recordCustomEvent';
|
|
13
13
|
import { setupRegisterAPI } from '../../../loaders/api/register';
|
|
14
|
+
import { setupMeasureAPI } from '../../../loaders/api/measure';
|
|
14
15
|
import { InstrumentBase } from '../../utils/instrument-base';
|
|
15
16
|
import { FEATURE_NAME, OBSERVED_EVENTS, OBSERVED_WINDOW_EVENTS } from '../constants';
|
|
16
17
|
export class Instrument extends InstrumentBase {
|
|
@@ -25,6 +26,7 @@ export class Instrument extends InstrumentBase {
|
|
|
25
26
|
setupRecordCustomEventAPI(agentRef);
|
|
26
27
|
setupFinishedAPI(agentRef);
|
|
27
28
|
setupRegisterAPI(agentRef);
|
|
29
|
+
setupMeasureAPI(agentRef);
|
|
28
30
|
if (isBrowserScope) {
|
|
29
31
|
if (agentRef.init.user_actions.enabled) {
|
|
30
32
|
OBSERVED_EVENTS.forEach(eventType => windowAddEventListener(eventType, evt => handle('ua', [evt], undefined, this.featureName, this.ee), true));
|
|
@@ -276,6 +276,9 @@ export class Aggregate extends AggregateBase {
|
|
|
276
276
|
this.recorder.clearBuffer();
|
|
277
277
|
if (recorderEvents.type === 'preloaded') this.agentRef.runtime.harvester.triggerHarvestFor(this);
|
|
278
278
|
payloadOutput.payload = payload;
|
|
279
|
+
if (!this.agentRef.runtime.session.state.traceHarvestStarted) {
|
|
280
|
+
warn(59, JSON.stringify(this.agentRef.runtime.session.state));
|
|
281
|
+
}
|
|
279
282
|
return [payloadOutput];
|
|
280
283
|
}
|
|
281
284
|
getCorrectedTimestamp(node) {
|
|
@@ -161,10 +161,6 @@ export class Recorder {
|
|
|
161
161
|
/** Store a payload in the buffer (this.#events). This should be the callback to the recording lib noticing a mutation */
|
|
162
162
|
store(event, isCheckout) {
|
|
163
163
|
if (!event) return;
|
|
164
|
-
if (this.parent.agentRef.runtime.session?.isAfterSessionExpiry(event.timestamp)) {
|
|
165
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['Session/Expired/SessionReplay/Seen'], undefined, FEATURE_NAMES.metrics, this.ee);
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
164
|
if (!(this.parent instanceof AggregateBase) && this.#preloaded.length) this.currentBufferTarget = this.#preloaded[this.#preloaded.length - 1];else this.currentBufferTarget = this.#events;
|
|
169
165
|
if (this.parent.blocked) return;
|
|
170
166
|
if (this.parent.timeKeeper?.ready && !event.__newrelic) {
|
|
@@ -11,6 +11,7 @@ import { globalScope } from '../../../common/constants/runtime';
|
|
|
11
11
|
import { MODE, SESSION_EVENTS } from '../../../common/session/constants';
|
|
12
12
|
import { applyFnToProps } from '../../../common/util/traverse';
|
|
13
13
|
import { cleanURL } from '../../../common/url/clean-url';
|
|
14
|
+
import { warn } from '../../../common/util/console';
|
|
14
15
|
const ERROR_MODE_SECONDS_WINDOW = 30 * 1000; // sliding window of nodes to track when simply monitoring (but not harvesting) in error mode
|
|
15
16
|
/** Reserved room for query param attrs */
|
|
16
17
|
const QUERY_PARAM_PADDING = 5000;
|
|
@@ -91,9 +92,11 @@ export class Aggregate extends AggregateBase {
|
|
|
91
92
|
sessionTraceMode: this.mode
|
|
92
93
|
});
|
|
93
94
|
this.drain();
|
|
95
|
+
/** try to harvest immediately. This will not send if the trace is not running in FULL mode due to the pre-harvest checks. */
|
|
96
|
+
this.agentRef.runtime.harvester.triggerHarvestFor(this);
|
|
94
97
|
}
|
|
95
98
|
preHarvestChecks() {
|
|
96
|
-
if (this.mode !== MODE.FULL) return; // only allow harvest if running in full mode
|
|
99
|
+
if (this.blocked || this.mode !== MODE.FULL) return; // only allow harvest if running in full mode
|
|
97
100
|
if (!this.timeKeeper?.ready) return; // this should likely never happen, but just to be safe, we should never harvest if we cant correct time
|
|
98
101
|
if (!this.agentRef.runtime.session) return; // session entity is required for trace to run and continue running
|
|
99
102
|
if (this.sessionId !== this.agentRef.runtime.session.state.value || this.ptid !== this.agentRef.runtime.ptid) {
|
|
@@ -187,7 +190,8 @@ export class Aggregate extends AggregateBase {
|
|
|
187
190
|
}
|
|
188
191
|
|
|
189
192
|
/** Stop running for the remainder of the page lifecycle */
|
|
190
|
-
abort() {
|
|
193
|
+
abort(code) {
|
|
194
|
+
warn(60, code);
|
|
191
195
|
this.blocked = true;
|
|
192
196
|
this.mode = MODE.OFF;
|
|
193
197
|
this.agentRef.runtime.session.write({
|
|
@@ -46,9 +46,6 @@ export class TraceStorage {
|
|
|
46
46
|
constructor(parent) {
|
|
47
47
|
this.parent = parent;
|
|
48
48
|
}
|
|
49
|
-
isAfterSessionExpiry(entryTimestamp) {
|
|
50
|
-
return this.parent.agentRef.runtime?.session?.isAfterSessionExpiry((this.parent.timeKeeper?.ready && this.parent.timeKeeper.convertRelativeTimestamp(entryTimestamp)) ?? undefined);
|
|
51
|
-
}
|
|
52
49
|
|
|
53
50
|
/** Central function called by all the other store__ & addToTrace API to append a trace node. */
|
|
54
51
|
storeSTN(stn) {
|
|
@@ -59,10 +56,6 @@ export class TraceStorage {
|
|
|
59
56
|
const openedSpace = this.trimSTNs(ERROR_MODE_SECONDS_WINDOW); // but maybe we could make some space by discarding irrelevant nodes if we're in sessioned Error mode
|
|
60
57
|
if (openedSpace === 0) return;
|
|
61
58
|
}
|
|
62
|
-
if (this.isAfterSessionExpiry(stn.s)) {
|
|
63
|
-
this.parent.reportSupportabilityMetric('Session/Expired/SessionTrace/Seen');
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
59
|
if (this.trace[stn.n]) this.trace[stn.n].push(stn);else this.trace[stn.n] = [stn];
|
|
67
60
|
if (stn.s < this.earliestTimeStamp) this.earliestTimeStamp = stn.s;
|
|
68
61
|
if (stn.s > this.latestTimeStamp) this.latestTimeStamp = stn.s;
|
|
@@ -22,4 +22,5 @@ export const SET_ERROR_HANDLER = 'setErrorHandler';
|
|
|
22
22
|
export const SET_PAGE_VIEW_NAME = 'setPageViewName';
|
|
23
23
|
export const SET_USER_ID = 'setUserId';
|
|
24
24
|
export const START = 'start';
|
|
25
|
-
export const WRAP_LOGGER = 'wrapLogger';
|
|
25
|
+
export const WRAP_LOGGER = 'wrapLogger';
|
|
26
|
+
export const MEASURE = 'measure';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { handle } from '../../common/event-emitter/handle';
|
|
6
|
+
import { now } from '../../common/timing/now';
|
|
7
|
+
import { warn } from '../../common/util/console';
|
|
8
|
+
import { FEATURE_NAMES } from '../features/features';
|
|
9
|
+
import { prefix, MEASURE } from './constants';
|
|
10
|
+
import { setupAPI } from './sharedHandlers';
|
|
11
|
+
export function setupMeasureAPI(agent) {
|
|
12
|
+
setupAPI(MEASURE, function (name, options) {
|
|
13
|
+
const n = now();
|
|
14
|
+
const {
|
|
15
|
+
start,
|
|
16
|
+
end,
|
|
17
|
+
customAttributes
|
|
18
|
+
} = options || {};
|
|
19
|
+
const returnObj = {
|
|
20
|
+
customAttributes: customAttributes || {}
|
|
21
|
+
};
|
|
22
|
+
if (typeof returnObj.customAttributes !== 'object' || typeof name !== 'string' || name.length === 0) {
|
|
23
|
+
warn(57);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* getValueFromTiming - Helper function to extract a numeric value from a supplied option.
|
|
29
|
+
* @param {Number|PerformanceMark} [timing] The timing value
|
|
30
|
+
* @param {Number} [d] The default value to return if timing is invalid
|
|
31
|
+
* @returns {Number} The timing value or the default value
|
|
32
|
+
*/
|
|
33
|
+
const getValueFromTiming = (timing, d) => {
|
|
34
|
+
if (timing == null) return d;
|
|
35
|
+
if (typeof timing === 'number') return timing;
|
|
36
|
+
if (timing instanceof PerformanceMark) return timing.startTime;
|
|
37
|
+
return Number.NaN;
|
|
38
|
+
};
|
|
39
|
+
returnObj.start = getValueFromTiming(start, 0);
|
|
40
|
+
returnObj.end = getValueFromTiming(end, n);
|
|
41
|
+
if (Number.isNaN(returnObj.start) || Number.isNaN(returnObj.end)) {
|
|
42
|
+
warn(57);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
returnObj.duration = returnObj.end - returnObj.start;
|
|
46
|
+
if (returnObj.duration < 0) {
|
|
47
|
+
warn(58);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
handle(prefix + MEASURE, [returnObj, name], undefined, FEATURE_NAMES.genericEvents, agent.ee);
|
|
51
|
+
return returnObj;
|
|
52
|
+
}, agent);
|
|
53
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { warn } from '../common/util/console';
|
|
6
|
-
import { ADD_PAGE_ACTION, ADD_RELEASE, ADD_TO_TRACE, FINISHED, INTERACTION, LOG, NOTICE_ERROR, PAUSE_REPLAY, RECORD_CUSTOM_EVENT, RECORD_REPLAY, REGISTER, SET_APPLICATION_VERSION, SET_CURRENT_ROUTE_NAME, SET_CUSTOM_ATTRIBUTE, SET_ERROR_HANDLER, SET_PAGE_VIEW_NAME, SET_USER_ID, START, WRAP_LOGGER } from './api/constants';
|
|
6
|
+
import { ADD_PAGE_ACTION, ADD_RELEASE, ADD_TO_TRACE, FINISHED, INTERACTION, LOG, NOTICE_ERROR, PAUSE_REPLAY, RECORD_CUSTOM_EVENT, RECORD_REPLAY, REGISTER, SET_APPLICATION_VERSION, SET_CURRENT_ROUTE_NAME, SET_CUSTOM_ATTRIBUTE, SET_ERROR_HANDLER, SET_PAGE_VIEW_NAME, SET_USER_ID, START, WRAP_LOGGER, MEASURE } from './api/constants';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @typedef {import('./api/interaction-types').InteractionInstance} InteractionInstance
|
|
@@ -214,4 +214,15 @@ export class ApiBase {
|
|
|
214
214
|
wrapLogger(parent, functionName, options) {
|
|
215
215
|
return this.#callMethod(WRAP_LOGGER, parent, functionName, options);
|
|
216
216
|
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Measures a task that is recorded as a BrowserPerformance event.
|
|
220
|
+
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/measure/}
|
|
221
|
+
* @param {string} name The name of the task
|
|
222
|
+
* @param {object?} options An object used to control the way the measure API operates
|
|
223
|
+
* @returns {{start: number, end: number, duration: number, customAttributes: object}} Measurement details
|
|
224
|
+
*/
|
|
225
|
+
measure(name, options) {
|
|
226
|
+
return this.#callMethod(MEASURE, name, options);
|
|
227
|
+
}
|
|
217
228
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/index.js","../src/cdn/experimental.js","../src/cdn/lite.js","../src/cdn/pro.js","../src/cdn/spa.js","../src/common/aggregate/aggregator.js","../src/common/aggregate/event-aggregator.js","../src/common/config/configurable.js","../src/common/config/info.js","../src/common/config/init-types.js","../src/common/config/init.js","../src/common/config/loader-config.js","../src/common/config/runtime.js","../src/common/constants/agent-constants.js","../src/common/constants/env.cdn.js","../src/common/constants/env.js","../src/common/constants/env.npm.js","../src/common/constants/runtime.js","../src/common/constants/shared-channel.js","../src/common/deny-list/deny-list.js","../src/common/dispatch/global-event.js","../src/common/dom/iframe.js","../src/common/dom/query-selector.js","../src/common/dom/selector-path.js","../src/common/drain/drain.js","../src/common/event-emitter/contextual-ee.js","../src/common/event-emitter/event-context.js","../src/common/event-emitter/handle.js","../src/common/event-emitter/register-handler.js","../src/common/event-listener/event-listener-opts.js","../src/common/harvest/harvester.js","../src/common/harvest/types.js","../src/common/ids/bundle-id.js","../src/common/ids/id.js","../src/common/ids/unique-id.js","../src/common/serialize/bel-serializer.js","../src/common/session/constants.js","../src/common/session/session-entity.js","../src/common/storage/local-storage.js","../src/common/timer/interaction-timer.js","../src/common/timer/timer.js","../src/common/timing/nav-timing.js","../src/common/timing/now.js","../src/common/timing/time-keeper.js","../src/common/unload/eol.js","../src/common/url/canonicalize-url.js","../src/common/url/clean-url.js","../src/common/url/encode.js","../src/common/url/location.js","../src/common/url/parse-url.js","../src/common/url/protocol.js","../src/common/util/console.js","../src/common/util/data-size.js","../src/common/util/event-origin.js","../src/common/util/feature-flags.js","../src/common/util/get-or-set.js","../src/common/util/invoke.js","../src/common/util/obfuscate.js","../src/common/util/stringify.js","../src/common/util/submit-data.js","../src/common/util/target.js","../src/common/util/text.js","../src/common/util/traverse.js","../src/common/util/type-check.js","../src/common/vitals/constants.js","../src/common/vitals/cumulative-layout-shift.js","../src/common/vitals/first-contentful-paint.js","../src/common/vitals/first-paint.js","../src/common/vitals/interaction-to-next-paint.js","../src/common/vitals/largest-contentful-paint.js","../src/common/vitals/time-to-first-byte.js","../src/common/vitals/vital-metric.js","../src/common/window/load.js","../src/common/window/nreum.js","../src/common/window/page-visibility.js","../src/common/wrap/wrap-events.js","../src/common/wrap/wrap-fetch.js","../src/common/wrap/wrap-function.js","../src/common/wrap/wrap-history.js","../src/common/wrap/wrap-jsonp.js","../src/common/wrap/wrap-logger.js","../src/common/wrap/wrap-mutation.js","../src/common/wrap/wrap-promise.js","../src/common/wrap/wrap-timer.js","../src/common/wrap/wrap-websocket.js","../src/common/wrap/wrap-xhr.js","../src/features/ajax/constants.js","../src/features/ajax/index.js","../src/features/ajax/aggregate/gql.js","../src/features/ajax/aggregate/index.js","../src/features/ajax/instrument/distributed-tracing.js","../src/features/ajax/instrument/index.js","../src/features/ajax/instrument/response-size.js","../src/features/generic_events/constants.js","../src/features/generic_events/index.js","../src/features/generic_events/aggregate/index.js","../src/features/generic_events/aggregate/user-actions/aggregated-user-action.js","../src/features/generic_events/aggregate/user-actions/user-actions-aggregator.js","../src/features/generic_events/instrument/index.js","../src/features/jserrors/constants.js","../src/features/jserrors/index.js","../src/features/jserrors/aggregate/canonical-function-name.js","../src/features/jserrors/aggregate/compute-stack-trace.js","../src/features/jserrors/aggregate/format-stack-trace.js","../src/features/jserrors/aggregate/index.js","../src/features/jserrors/aggregate/internal-errors.js","../src/features/jserrors/aggregate/string-hash-code.js","../src/features/jserrors/instrument/index.js","../src/features/jserrors/shared/cast-error.js","../src/features/jserrors/shared/uncaught-error.js","../src/features/logging/constants.js","../src/features/logging/index.js","../src/features/logging/aggregate/index.js","../src/features/logging/instrument/index.js","../src/features/logging/shared/log.js","../src/features/logging/shared/utils.js","../src/features/metrics/constants.js","../src/features/metrics/index.js","../src/features/metrics/aggregate/framework-detection.js","../src/features/metrics/aggregate/index.js","../src/features/metrics/aggregate/websocket-detection.js","../src/features/metrics/instrument/index.js","../src/features/page_action/constants.js","../src/features/page_action/index.js","../src/features/page_action/instrument/index.js","../src/features/page_view_event/constants.js","../src/features/page_view_event/index.js","../src/features/page_view_event/aggregate/index.js","../src/features/page_view_event/aggregate/initialized-features.js","../src/features/page_view_event/instrument/index.js","../src/features/page_view_timing/constants.js","../src/features/page_view_timing/index.js","../src/features/page_view_timing/aggregate/index.js","../src/features/page_view_timing/instrument/index.js","../src/features/session_replay/constants.js","../src/features/session_replay/index.js","../src/features/session_replay/aggregate/index.js","../src/features/session_replay/instrument/index.js","../src/features/session_replay/shared/recorder-events.js","../src/features/session_replay/shared/recorder.js","../src/features/session_replay/shared/stylesheet-evaluator.js","../src/features/session_replay/shared/utils.js","../src/features/session_trace/constants.js","../src/features/session_trace/index.js","../src/features/session_trace/aggregate/index.js","../src/features/session_trace/aggregate/trace/node.js","../src/features/session_trace/aggregate/trace/storage.js","../src/features/session_trace/instrument/index.js","../src/features/soft_navigations/constants.js","../src/features/soft_navigations/index.js","../src/features/soft_navigations/aggregate/ajax-node.js","../src/features/soft_navigations/aggregate/bel-node.js","../src/features/soft_navigations/aggregate/index.js","../src/features/soft_navigations/aggregate/initial-page-load-interaction.js","../src/features/soft_navigations/aggregate/interaction.js","../src/features/soft_navigations/instrument/index.js","../src/features/spa/constants.js","../src/features/spa/index.js","../src/features/spa/aggregate/index.js","../src/features/spa/aggregate/interaction-node.js","../src/features/spa/aggregate/interaction.js","../src/features/spa/aggregate/serializer.js","../src/features/spa/instrument/index.js","../src/features/utils/agent-session.js","../src/features/utils/aggregate-base.js","../src/features/utils/entity-manager.js","../src/features/utils/event-buffer.js","../src/features/utils/event-store-manager.js","../src/features/utils/feature-base.js","../src/features/utils/feature-gates.js","../src/features/utils/instrument-base.js","../src/features/utils/nr1-debugger.js","../src/interfaces/registered-entity.js","../src/loaders/agent-base.js","../src/loaders/agent.js","../src/loaders/api-base.js","../src/loaders/browser-agent.js","../src/loaders/micro-agent-base.js","../src/loaders/micro-agent.js","../src/loaders/api/addPageAction.js","../src/loaders/api/addRelease.js","../src/loaders/api/addToTrace.js","../src/loaders/api/constants.js","../src/loaders/api/finished.js","../src/loaders/api/interaction-types.js","../src/loaders/api/interaction.js","../src/loaders/api/log.js","../src/loaders/api/noticeError.js","../src/loaders/api/pauseReplay.js","../src/loaders/api/recordCustomEvent.js","../src/loaders/api/recordReplay.js","../src/loaders/api/register-api-types.js","../src/loaders/api/register-api.js","../src/loaders/api/register.js","../src/loaders/api/setApplicationVersion.js","../src/loaders/api/setCustomAttribute.js","../src/loaders/api/setErrorHandler.js","../src/loaders/api/setPageViewName.js","../src/loaders/api/setUserId.js","../src/loaders/api/sharedHandlers.js","../src/loaders/api/start.js","../src/loaders/api/topLevelCallers.js","../src/loaders/api/wrapLogger.js","../src/loaders/configure/configure.js","../src/loaders/configure/nonce.js","../src/loaders/configure/public-path.js","../src/loaders/features/enabled-features.js","../src/loaders/features/featureDependencies.js","../src/loaders/features/features.js"],"version":"5.7.3"}
|
|
1
|
+
{"root":["../src/index.js","../src/cdn/experimental.js","../src/cdn/lite.js","../src/cdn/pro.js","../src/cdn/spa.js","../src/common/aggregate/aggregator.js","../src/common/aggregate/event-aggregator.js","../src/common/config/configurable.js","../src/common/config/info.js","../src/common/config/init-types.js","../src/common/config/init.js","../src/common/config/loader-config.js","../src/common/config/runtime.js","../src/common/constants/agent-constants.js","../src/common/constants/env.cdn.js","../src/common/constants/env.js","../src/common/constants/env.npm.js","../src/common/constants/runtime.js","../src/common/constants/shared-channel.js","../src/common/deny-list/deny-list.js","../src/common/dispatch/global-event.js","../src/common/dom/iframe.js","../src/common/dom/query-selector.js","../src/common/dom/selector-path.js","../src/common/drain/drain.js","../src/common/event-emitter/contextual-ee.js","../src/common/event-emitter/event-context.js","../src/common/event-emitter/handle.js","../src/common/event-emitter/register-handler.js","../src/common/event-listener/event-listener-opts.js","../src/common/harvest/harvester.js","../src/common/harvest/types.js","../src/common/ids/bundle-id.js","../src/common/ids/id.js","../src/common/ids/unique-id.js","../src/common/serialize/bel-serializer.js","../src/common/session/constants.js","../src/common/session/session-entity.js","../src/common/storage/local-storage.js","../src/common/timer/interaction-timer.js","../src/common/timer/timer.js","../src/common/timing/nav-timing.js","../src/common/timing/now.js","../src/common/timing/time-keeper.js","../src/common/unload/eol.js","../src/common/url/canonicalize-url.js","../src/common/url/clean-url.js","../src/common/url/encode.js","../src/common/url/location.js","../src/common/url/parse-url.js","../src/common/url/protocol.js","../src/common/util/console.js","../src/common/util/data-size.js","../src/common/util/event-origin.js","../src/common/util/feature-flags.js","../src/common/util/get-or-set.js","../src/common/util/invoke.js","../src/common/util/obfuscate.js","../src/common/util/stringify.js","../src/common/util/submit-data.js","../src/common/util/target.js","../src/common/util/text.js","../src/common/util/traverse.js","../src/common/util/type-check.js","../src/common/vitals/constants.js","../src/common/vitals/cumulative-layout-shift.js","../src/common/vitals/first-contentful-paint.js","../src/common/vitals/first-paint.js","../src/common/vitals/interaction-to-next-paint.js","../src/common/vitals/largest-contentful-paint.js","../src/common/vitals/time-to-first-byte.js","../src/common/vitals/vital-metric.js","../src/common/window/load.js","../src/common/window/nreum.js","../src/common/window/page-visibility.js","../src/common/wrap/wrap-events.js","../src/common/wrap/wrap-fetch.js","../src/common/wrap/wrap-function.js","../src/common/wrap/wrap-history.js","../src/common/wrap/wrap-jsonp.js","../src/common/wrap/wrap-logger.js","../src/common/wrap/wrap-mutation.js","../src/common/wrap/wrap-promise.js","../src/common/wrap/wrap-timer.js","../src/common/wrap/wrap-websocket.js","../src/common/wrap/wrap-xhr.js","../src/features/ajax/constants.js","../src/features/ajax/index.js","../src/features/ajax/aggregate/gql.js","../src/features/ajax/aggregate/index.js","../src/features/ajax/instrument/distributed-tracing.js","../src/features/ajax/instrument/index.js","../src/features/ajax/instrument/response-size.js","../src/features/generic_events/constants.js","../src/features/generic_events/index.js","../src/features/generic_events/aggregate/index.js","../src/features/generic_events/aggregate/user-actions/aggregated-user-action.js","../src/features/generic_events/aggregate/user-actions/user-actions-aggregator.js","../src/features/generic_events/instrument/index.js","../src/features/jserrors/constants.js","../src/features/jserrors/index.js","../src/features/jserrors/aggregate/canonical-function-name.js","../src/features/jserrors/aggregate/compute-stack-trace.js","../src/features/jserrors/aggregate/format-stack-trace.js","../src/features/jserrors/aggregate/index.js","../src/features/jserrors/aggregate/internal-errors.js","../src/features/jserrors/aggregate/string-hash-code.js","../src/features/jserrors/instrument/index.js","../src/features/jserrors/shared/cast-error.js","../src/features/jserrors/shared/uncaught-error.js","../src/features/logging/constants.js","../src/features/logging/index.js","../src/features/logging/aggregate/index.js","../src/features/logging/instrument/index.js","../src/features/logging/shared/log.js","../src/features/logging/shared/utils.js","../src/features/metrics/constants.js","../src/features/metrics/index.js","../src/features/metrics/aggregate/framework-detection.js","../src/features/metrics/aggregate/index.js","../src/features/metrics/aggregate/websocket-detection.js","../src/features/metrics/instrument/index.js","../src/features/page_action/constants.js","../src/features/page_action/index.js","../src/features/page_action/instrument/index.js","../src/features/page_view_event/constants.js","../src/features/page_view_event/index.js","../src/features/page_view_event/aggregate/index.js","../src/features/page_view_event/aggregate/initialized-features.js","../src/features/page_view_event/instrument/index.js","../src/features/page_view_timing/constants.js","../src/features/page_view_timing/index.js","../src/features/page_view_timing/aggregate/index.js","../src/features/page_view_timing/instrument/index.js","../src/features/session_replay/constants.js","../src/features/session_replay/index.js","../src/features/session_replay/aggregate/index.js","../src/features/session_replay/instrument/index.js","../src/features/session_replay/shared/recorder-events.js","../src/features/session_replay/shared/recorder.js","../src/features/session_replay/shared/stylesheet-evaluator.js","../src/features/session_replay/shared/utils.js","../src/features/session_trace/constants.js","../src/features/session_trace/index.js","../src/features/session_trace/aggregate/index.js","../src/features/session_trace/aggregate/trace/node.js","../src/features/session_trace/aggregate/trace/storage.js","../src/features/session_trace/instrument/index.js","../src/features/soft_navigations/constants.js","../src/features/soft_navigations/index.js","../src/features/soft_navigations/aggregate/ajax-node.js","../src/features/soft_navigations/aggregate/bel-node.js","../src/features/soft_navigations/aggregate/index.js","../src/features/soft_navigations/aggregate/initial-page-load-interaction.js","../src/features/soft_navigations/aggregate/interaction.js","../src/features/soft_navigations/instrument/index.js","../src/features/spa/constants.js","../src/features/spa/index.js","../src/features/spa/aggregate/index.js","../src/features/spa/aggregate/interaction-node.js","../src/features/spa/aggregate/interaction.js","../src/features/spa/aggregate/serializer.js","../src/features/spa/instrument/index.js","../src/features/utils/agent-session.js","../src/features/utils/aggregate-base.js","../src/features/utils/entity-manager.js","../src/features/utils/event-buffer.js","../src/features/utils/event-store-manager.js","../src/features/utils/feature-base.js","../src/features/utils/feature-gates.js","../src/features/utils/instrument-base.js","../src/features/utils/nr1-debugger.js","../src/interfaces/registered-entity.js","../src/loaders/agent-base.js","../src/loaders/agent.js","../src/loaders/api-base.js","../src/loaders/browser-agent.js","../src/loaders/micro-agent-base.js","../src/loaders/micro-agent.js","../src/loaders/api/addPageAction.js","../src/loaders/api/addRelease.js","../src/loaders/api/addToTrace.js","../src/loaders/api/constants.js","../src/loaders/api/finished.js","../src/loaders/api/interaction-types.js","../src/loaders/api/interaction.js","../src/loaders/api/log.js","../src/loaders/api/measure.js","../src/loaders/api/noticeError.js","../src/loaders/api/pauseReplay.js","../src/loaders/api/recordCustomEvent.js","../src/loaders/api/recordReplay.js","../src/loaders/api/register-api-types.js","../src/loaders/api/register-api.js","../src/loaders/api/register.js","../src/loaders/api/setApplicationVersion.js","../src/loaders/api/setCustomAttribute.js","../src/loaders/api/setErrorHandler.js","../src/loaders/api/setPageViewName.js","../src/loaders/api/setUserId.js","../src/loaders/api/sharedHandlers.js","../src/loaders/api/start.js","../src/loaders/api/topLevelCallers.js","../src/loaders/api/wrapLogger.js","../src/loaders/configure/configure.js","../src/loaders/configure/nonce.js","../src/loaders/configure/public-path.js","../src/loaders/features/enabled-features.js","../src/loaders/features/featureDependencies.js","../src/loaders/features/features.js"],"version":"5.7.3"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harvester.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/harvester.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"harvester.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/harvester.js"],"names":[],"mappings":"AAuBA;IAIE,2BAUC;IAZD,6BAA0B;IAGxB,cAAwB;IAW1B,wCASC;IAED;;;;;OAKG;IACH,iCAJW,MAAM,cACN,MAAM,GACJ,OAAO,CA+CnB;;CACF;8BAGY,OAAO,YAAY,EAAE,eAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-entity.d.ts","sourceRoot":"","sources":["../../../../src/common/session/session-entity.js"],"names":[],"mappings":"AAqCA;IACE;;;;;OAKG;IACH,uBA+BC;IAzBC,qBAAsC;IACtC,aAAsB;IACtB,UAAe;IAGf,SAAc;IAEd,QAAiC;IAoBnC;;;;;aA6EC;IApEC,8BAA0B;IAC1B,+BAA4B;IAe1B,gCAOqC;IAUrC,4CAkBsC;IAexC,iCAAuB;IAKzB,wBAEC;IAED,sBAEC;IAED;;;OAGG;IACH,QAFa,MAAM,CA6BlB;IAED;;;;;;OAMG;IACH,YAHW,MAAM,GACJ,MAAM,CAkBlB;IAED,
|
|
1
|
+
{"version":3,"file":"session-entity.d.ts","sourceRoot":"","sources":["../../../../src/common/session/session-entity.js"],"names":[],"mappings":"AAqCA;IACE;;;;;OAKG;IACH,uBA+BC;IAzBC,qBAAsC;IACtC,aAAsB;IACtB,UAAe;IAGf,SAAc;IAEd,QAAiC;IAoBnC;;;;;aA6EC;IApEC,8BAA0B;IAC1B,+BAA4B;IAe1B,gCAOqC;IAUrC,4CAkBsC;IAexC,iCAAuB;IAKzB,wBAEC;IAED,sBAEC;IAED;;;OAGG;IACH,QAFa,MAAM,CA6BlB;IAED;;;;;;OAMG;IACH,YAHW,MAAM,GACJ,MAAM,CAkBlB;IAED,gBA2BC;IAED;;OAEG;IACH,gBAIC;IAED;;;OAGG;IACH,qBAHW,MAAM,GACJ,OAAO,CAInB;IAED;;;OAGG;IACH,gBAHW,MAAM,GACJ,OAAO,CAKnB;IAED,yDAUC;IAED,6DAIC;IAED;;;OAGG;IACH,6BAHW,MAAM,GACJ,MAAM,CAIlB;IAED,gDAaC;IAHG,YAAuD;CAI5D;sBAtTqB,gBAAgB;iCAGL,4BAA4B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../../../src/common/util/console.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../../../src/common/util/console.js"],"names":[],"mappings":"AASA;;;;;GAKG;AACH,4CAHW,GAAC,QAiBX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/generic_events/aggregate/index.js"],"names":[],"mappings":"AAkBA;IACE,2BAAiC;IACjC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/generic_events/aggregate/index.js"],"names":[],"mappings":"AAkBA;IACE,2BAAiC;IACjC,2BA4NC;IA1NC,yBAA4B;IAC5B,gCAAkG;IAwC9F,4CAAuD;IAoL7D;;;;;;;;;;;;OAYG;IACH,eAJW,MAAM,YAAC,qBACP,MAAM,YAAC,QA0CjB;IAED,qCAEC;IAED;;;MAEC;IAED,gCAEC;IAED,mCASC;CACF;8BAvT6B,4BAA4B;sCAMpB,wCAAwC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/generic_events/instrument/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/generic_events/instrument/index.js"],"names":[],"mappings":"AAiBA;IACE,2BAAiC;IACjC,2BA2CC;CACF;AAED,8CAAuC;+BAnDR,6BAA6B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/aggregate/index.js"],"names":[],"mappings":"AAyBA;IACE,2BAAiC;IAIjC,sCAsFC;IAzFD,aAAe;IAKb,iFAAiF;IACjF,qBAAwB;IAGxB,2CAA2C;IAC3C,sDAAwB;IACxB,6CAA6C;IAC7C,gDAAmB;IAEnB,0BAA0B;IAC1B,kBAAqB;IACrB,6CAA6C;IAC7C,gBAA2B;IAE3B,cAA8B;IAC9B,kBAA+C;IAG/C,kCAAqG;IAoEvG,0BAEC;IAED,0BAMC;IAED,qBAUC;IAED;;;;;OAKG;IACH,4BAJW,OAAO,iBACP,OAAO,GACL,IAAI,CAuDhB;IAED,2BASC;IAED;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/aggregate/index.js"],"names":[],"mappings":"AAyBA;IACE,2BAAiC;IAIjC,sCAsFC;IAzFD,aAAe;IAKb,iFAAiF;IACjF,qBAAwB;IAGxB,2CAA2C;IAC3C,sDAAwB;IACxB,6CAA6C;IAC7C,gDAAmB;IAEnB,0BAA0B;IAC1B,kBAAqB;IACrB,6CAA6C;IAC7C,gBAA2B;IAE3B,cAA8B;IAC9B,kBAA+C;IAG/C,kCAAqG;IAoEvG,0BAEC;IAED,0BAMC;IAED,qBAUC;IAED;;;;;OAKG;IACH,4BAJW,OAAO,iBACP,OAAO,GACL,IAAI,CAuDhB;IAED,2BASC;IAED;;;oBAuDC;IAED,sCAIC;IAED;;;;;;;;;;MAuEC;IAED,sCAKC;IAED;;;;OAIG;IACH,mCAKC;IAED,yDAAyD;IACzD,+CASC;IAED,yCAIC;CACF;8BAxX6B,4BAA4B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder.js"],"names":[],"mappings":"AAmBA;IAYE,yBAiBC;IAhBC,sDAAsD;IACtD,YAAoB;IACpB,0FAA0F;IAC1F,eAAyE;IAKzE,6DAA6D;IAC7D,oCAAuC;IACvC,+IAA+I;IAC/I,yBAA4B;IAC5B,kIAAkI;IAClI,kBAAqB;IACrB,uIAAuI;IACvI,0BAA+E;IAGjF;;;;;;;;;MAmBC;IAED,mFAAmF;IACnF,oBAKC;IAED,qDAAqD;IACrD,uBAiCC;IAED;;;;;OAKG;IACH,aAHW,GAAC,cACD,GAAC,QAiCX;IAED,0HAA0H;IAC1H,
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder.js"],"names":[],"mappings":"AAmBA;IAYE,yBAiBC;IAhBC,sDAAsD;IACtD,YAAoB;IACpB,0FAA0F;IAC1F,eAAyE;IAKzE,6DAA6D;IAC7D,oCAAuC;IACvC,+IAA+I;IAC/I,yBAA4B;IAC5B,kIAAkI;IAClI,kBAAqB;IACrB,uIAAuI;IACvI,0BAA+E;IAGjF;;;;;;;;;MAmBC;IAED,mFAAmF;IACnF,oBAKC;IAED,qDAAqD;IACrD,uBAiCC;IAED;;;;;OAKG;IACH,aAHW,GAAC,cACD,GAAC,QAiCX;IAED,0HAA0H;IAC1H,yCA+CC;IAED,0HAA0H;IAC1H,yBAOC;IAED,wBAEC;IAED,gCAAgC;IAChC,uCAGC;IAED;;;SAGK;IACL,oCAGC;;CACF;+BAjO8B,mBAAmB"}
|
|
@@ -35,7 +35,7 @@ export class Aggregate extends AggregateBase {
|
|
|
35
35
|
/** Switch from "off" or "error" to full mode (if entitled) */
|
|
36
36
|
switchToFull(): void;
|
|
37
37
|
/** Stop running for the remainder of the page lifecycle */
|
|
38
|
-
abort(): void;
|
|
38
|
+
abort(code: any): void;
|
|
39
39
|
}
|
|
40
40
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
41
41
|
import { TraceStorage } from './trace/storage';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_trace/aggregate/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_trace/aggregate/index.js"],"names":[],"mappings":"AAkBA;IACE,2BAAiC;IAEjC,2BAgBC;IAZC,0GAA0G;IAC1G,cAAyB;IACzB,mIAAmI;IACnI,uBAA0B;IAC1B,0CAA0C;IAC1C,oBAAuB;IACvB,wIAAwI;IACxI,qBAAoC;IAOtC,gLAAgL;IAChL,mEA8DC;IAxDG,iCAAuB;IACvB,yJAAyJ;IACzJ,UAAsC;IACtC,eAA2D;IAyBD,UAAgE;IA8B9H,qCAUC;IAED;;2BAIC;IAED;;;;;;;;;;;MA6CC;IAED,8DAA8D;IAC9D,qBAUC;IAED,2DAA2D;IAC3D,uBAMC;CACF;8BAxL6B,4BAA4B;6BAC7B,iBAAiB"}
|
|
@@ -7,7 +7,6 @@ export class TraceStorage {
|
|
|
7
7
|
latestTimeStamp: number;
|
|
8
8
|
prevStoredEvents: Set<any>;
|
|
9
9
|
parent: any;
|
|
10
|
-
isAfterSessionExpiry(entryTimestamp: any): any;
|
|
11
10
|
/** Central function called by all the other store__ & addToTrace API to append a trace node. */
|
|
12
11
|
storeSTN(stn: any): void;
|
|
13
12
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../../../../src/features/session_trace/aggregate/trace/storage.js"],"names":[],"mappings":"AA8BA,+HAA+H;AAC/H;IAQE,yBAEC;IATD,kBAAa;IACb,UAAU;IACV,0BAA4B;IAC5B,wBAAmB;IACnB,2BAA4B;IAI1B,YAAoB;IAGtB
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../../../../src/features/session_trace/aggregate/trace/storage.js"],"names":[],"mappings":"AA8BA,+HAA+H;AAC/H;IAQE,yBAEC;IATD,kBAAa;IACb,UAAU;IACV,0BAA4B;IAC5B,wBAAmB;IACnB,2BAA4B;IAI1B,YAAoB;IAGtB,gGAAgG;IAChG,yBAcC;IAED;;;;OAIG;IACH,2BAHW,MAAM,GACJ,MAAM,CAsBlB;IAED,oEAAoE;IACpE;;;;MAgBC;IAED,mEA6BC;IAED,oDAEC;IAED,mEAuBC;IAGD,uEAcC;IAED,oDAKC;IAED,wBAwBC;IAGD,gDAEC;IAID,qCAaC;IAGD,qEAGC;IAGD,mEAGC;IAID,mBAEC;IAED,aAEC;IAED;;;;;;;QAEC;IAED,cAMC;IAED,mBAEC;IAED,kBAEC;;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/constants.js"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAsB,MAAM,CAAA;AAC5B,+BAAwC;AAExC,8BAA+B,eAAe,CAAA;AAC9C,2BAA4B,YAAY,CAAA;AACxC,0BAA2B,YAAY,CAAA;AACvC,uBAAwB,UAAU,CAAA;AAClC,0BAA2B,aAAa,CAAA;AACxC,kBAAmB,KAAK,CAAA;AACxB,2BAA4B,aAAa,CAAA;AACzC,2BAA4B,aAAa,CAAA;AACzC,kCAAmC,mBAAmB,CAAA;AACtD,4BAA6B,cAAc,CAAA;AAC3C,uBAAwB,UAAU,CAAA;AAClC,sCAAuC,uBAAuB,CAAA;AAC9D,qCAAsC,qBAAqB,CAAA;AAC3D,mCAAoC,oBAAoB,CAAA;AACxD,gCAAiC,iBAAiB,CAAA;AAClD,iCAAkC,iBAAiB,CAAA;AACnD,0BAA2B,WAAW,CAAA;AACtC,oBAAqB,OAAO,CAAA;AAC5B,0BAA2B,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/constants.js"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAsB,MAAM,CAAA;AAC5B,+BAAwC;AAExC,8BAA+B,eAAe,CAAA;AAC9C,2BAA4B,YAAY,CAAA;AACxC,0BAA2B,YAAY,CAAA;AACvC,uBAAwB,UAAU,CAAA;AAClC,0BAA2B,aAAa,CAAA;AACxC,kBAAmB,KAAK,CAAA;AACxB,2BAA4B,aAAa,CAAA;AACzC,2BAA4B,aAAa,CAAA;AACzC,kCAAmC,mBAAmB,CAAA;AACtD,4BAA6B,cAAc,CAAA;AAC3C,uBAAwB,UAAU,CAAA;AAClC,sCAAuC,uBAAuB,CAAA;AAC9D,qCAAsC,qBAAqB,CAAA;AAC3D,mCAAoC,oBAAoB,CAAA;AACxD,gCAAiC,iBAAiB,CAAA;AAClD,iCAAkC,iBAAiB,CAAA;AACnD,0BAA2B,WAAW,CAAA;AACtC,oBAAqB,OAAO,CAAA;AAC5B,0BAA2B,YAAY,CAAA;AACvC,sBAAuB,SAAS,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/measure.js"],"names":[],"mappings":"AAWA,kDAyCC"}
|
|
@@ -163,6 +163,19 @@ export class ApiBase {
|
|
|
163
163
|
customAttributes?: object;
|
|
164
164
|
level?: "ERROR" | "TRACE" | "DEBUG" | "INFO" | "WARN";
|
|
165
165
|
}): any;
|
|
166
|
+
/**
|
|
167
|
+
* Measures a task that is recorded as a BrowserPerformance event.
|
|
168
|
+
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/measure/}
|
|
169
|
+
* @param {string} name The name of the task
|
|
170
|
+
* @param {object?} options An object used to control the way the measure API operates
|
|
171
|
+
* @returns {{start: number, end: number, duration: number, customAttributes: object}} Measurement details
|
|
172
|
+
*/
|
|
173
|
+
measure(name: string, options: object | null): {
|
|
174
|
+
start: number;
|
|
175
|
+
end: number;
|
|
176
|
+
duration: number;
|
|
177
|
+
customAttributes: object;
|
|
178
|
+
};
|
|
166
179
|
#private;
|
|
167
180
|
}
|
|
168
181
|
export type InteractionInstance = import("./api/interaction-types").InteractionInstance;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-base.d.ts","sourceRoot":"","sources":["../../../src/loaders/api-base.js"],"names":[],"mappings":"AAOA;;GAEG;AACH;IAQE;;;;;OAKG;IACH,oBAHW,MAAM,eACN,MAAM,OAIhB;IAED;;;;;;;;;;;OAWG;IACH,iBALG;QAAuB,UAAU,EAAzB,MAAM;QACS,aAAa,EAA5B,MAAM;QACU,UAAU,GAA1B,MAAM,YAAC;KACf,GAAU,MAAM,CAIlB;IAED;;;;;OAKG;IACH,6BAHW,MAAM,eACN,MAAM,OAIhB;IAED;;;;;OAKG;IACH,sBAHW,MAAM,SACN,MAAM,OAIhB;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,SACN,MAAM,GAAC,MAAM,GAAC,OAAO,GAAC,IAAI,YAC1B,OAAO,OAIjB;IAED;;;;;OAKG;IACH,mBAHW,KAAK,GAAC,MAAM,qBACZ,MAAM,OAIhB;IAED;;;;OAIG;IACH,iBAFW,MAAM,GAAC,IAAI,OAIrB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,GAAC,IAAI,OAMrB;IAED;;;;OAIG;IACH,0BAFW,CAAC,KAAK,EAAE,KAAK,GAAC,MAAM,KAAK,OAAO,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,OAI9D;IAED;;;;;OAKG;IACH,iBAHW,MAAM,MACN,MAAM,OAIhB;IAED;;;;;MAKE;IACF,aAHW,MAAM,YACN;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAC,OAAO,GAAC,OAAO,GAAC,MAAM,GAAC,MAAM,CAAA;KAAC,OAIpF;IAED;;;OAGG;IACH,aAEC;IAED;;;;OAIG;IACH,qBAFW,MAAM,OAIhB;IAED;;;;OAIG;IACH,oBAEC;IAED;;;;;OAKG;IACH,mBAEC;IAED;;;;;;;;;;OAUG;IACH,6BARW;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAC,OAUrF;IAED;;;;;OAKG;IACH,0BAHW,MAAM,OAKhB;IAED;;;;;;MAME;IACF,eAJa,mBAAmB,CAM/B;IAED;;;;;;MAME;IACF,mBAJW,MAAM,gBACN,MAAM,YACN;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAC,OAAO,GAAC,OAAO,GAAC,MAAM,GAAC,MAAM,CAAA;KAAC,OAIpF;;CACF;
|
|
1
|
+
{"version":3,"file":"api-base.d.ts","sourceRoot":"","sources":["../../../src/loaders/api-base.js"],"names":[],"mappings":"AAOA;;GAEG;AACH;IAQE;;;;;OAKG;IACH,oBAHW,MAAM,eACN,MAAM,OAIhB;IAED;;;;;;;;;;;OAWG;IACH,iBALG;QAAuB,UAAU,EAAzB,MAAM;QACS,aAAa,EAA5B,MAAM;QACU,UAAU,GAA1B,MAAM,YAAC;KACf,GAAU,MAAM,CAIlB;IAED;;;;;OAKG;IACH,6BAHW,MAAM,eACN,MAAM,OAIhB;IAED;;;;;OAKG;IACH,sBAHW,MAAM,SACN,MAAM,OAIhB;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,SACN,MAAM,GAAC,MAAM,GAAC,OAAO,GAAC,IAAI,YAC1B,OAAO,OAIjB;IAED;;;;;OAKG;IACH,mBAHW,KAAK,GAAC,MAAM,qBACZ,MAAM,OAIhB;IAED;;;;OAIG;IACH,iBAFW,MAAM,GAAC,IAAI,OAIrB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,GAAC,IAAI,OAMrB;IAED;;;;OAIG;IACH,0BAFW,CAAC,KAAK,EAAE,KAAK,GAAC,MAAM,KAAK,OAAO,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,OAI9D;IAED;;;;;OAKG;IACH,iBAHW,MAAM,MACN,MAAM,OAIhB;IAED;;;;;MAKE;IACF,aAHW,MAAM,YACN;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAC,OAAO,GAAC,OAAO,GAAC,MAAM,GAAC,MAAM,CAAA;KAAC,OAIpF;IAED;;;OAGG;IACH,aAEC;IAED;;;;OAIG;IACH,qBAFW,MAAM,OAIhB;IAED;;;;OAIG;IACH,oBAEC;IAED;;;;;OAKG;IACH,mBAEC;IAED;;;;;;;;;;OAUG;IACH,6BARW;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAC,OAUrF;IAED;;;;;OAKG;IACH,0BAHW,MAAM,OAKhB;IAED;;;;;;MAME;IACF,eAJa,mBAAmB,CAM/B;IAED;;;;;;MAME;IACF,mBAJW,MAAM,gBACN,MAAM,YACN;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAC,OAAO,GAAC,OAAO,GAAC,MAAM,GAAC,MAAM,CAAA;KAAC,OAIpF;IAED;;;;;;OAMG;IACH,cAJW,MAAM,WACN,MAAM,OAAC,GACL;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAC,CAIpF;;CACF;kCA5NY,OAAO,yBAAyB,EAAE,mBAAmB"}
|
package/package.json
CHANGED
|
@@ -8,7 +8,6 @@ import { VERSION } from '../constants/env'
|
|
|
8
8
|
import { globalScope, isWorkerScope } from '../constants/runtime'
|
|
9
9
|
import { handle } from '../event-emitter/handle'
|
|
10
10
|
import { eventListenerOpts } from '../event-listener/event-listener-opts'
|
|
11
|
-
import { SESSION_EVENTS } from '../session/constants'
|
|
12
11
|
import { now } from '../timing/now'
|
|
13
12
|
import { subscribeToEOL } from '../unload/eol'
|
|
14
13
|
import { cleanURL } from '../url/clean-url'
|
|
@@ -36,10 +35,6 @@ export class Harvester {
|
|
|
36
35
|
this.initializedAggregates.forEach(aggregateInst => this.triggerHarvestFor(aggregateInst, { isFinalHarvest: true }))
|
|
37
36
|
/* This callback should run in bubble phase, so that that CWV api, like "onLCP", is called before the final harvest so that emitted timings are part of last outgoing. */
|
|
38
37
|
}, false)
|
|
39
|
-
|
|
40
|
-
/* Flush all buffered data if session resets and give up retries. This should be synchronous to ensure that the correct `session` value is sent.
|
|
41
|
-
Since session-reset generates a new session ID and the ID is grabbed at send-time, any delays or retries would cause the payload to be sent under the wrong session ID. */
|
|
42
|
-
agentRef.ee.on(SESSION_EVENTS.RESET, () => this.initializedAggregates.forEach(aggregateInst => this.triggerHarvestFor(aggregateInst, { forceNoRetry: true })))
|
|
43
38
|
}
|
|
44
39
|
|
|
45
40
|
startTimer (harvestInterval = this.agentRef.init.harvest.interval) {
|
|
@@ -227,7 +227,10 @@ export class SessionEntity {
|
|
|
227
227
|
// * stop recording (stn and sr)...
|
|
228
228
|
// * delete the session and start over
|
|
229
229
|
try {
|
|
230
|
-
if (this.initialized)
|
|
230
|
+
if (this.initialized) {
|
|
231
|
+
this.ee.emit(SESSION_EVENTS.RESET)
|
|
232
|
+
this.state.numOfResets++
|
|
233
|
+
}
|
|
231
234
|
this.storage.remove(this.lookupKey)
|
|
232
235
|
this.inactiveTimer?.abort?.()
|
|
233
236
|
this.expiresTimer?.clear?.()
|
|
@@ -239,7 +242,7 @@ export class SessionEntity {
|
|
|
239
242
|
storage: this.storage,
|
|
240
243
|
expiresMs: this.expiresMs,
|
|
241
244
|
inactiveMs: this.inactiveMs,
|
|
242
|
-
numOfResets:
|
|
245
|
+
numOfResets: this.state.numOfResets
|
|
243
246
|
})
|
|
244
247
|
return this.read()
|
|
245
248
|
} catch (e) {
|
|
@@ -256,10 +259,6 @@ export class SessionEntity {
|
|
|
256
259
|
this.write({ ...existingData, inactiveAt: this.getFutureTimestamp(this.inactiveMs) })
|
|
257
260
|
}
|
|
258
261
|
|
|
259
|
-
isAfterSessionExpiry (timestamp) {
|
|
260
|
-
return this.state.numOfResets > 0 || (typeof timestamp === 'number' && typeof this.state.expiresAt === 'number' && timestamp >= this.state.expiresAt)
|
|
261
|
-
}
|
|
262
|
-
|
|
263
262
|
/**
|
|
264
263
|
* @param {number} timestamp
|
|
265
264
|
* @returns {boolean}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { dispatchGlobalEvent } from '../dispatch/global-event'
|
|
7
|
+
|
|
6
8
|
/* eslint no-console: ["error", { allow: ["debug"] }] */
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -14,4 +16,15 @@
|
|
|
14
16
|
export function warn (code, secondary) {
|
|
15
17
|
if (typeof console.debug !== 'function') return
|
|
16
18
|
console.debug(`New Relic Warning: https://github.com/newrelic/newrelic-browser-agent/blob/main/docs/warning-codes.md#${code}`, secondary)
|
|
19
|
+
dispatchGlobalEvent({
|
|
20
|
+
agentIdentifier: null,
|
|
21
|
+
drained: null,
|
|
22
|
+
type: 'data',
|
|
23
|
+
name: 'warn',
|
|
24
|
+
feature: 'warn',
|
|
25
|
+
data: {
|
|
26
|
+
code,
|
|
27
|
+
secondary
|
|
28
|
+
}
|
|
29
|
+
})
|
|
17
30
|
}
|
|
@@ -220,6 +220,21 @@ export class Aggregate extends AggregateBase {
|
|
|
220
220
|
}, this.featureName, this.ee)
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
registerHandler('api-measure', (args, n) => {
|
|
224
|
+
const { start, duration, customAttributes } = args
|
|
225
|
+
|
|
226
|
+
const event = {
|
|
227
|
+
...customAttributes,
|
|
228
|
+
eventType: 'BrowserPerformance',
|
|
229
|
+
timestamp: Math.floor(agentRef.runtime.timeKeeper.correctRelativeTimestamp(start)),
|
|
230
|
+
entryName: n,
|
|
231
|
+
entryDuration: duration,
|
|
232
|
+
entryType: 'measure'
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
this.addEvent(event)
|
|
236
|
+
}, this.featureName, this.ee)
|
|
237
|
+
|
|
223
238
|
agentRef.runtime.harvester.triggerHarvestFor(this)
|
|
224
239
|
this.drain()
|
|
225
240
|
})
|
|
@@ -11,6 +11,7 @@ import { setupAddPageActionAPI } from '../../../loaders/api/addPageAction'
|
|
|
11
11
|
import { setupFinishedAPI } from '../../../loaders/api/finished'
|
|
12
12
|
import { setupRecordCustomEventAPI } from '../../../loaders/api/recordCustomEvent'
|
|
13
13
|
import { setupRegisterAPI } from '../../../loaders/api/register'
|
|
14
|
+
import { setupMeasureAPI } from '../../../loaders/api/measure'
|
|
14
15
|
import { InstrumentBase } from '../../utils/instrument-base'
|
|
15
16
|
import { FEATURE_NAME, OBSERVED_EVENTS, OBSERVED_WINDOW_EVENTS } from '../constants'
|
|
16
17
|
|
|
@@ -32,6 +33,7 @@ export class Instrument extends InstrumentBase {
|
|
|
32
33
|
setupRecordCustomEventAPI(agentRef)
|
|
33
34
|
setupFinishedAPI(agentRef)
|
|
34
35
|
setupRegisterAPI(agentRef)
|
|
36
|
+
setupMeasureAPI(agentRef)
|
|
35
37
|
|
|
36
38
|
if (isBrowserScope) {
|
|
37
39
|
if (agentRef.init.user_actions.enabled) {
|
|
@@ -262,6 +262,10 @@ export class Aggregate extends AggregateBase {
|
|
|
262
262
|
if (recorderEvents.type === 'preloaded') this.agentRef.runtime.harvester.triggerHarvestFor(this)
|
|
263
263
|
payloadOutput.payload = payload
|
|
264
264
|
|
|
265
|
+
if (!this.agentRef.runtime.session.state.traceHarvestStarted) {
|
|
266
|
+
warn(59, JSON.stringify(this.agentRef.runtime.session.state))
|
|
267
|
+
}
|
|
268
|
+
|
|
265
269
|
return [payloadOutput]
|
|
266
270
|
}
|
|
267
271
|
|
|
@@ -155,10 +155,6 @@ export class Recorder {
|
|
|
155
155
|
/** Store a payload in the buffer (this.#events). This should be the callback to the recording lib noticing a mutation */
|
|
156
156
|
store (event, isCheckout) {
|
|
157
157
|
if (!event) return
|
|
158
|
-
if (this.parent.agentRef.runtime.session?.isAfterSessionExpiry(event.timestamp)) {
|
|
159
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['Session/Expired/SessionReplay/Seen'], undefined, FEATURE_NAMES.metrics, this.ee)
|
|
160
|
-
return
|
|
161
|
-
}
|
|
162
158
|
|
|
163
159
|
if (!(this.parent instanceof AggregateBase) && this.#preloaded.length) this.currentBufferTarget = this.#preloaded[this.#preloaded.length - 1]
|
|
164
160
|
else this.currentBufferTarget = this.#events
|
|
@@ -11,6 +11,7 @@ import { globalScope } from '../../../common/constants/runtime'
|
|
|
11
11
|
import { MODE, SESSION_EVENTS } from '../../../common/session/constants'
|
|
12
12
|
import { applyFnToProps } from '../../../common/util/traverse'
|
|
13
13
|
import { cleanURL } from '../../../common/url/clean-url'
|
|
14
|
+
import { warn } from '../../../common/util/console'
|
|
14
15
|
|
|
15
16
|
const ERROR_MODE_SECONDS_WINDOW = 30 * 1000 // sliding window of nodes to track when simply monitoring (but not harvesting) in error mode
|
|
16
17
|
/** Reserved room for query param attrs */
|
|
@@ -97,10 +98,12 @@ export class Aggregate extends AggregateBase {
|
|
|
97
98
|
}
|
|
98
99
|
this.agentRef.runtime.session.write({ sessionTraceMode: this.mode })
|
|
99
100
|
this.drain()
|
|
101
|
+
/** try to harvest immediately. This will not send if the trace is not running in FULL mode due to the pre-harvest checks. */
|
|
102
|
+
this.agentRef.runtime.harvester.triggerHarvestFor(this)
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
preHarvestChecks () {
|
|
103
|
-
if (this.mode !== MODE.FULL) return // only allow harvest if running in full mode
|
|
106
|
+
if (this.blocked || this.mode !== MODE.FULL) return // only allow harvest if running in full mode
|
|
104
107
|
if (!this.timeKeeper?.ready) return // this should likely never happen, but just to be safe, we should never harvest if we cant correct time
|
|
105
108
|
if (!this.agentRef.runtime.session) return // session entity is required for trace to run and continue running
|
|
106
109
|
if (this.sessionId !== this.agentRef.runtime.session.state.value || this.ptid !== this.agentRef.runtime.ptid) {
|
|
@@ -178,7 +181,8 @@ export class Aggregate extends AggregateBase {
|
|
|
178
181
|
}
|
|
179
182
|
|
|
180
183
|
/** Stop running for the remainder of the page lifecycle */
|
|
181
|
-
abort () {
|
|
184
|
+
abort (code) {
|
|
185
|
+
warn(60, code)
|
|
182
186
|
this.blocked = true
|
|
183
187
|
this.mode = MODE.OFF
|
|
184
188
|
this.agentRef.runtime.session.write({ sessionTraceMode: this.mode })
|
|
@@ -41,10 +41,6 @@ export class TraceStorage {
|
|
|
41
41
|
this.parent = parent
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
isAfterSessionExpiry (entryTimestamp) {
|
|
45
|
-
return this.parent.agentRef.runtime?.session?.isAfterSessionExpiry((this.parent.timeKeeper?.ready && this.parent.timeKeeper.convertRelativeTimestamp(entryTimestamp)) ?? undefined)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
44
|
/** Central function called by all the other store__ & addToTrace API to append a trace node. */
|
|
49
45
|
storeSTN (stn) {
|
|
50
46
|
if (this.parent.blocked) return
|
|
@@ -53,10 +49,6 @@ export class TraceStorage {
|
|
|
53
49
|
const openedSpace = this.trimSTNs(ERROR_MODE_SECONDS_WINDOW) // but maybe we could make some space by discarding irrelevant nodes if we're in sessioned Error mode
|
|
54
50
|
if (openedSpace === 0) return
|
|
55
51
|
}
|
|
56
|
-
if (this.isAfterSessionExpiry(stn.s)) {
|
|
57
|
-
this.parent.reportSupportabilityMetric('Session/Expired/SessionTrace/Seen')
|
|
58
|
-
return
|
|
59
|
-
}
|
|
60
52
|
|
|
61
53
|
if (this.trace[stn.n]) this.trace[stn.n].push(stn)
|
|
62
54
|
else this.trace[stn.n] = [stn]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { handle } from '../../common/event-emitter/handle'
|
|
6
|
+
import { now } from '../../common/timing/now'
|
|
7
|
+
import { warn } from '../../common/util/console'
|
|
8
|
+
import { FEATURE_NAMES } from '../features/features'
|
|
9
|
+
import { prefix, MEASURE } from './constants'
|
|
10
|
+
import { setupAPI } from './sharedHandlers'
|
|
11
|
+
|
|
12
|
+
export function setupMeasureAPI (agent) {
|
|
13
|
+
setupAPI(MEASURE, function (name, options) {
|
|
14
|
+
const n = now()
|
|
15
|
+
const { start, end, customAttributes } = options || {}
|
|
16
|
+
const returnObj = { customAttributes: customAttributes || {} }
|
|
17
|
+
|
|
18
|
+
if (typeof returnObj.customAttributes !== 'object' || typeof name !== 'string' || name.length === 0) {
|
|
19
|
+
warn(57)
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* getValueFromTiming - Helper function to extract a numeric value from a supplied option.
|
|
25
|
+
* @param {Number|PerformanceMark} [timing] The timing value
|
|
26
|
+
* @param {Number} [d] The default value to return if timing is invalid
|
|
27
|
+
* @returns {Number} The timing value or the default value
|
|
28
|
+
*/
|
|
29
|
+
const getValueFromTiming = (timing, d) => {
|
|
30
|
+
if (timing == null) return d
|
|
31
|
+
if (typeof timing === 'number') return timing
|
|
32
|
+
if (timing instanceof PerformanceMark) return timing.startTime
|
|
33
|
+
return Number.NaN
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
returnObj.start = getValueFromTiming(start, 0)
|
|
37
|
+
returnObj.end = getValueFromTiming(end, n)
|
|
38
|
+
if (Number.isNaN(returnObj.start) || Number.isNaN(returnObj.end)) {
|
|
39
|
+
warn(57)
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
returnObj.duration = returnObj.end - returnObj.start
|
|
44
|
+
if (returnObj.duration < 0) {
|
|
45
|
+
warn(58)
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
handle(prefix + MEASURE, [returnObj, name], undefined, FEATURE_NAMES.genericEvents, agent.ee)
|
|
50
|
+
|
|
51
|
+
return returnObj
|
|
52
|
+
}, agent)
|
|
53
|
+
}
|
package/src/loaders/api-base.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { warn } from '../common/util/console'
|
|
6
|
-
import { ADD_PAGE_ACTION, ADD_RELEASE, ADD_TO_TRACE, FINISHED, INTERACTION, LOG, NOTICE_ERROR, PAUSE_REPLAY, RECORD_CUSTOM_EVENT, RECORD_REPLAY, REGISTER, SET_APPLICATION_VERSION, SET_CURRENT_ROUTE_NAME, SET_CUSTOM_ATTRIBUTE, SET_ERROR_HANDLER, SET_PAGE_VIEW_NAME, SET_USER_ID, START, WRAP_LOGGER } from './api/constants'
|
|
6
|
+
import { ADD_PAGE_ACTION, ADD_RELEASE, ADD_TO_TRACE, FINISHED, INTERACTION, LOG, NOTICE_ERROR, PAUSE_REPLAY, RECORD_CUSTOM_EVENT, RECORD_REPLAY, REGISTER, SET_APPLICATION_VERSION, SET_CURRENT_ROUTE_NAME, SET_CUSTOM_ATTRIBUTE, SET_ERROR_HANDLER, SET_PAGE_VIEW_NAME, SET_USER_ID, START, WRAP_LOGGER, MEASURE } from './api/constants'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @typedef {import('./api/interaction-types').InteractionInstance} InteractionInstance
|
|
@@ -215,4 +215,15 @@ export class ApiBase {
|
|
|
215
215
|
wrapLogger (parent, functionName, options) {
|
|
216
216
|
return this.#callMethod(WRAP_LOGGER, parent, functionName, options)
|
|
217
217
|
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Measures a task that is recorded as a BrowserPerformance event.
|
|
221
|
+
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/measure/}
|
|
222
|
+
* @param {string} name The name of the task
|
|
223
|
+
* @param {object?} options An object used to control the way the measure API operates
|
|
224
|
+
* @returns {{start: number, end: number, duration: number, customAttributes: object}} Measurement details
|
|
225
|
+
*/
|
|
226
|
+
measure (name, options) {
|
|
227
|
+
return this.#callMethod(MEASURE, name, options)
|
|
228
|
+
}
|
|
218
229
|
}
|