@newrelic/browser-agent 1.237.0 → 1.238.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/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/deny-list/deny-list.js +1 -1
- package/dist/cjs/common/event-emitter/contextual-ee.js +18 -26
- package/dist/cjs/common/event-emitter/event-context.js +12 -0
- package/dist/cjs/common/harvest/harvest.js +4 -4
- package/dist/cjs/common/ids/bundle-id.js +19 -0
- package/dist/cjs/common/wrap/wrap-events.js +3 -2
- package/dist/cjs/common/wrap/wrap-fetch.js +1 -3
- package/dist/cjs/common/wrap/wrap-function.js +15 -46
- package/dist/cjs/common/wrap/wrap-mutation.js +1 -2
- package/dist/cjs/common/wrap/wrap-promise.js +2 -3
- package/dist/cjs/common/wrap/wrap-xhr.js +23 -27
- package/dist/cjs/features/ajax/instrument/distributed-tracing.js +0 -4
- package/dist/cjs/features/ajax/instrument/index.js +19 -9
- package/dist/cjs/features/metrics/aggregate/index.js +8 -0
- package/dist/cjs/features/session_replay/aggregate/index.js +2 -0
- package/dist/cjs/features/session_trace/aggregate/index.js +14 -8
- package/dist/cjs/features/spa/aggregate/index.js +1 -1
- package/dist/cjs/loaders/agent-base.js +12 -0
- package/dist/cjs/loaders/api/api.js +14 -1
- package/dist/cjs/loaders/api/interaction-types.js +11 -4
- package/dist/cjs/loaders/configure/configure.js +2 -1
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/deny-list/deny-list.js +1 -1
- package/dist/esm/common/event-emitter/contextual-ee.js +16 -23
- package/dist/esm/common/event-emitter/event-context.js +5 -0
- package/dist/esm/common/harvest/harvest.js +4 -4
- package/dist/esm/common/ids/bundle-id.js +13 -0
- package/dist/esm/common/wrap/wrap-events.js +4 -3
- package/dist/esm/common/wrap/wrap-fetch.js +2 -4
- package/dist/esm/common/wrap/wrap-function.js +15 -44
- package/dist/esm/common/wrap/wrap-mutation.js +2 -3
- package/dist/esm/common/wrap/wrap-promise.js +3 -4
- package/dist/esm/common/wrap/wrap-xhr.js +23 -27
- package/dist/esm/features/ajax/instrument/distributed-tracing.js +0 -4
- package/dist/esm/features/ajax/instrument/index.js +20 -10
- package/dist/esm/features/metrics/aggregate/index.js +8 -0
- package/dist/esm/features/session_replay/aggregate/index.js +2 -0
- package/dist/esm/features/session_trace/aggregate/index.js +14 -8
- package/dist/esm/features/spa/aggregate/index.js +1 -1
- package/dist/esm/loaders/agent-base.js +12 -0
- package/dist/esm/loaders/api/api.js +14 -1
- package/dist/esm/loaders/api/interaction-types.js +11 -4
- package/dist/esm/loaders/configure/configure.js +3 -2
- package/dist/types/common/event-emitter/contextual-ee.d.ts +22 -2
- package/dist/types/common/event-emitter/contextual-ee.d.ts.map +1 -1
- package/dist/types/common/event-emitter/event-context.d.ts +5 -0
- package/dist/types/common/event-emitter/event-context.d.ts.map +1 -0
- package/dist/types/common/event-emitter/register-handler.d.ts +1 -1
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/ids/bundle-id.d.ts +5 -0
- package/dist/types/common/ids/bundle-id.d.ts.map +1 -0
- package/dist/types/common/session/session-entity.d.ts +6 -6
- package/dist/types/common/window/nreum.d.ts +2 -2
- package/dist/types/common/wrap/wrap-events.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-fetch.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-function.d.ts +1 -19
- package/dist/types/common/wrap/wrap-function.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-mutation.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-promise.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-xhr.d.ts.map +1 -1
- package/dist/types/features/ajax/instrument/distributed-tracing.d.ts +1 -1
- package/dist/types/features/ajax/instrument/distributed-tracing.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/endpoint-map.d.ts +5 -5
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +5 -0
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/loaders/agent-base.d.ts +9 -0
- package/dist/types/loaders/agent-base.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts +6 -0
- package/dist/types/loaders/api/api.d.ts.map +1 -1
- package/dist/types/loaders/api/interaction-types.d.ts +18 -7
- package/dist/types/loaders/api/interaction-types.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts +1 -0
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts +9 -9
- package/dist/types/loaders/micro-agent.d.ts +1 -1
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +22 -27
- package/src/common/deny-list/deny-list.js +1 -1
- package/src/common/deny-list/deny-list.test.js +103 -30
- package/src/common/event-emitter/{contextual-ee.test.js → contextual-ee.component-test.js} +15 -32
- package/src/common/event-emitter/contextual-ee.js +20 -31
- package/src/common/event-emitter/event-context.js +5 -0
- package/src/common/harvest/harvest.js +4 -4
- package/src/common/harvest/harvest.test.js +1 -1
- package/src/common/ids/__mocks__/bundle-id.js +2 -0
- package/src/common/ids/__mocks__/unique-id.js +17 -0
- package/src/common/ids/bundle-id.js +13 -0
- package/src/common/url/__mocks__/parse-url.js +15 -0
- package/src/common/util/__mocks__/get-or-set.js +5 -0
- package/src/common/window/__mocks__/nreum.js +10 -0
- package/src/common/wrap/wrap-events.js +4 -3
- package/src/common/wrap/wrap-fetch.js +2 -4
- package/src/common/wrap/wrap-function.js +16 -44
- package/src/common/wrap/wrap-mutation.js +2 -3
- package/src/common/wrap/{wrap-promise.test.js → wrap-promise.component-test.js} +2 -32
- package/src/common/wrap/wrap-promise.js +3 -4
- package/src/common/wrap/wrap-xhr.js +24 -28
- package/src/features/ajax/instrument/distributed-tracing.js +0 -4
- package/src/features/ajax/instrument/distributed-tracing.test.js +375 -0
- package/src/features/ajax/instrument/index.js +22 -10
- package/src/features/metrics/aggregate/index.js +8 -0
- package/src/features/session_replay/aggregate/index.js +2 -0
- package/src/features/session_trace/aggregate/index.js +16 -7
- package/src/features/spa/aggregate/index.js +1 -1
- package/src/loaders/agent-base.js +12 -0
- package/src/loaders/api/api.component-test.js +45 -0
- package/src/loaders/api/api.js +14 -1
- package/src/loaders/api/interaction-types.js +11 -4
- package/src/loaders/configure/configure.js +11 -2
- /package/src/common/url/{encode.component-test.js → encode.test.js} +0 -0
- /package/src/common/url/{protocol.component-test.js → protocol.test.js} +0 -0
|
@@ -3,30 +3,29 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.ee = void 0;
|
|
7
|
-
exports.getOrSetContext = getOrSetContext;
|
|
6
|
+
exports.ee = exports.contextId = void 0;
|
|
8
7
|
var _nreum = require("../window/nreum");
|
|
9
8
|
var _getOrSet = require("../util/get-or-set");
|
|
10
|
-
var _mapOwn = require("../util/map-own");
|
|
11
9
|
var _config = require("../config/config");
|
|
10
|
+
var _eventContext = require("./event-context");
|
|
11
|
+
var _bundleId = require("../ids/bundle-id");
|
|
12
12
|
/*
|
|
13
13
|
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
14
14
|
* SPDX-License-Identifier: Apache-2.0
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
// create a unique id to store event context data for the current agent bundle
|
|
18
|
+
const contextId = "nr@context:".concat(_bundleId.bundleId);
|
|
19
19
|
// create global emitter instance that can be shared among bundles
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
exports.contextId = contextId;
|
|
21
|
+
const globalInstance = ee(undefined, 'globalEE');
|
|
22
|
+
|
|
23
|
+
// Only override the exposed event emitter if one has not already been exposed
|
|
22
24
|
exports.ee = globalInstance;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
} else {
|
|
26
|
-
exports.ee = globalInstance = ee(undefined, 'globalEE');
|
|
25
|
+
const nr = (0, _nreum.gosNREUM)();
|
|
26
|
+
if (!nr.ee) {
|
|
27
27
|
nr.ee = globalInstance;
|
|
28
28
|
}
|
|
29
|
-
function EventContext() {}
|
|
30
29
|
function ee(old, debugId) {
|
|
31
30
|
var handlers = {};
|
|
32
31
|
var bufferGroupMap = {};
|
|
@@ -60,12 +59,12 @@ function ee(old, debugId) {
|
|
|
60
59
|
};
|
|
61
60
|
return emitter;
|
|
62
61
|
function context(contextOrStore) {
|
|
63
|
-
if (contextOrStore && contextOrStore instanceof EventContext) {
|
|
62
|
+
if (contextOrStore && contextOrStore instanceof _eventContext.EventContext) {
|
|
64
63
|
return contextOrStore;
|
|
65
64
|
} else if (contextOrStore) {
|
|
66
|
-
return (0, _getOrSet.getOrSet)(contextOrStore,
|
|
65
|
+
return (0, _getOrSet.getOrSet)(contextOrStore, contextId, () => new _eventContext.EventContext(contextId));
|
|
67
66
|
} else {
|
|
68
|
-
return
|
|
67
|
+
return new _eventContext.EventContext(contextId);
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
function emit(type, args, contextOrStore, force, bubble) {
|
|
@@ -112,12 +111,13 @@ function ee(old, debugId) {
|
|
|
112
111
|
return emitters[name] = emitters[name] || ee(emitter, name);
|
|
113
112
|
}
|
|
114
113
|
function bufferEventsByGroup(types, group) {
|
|
115
|
-
|
|
114
|
+
const eventBuffer = getBuffer();
|
|
115
|
+
group = group || 'feature';
|
|
116
116
|
|
|
117
117
|
// do not buffer events if agent has been aborted
|
|
118
118
|
if (emitter.aborted) return;
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
Object.entries(types || {}).forEach(_ref => {
|
|
120
|
+
let [_, type] = _ref;
|
|
121
121
|
bufferGroupMap[type] = group;
|
|
122
122
|
if (!(group in eventBuffer)) {
|
|
123
123
|
eventBuffer[group] = [];
|
|
@@ -135,14 +135,6 @@ function ee(old, debugId) {
|
|
|
135
135
|
return emitter.backlog;
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
|
|
139
|
-
// get context object from store object, or create if does not exist
|
|
140
|
-
function getOrSetContext(obj) {
|
|
141
|
-
return (0, _getOrSet.getOrSet)(obj, ctxId, getNewContext);
|
|
142
|
-
}
|
|
143
|
-
function getNewContext() {
|
|
144
|
-
return new EventContext();
|
|
145
|
-
}
|
|
146
138
|
function abort() {
|
|
147
139
|
globalInstance.aborted = true;
|
|
148
140
|
globalInstance.backlog = {};
|
|
@@ -56,7 +56,8 @@ class Harvest extends _sharedContext.SharedContext {
|
|
|
56
56
|
isFinalHarvest: spec.opts?.unload
|
|
57
57
|
});
|
|
58
58
|
const options = {
|
|
59
|
-
retry: !spec.opts?.unload && submitMethod === submitData.xhr
|
|
59
|
+
retry: !spec.opts?.unload && submitMethod === submitData.xhr,
|
|
60
|
+
isFinalHarvest: spec.opts?.unload === true
|
|
60
61
|
};
|
|
61
62
|
const payload = this.createPayload(spec.endpoint, options);
|
|
62
63
|
const caller = this.obfuscator.shouldObfuscate() ? this.obfuscateAndSend.bind(this) : this._send.bind(this);
|
|
@@ -258,9 +259,8 @@ class Harvest extends _sharedContext.SharedContext {
|
|
|
258
259
|
cleanPayload() {
|
|
259
260
|
let payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
260
261
|
const clean = input => {
|
|
261
|
-
if (typeof Uint8Array !== 'undefined' && input instanceof Uint8Array ||
|
|
262
|
-
|
|
263
|
-
}
|
|
262
|
+
if (typeof Uint8Array !== 'undefined' && input instanceof Uint8Array || Array.isArray(input)) return input;
|
|
263
|
+
if (typeof input === 'string') return input.length > 0 ? input : null;
|
|
264
264
|
return Object.entries(input || {}).reduce((accumulator, _ref2) => {
|
|
265
265
|
let [key, value] = _ref2;
|
|
266
266
|
if (typeof value === 'number' || typeof value === 'string' && value.length > 0 || typeof value === 'object' && Object.keys(value || {}).length > 0) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.bundleId = void 0;
|
|
7
|
+
var _uniqueId = require("./unique-id");
|
|
8
|
+
/**
|
|
9
|
+
* @file Contains a unique identifier for the running agent bundle
|
|
10
|
+
* when loaded.
|
|
11
|
+
* @copyright 2023 New Relic Corporation. All rights reserved.
|
|
12
|
+
* @license Apache-2.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Provides a unique id for the current agent bundle
|
|
17
|
+
*/
|
|
18
|
+
const bundleId = (0, _uniqueId.generateUuid)();
|
|
19
|
+
exports.bundleId = bundleId;
|
|
@@ -20,9 +20,10 @@ var _runtime = require("../constants/runtime");
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
const wrapped = {};
|
|
23
|
-
const XHR = XMLHttpRequest;
|
|
23
|
+
const XHR = _runtime.globalScope.XMLHttpRequest;
|
|
24
24
|
const ADD_EVENT_LISTENER = 'addEventListener';
|
|
25
25
|
const REMOVE_EVENT_LISTENER = 'removeEventListener';
|
|
26
|
+
const flag = "nr@wrapped:".concat(_contextualEe.contextId);
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Wraps `addEventListener` and `removeEventListener` on: global scope; the prototype of `XMLHttpRequest`, and
|
|
@@ -51,7 +52,7 @@ function wrapEvents(sharedEE) {
|
|
|
51
52
|
if (originalListener === null || typeof originalListener !== 'function' && typeof originalListener !== 'object') {
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
|
-
var wrapped = (0, _getOrSet.getOrSet)(originalListener,
|
|
55
|
+
var wrapped = (0, _getOrSet.getOrSet)(originalListener, flag, function () {
|
|
55
56
|
var listener = {
|
|
56
57
|
object: wrapHandleEvent,
|
|
57
58
|
function: originalListener
|
|
@@ -7,7 +7,6 @@ exports.scopedEE = scopedEE;
|
|
|
7
7
|
exports.wrapFetch = wrapFetch;
|
|
8
8
|
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
9
9
|
var _runtime = require("../constants/runtime");
|
|
10
|
-
var _wrapFunction = require("./wrap-function");
|
|
11
10
|
/*
|
|
12
11
|
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
13
12
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -23,7 +22,6 @@ var bodyMethods = ['arrayBuffer', 'blob', 'json', 'text', 'formData'];
|
|
|
23
22
|
var Req = _runtime.globalScope.Request;
|
|
24
23
|
var Res = _runtime.globalScope.Response;
|
|
25
24
|
var proto = 'prototype';
|
|
26
|
-
var ctxId = 'nr@context';
|
|
27
25
|
const wrapped = {};
|
|
28
26
|
|
|
29
27
|
/**
|
|
@@ -80,7 +78,7 @@ function wrapFetch(sharedEE) {
|
|
|
80
78
|
// we are wrapping args in an array so we can preserve the reference
|
|
81
79
|
ee.emit(prefix + 'before-start', [args], ctx);
|
|
82
80
|
var dtPayload;
|
|
83
|
-
if (ctx[
|
|
81
|
+
if (ctx[_contextualEe.contextId] && ctx[_contextualEe.contextId].dt) dtPayload = ctx[_contextualEe.contextId].dt;
|
|
84
82
|
var origPromiseFromFetch = fn.apply(this, args);
|
|
85
83
|
ee.emit(prefix + 'start', [args, dtPayload], origPromiseFromFetch);
|
|
86
84
|
|
|
@@ -5,9 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.createWrapperWithEmitter = createWrapperWithEmitter;
|
|
7
7
|
exports.flag = exports.default = void 0;
|
|
8
|
-
exports.wrapFunction = wrapFunction;
|
|
9
|
-
exports.wrapInPlace = wrapInPlace;
|
|
10
8
|
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
9
|
+
var _bundleId = require("../ids/bundle-id");
|
|
11
10
|
/*
|
|
12
11
|
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
13
12
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -16,7 +15,7 @@ var _contextualEe = require("../event-emitter/contextual-ee");
|
|
|
16
15
|
* @file Provides helper functions for wrapping functions in various scenarios.
|
|
17
16
|
*/
|
|
18
17
|
|
|
19
|
-
const flag =
|
|
18
|
+
const flag = "nr@original:".concat(_bundleId.bundleId);
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
21
|
* A convenience alias of `hasOwnProperty`.
|
|
@@ -110,25 +109,23 @@ function createWrapperWithEmitter(emitter, always) {
|
|
|
110
109
|
|
|
111
110
|
/**
|
|
112
111
|
* Creates wrapper functions around each of an array of methods on a specified object.
|
|
113
|
-
* @param {Object} obj
|
|
114
|
-
* @param {string[]} methods
|
|
115
|
-
* @param {string} [prefix='']
|
|
116
|
-
*
|
|
117
|
-
* @param {function|object} [getContext]
|
|
118
|
-
*
|
|
119
|
-
* @param {boolean} [bubble=false]
|
|
120
|
-
*
|
|
112
|
+
* @param {Object} obj The object to which the specified methods belong.
|
|
113
|
+
* @param {string[]} methods An array of method names to be wrapped.
|
|
114
|
+
* @param {string} [prefix=''] A prefix to add to the names of emitted events. If `-` is the first character, also
|
|
115
|
+
* adds the method name before the prefix.
|
|
116
|
+
* @param {function|object} [getContext] The function or object that will serve as the 'this' context for handlers
|
|
117
|
+
* of events emitted by this wrapper.
|
|
118
|
+
* @param {boolean} [bubble=false] If `true`, emitted events should also bubble up to the old emitter upon which
|
|
119
|
+
* the `emitter` in the current scope was based (if it defines one).
|
|
121
120
|
*/
|
|
122
121
|
function inPlace(obj, methods, prefix, getContext, bubble) {
|
|
123
122
|
if (!prefix) prefix = '';
|
|
123
|
+
|
|
124
124
|
// If prefix starts with '-' set this boolean to add the method name to the prefix before passing each one to wrap.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
for (i = 0; i < methods.length; i++) {
|
|
130
|
-
method = methods[i];
|
|
131
|
-
fn = obj[method];
|
|
125
|
+
const prependMethodPrefix = prefix.charAt(0) === '-';
|
|
126
|
+
for (let i = 0; i < methods.length; i++) {
|
|
127
|
+
const method = methods[i];
|
|
128
|
+
const fn = obj[method];
|
|
132
129
|
|
|
133
130
|
// Unless fn is both wrappable and unwrapped, bail so we don't add extra properties with undefined values.
|
|
134
131
|
if (notWrappable(fn)) continue;
|
|
@@ -222,32 +219,4 @@ function copy(from, to, emitter) {
|
|
|
222
219
|
*/
|
|
223
220
|
function notWrappable(fn) {
|
|
224
221
|
return !(fn && fn instanceof Function && fn.apply && !fn[flag]);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Creates a wrapped version of a function using a specified wrapper function. The new wrapped function references the
|
|
229
|
-
* original function. Also copies the properties of the original function to the wrapped function.
|
|
230
|
-
* @param {function} fn - A function to be wrapped.
|
|
231
|
-
* @param {function} wrapper - A higher order function that returns a new function, which executes the function passed
|
|
232
|
-
* to the higher order function as an argument.
|
|
233
|
-
* @returns {function} A wrapped function with an internal reference to the original function.
|
|
234
|
-
*/
|
|
235
|
-
function wrapFunction(fn, wrapper) {
|
|
236
|
-
var wrapped = wrapper(fn);
|
|
237
|
-
wrapped[flag] = fn;
|
|
238
|
-
copy(fn, wrapped, _contextualEe.ee);
|
|
239
|
-
return wrapped;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Replaces a function with a wrapped version of itself. To preserve object references, rather than taking the function
|
|
244
|
-
* itself as an argument, takes the object on which the particular named function is a property.
|
|
245
|
-
* @param {Object} obj - The object on which the named function is a property.
|
|
246
|
-
* @param {string} fnName - The name of the function to be wrapped.
|
|
247
|
-
* @param {function} wrapper - A higher order function that returns a new function, which executes the function passed
|
|
248
|
-
* to the higher order function as an argument.
|
|
249
|
-
*/
|
|
250
|
-
function wrapInPlace(obj, fnName, wrapper) {
|
|
251
|
-
var fn = obj[fnName];
|
|
252
|
-
obj[fnName] = wrapFunction(fn, wrapper);
|
|
253
222
|
}
|
|
@@ -7,7 +7,6 @@ exports.scopedEE = scopedEE;
|
|
|
7
7
|
exports.wrapMutation = wrapMutation;
|
|
8
8
|
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
9
9
|
var _wrapFunction = require("./wrap-function");
|
|
10
|
-
var _config = require("../config/config");
|
|
11
10
|
var _runtime = require("../constants/runtime");
|
|
12
11
|
/*
|
|
13
12
|
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
@@ -36,7 +35,7 @@ function wrapMutation(sharedEE) {
|
|
|
36
35
|
wrapped[ee.debugId] = true; // otherwise, first feature to wrap mutations
|
|
37
36
|
|
|
38
37
|
var wrapFn = (0, _wrapFunction.createWrapperWithEmitter)(ee);
|
|
39
|
-
var OriginalObserver =
|
|
38
|
+
var OriginalObserver = _runtime.globalScope.MutationObserver;
|
|
40
39
|
if (OriginalObserver) {
|
|
41
40
|
window.MutationObserver = function WrappedMutationObserver(cb) {
|
|
42
41
|
if (this instanceof OriginalObserver) {
|
|
@@ -7,7 +7,6 @@ exports.scopedEE = scopedEE;
|
|
|
7
7
|
exports.wrapPromise = wrapPromise;
|
|
8
8
|
var _wrapFunction = require("./wrap-function");
|
|
9
9
|
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
10
|
-
var _config = require("../config/config");
|
|
11
10
|
var _runtime = require("../constants/runtime");
|
|
12
11
|
/*
|
|
13
12
|
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
@@ -35,9 +34,9 @@ function wrapPromise(sharedEE) {
|
|
|
35
34
|
if (wrapped[promiseEE.debugId]) return promiseEE;
|
|
36
35
|
wrapped[promiseEE.debugId] = true; // otherwise, first feature to wrap promise
|
|
37
36
|
|
|
38
|
-
var getContext =
|
|
37
|
+
var getContext = promiseEE.context;
|
|
39
38
|
var promiseWrapper = (0, _wrapFunction.createWrapperWithEmitter)(promiseEE);
|
|
40
|
-
var prevPromiseObj =
|
|
39
|
+
var prevPromiseObj = _runtime.globalScope.Promise;
|
|
41
40
|
if (prevPromiseObj) {
|
|
42
41
|
// ensure there's a Promise API (native or otherwise) to even wrap
|
|
43
42
|
wrap();
|
|
@@ -9,7 +9,6 @@ var _wrapEvents = require("./wrap-events");
|
|
|
9
9
|
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
10
10
|
var _eventListenerOpts = require("../event-listener/event-listener-opts");
|
|
11
11
|
var _wrapFunction = require("./wrap-function");
|
|
12
|
-
var _config = require("../config/config");
|
|
13
12
|
var _runtime = require("../constants/runtime");
|
|
14
13
|
var _console = require("../util/console");
|
|
15
14
|
/*
|
|
@@ -42,32 +41,28 @@ function wrapXhr(sharedEE) {
|
|
|
42
41
|
|
|
43
42
|
(0, _wrapEvents.wrapEvents)(baseEE); // wrap-events patches XMLHttpRequest.prototype.addEventListener for us
|
|
44
43
|
var wrapFn = (0, _wrapFunction.createWrapperWithEmitter)(ee);
|
|
45
|
-
var OrigXHR =
|
|
46
|
-
var MutationObserver =
|
|
47
|
-
var Promise =
|
|
48
|
-
var setImmediate =
|
|
44
|
+
var OrigXHR = _runtime.globalScope.XMLHttpRequest;
|
|
45
|
+
var MutationObserver = _runtime.globalScope.MutationObserver;
|
|
46
|
+
var Promise = _runtime.globalScope.Promise;
|
|
47
|
+
var setImmediate = _runtime.globalScope.setInterval;
|
|
49
48
|
var READY_STATE_CHANGE = 'readystatechange';
|
|
50
49
|
var handlers = ['onload', 'onerror', 'onabort', 'onloadstart', 'onloadend', 'onprogress', 'ontimeout'];
|
|
51
50
|
var pendingXhrs = [];
|
|
52
|
-
var activeListeners = _runtime.globalScope.XMLHttpRequest.listeners;
|
|
53
51
|
var XHR = _runtime.globalScope.XMLHttpRequest = newXHR;
|
|
54
52
|
function newXHR(opts) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
const xhr = new OrigXHR(opts);
|
|
54
|
+
const context = ee.context(xhr);
|
|
55
|
+
try {
|
|
56
|
+
ee.emit('new-xhr', [xhr], context);
|
|
57
|
+
xhr.addEventListener(READY_STATE_CHANGE, wrapXHR(context), (0, _eventListenerOpts.eventListenerOpts)(false));
|
|
58
|
+
} catch (e) {
|
|
59
|
+
(0, _console.warn)('An error occurred while intercepting XHR', e);
|
|
58
60
|
try {
|
|
59
|
-
ee.emit('
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
(0, _console.warn)('An error occured while intercepting XHR', e);
|
|
63
|
-
try {
|
|
64
|
-
ee.emit('internal-error', [e]);
|
|
65
|
-
} catch (err) {
|
|
66
|
-
// do nothing
|
|
67
|
-
}
|
|
61
|
+
ee.emit('internal-error', [e]);
|
|
62
|
+
} catch (err) {
|
|
63
|
+
// do nothing
|
|
68
64
|
}
|
|
69
65
|
}
|
|
70
|
-
this.listeners.forEach(listener => listener());
|
|
71
66
|
return xhr;
|
|
72
67
|
}
|
|
73
68
|
copy(OrigXHR, XHR);
|
|
@@ -81,14 +76,15 @@ function wrapXhr(sharedEE) {
|
|
|
81
76
|
function wrapOnreadystatechange(args, xhr) {
|
|
82
77
|
wrapFn.inPlace(xhr, ['onreadystatechange'], 'fn-', getObject);
|
|
83
78
|
}
|
|
84
|
-
function wrapXHR() {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
79
|
+
function wrapXHR(ctx) {
|
|
80
|
+
return function () {
|
|
81
|
+
var xhr = this;
|
|
82
|
+
if (xhr.readyState > 3 && !ctx.resolved) {
|
|
83
|
+
ctx.resolved = true;
|
|
84
|
+
ee.emit('xhr-resolved', [], xhr);
|
|
85
|
+
}
|
|
86
|
+
wrapFn.inPlace(xhr, handlers, 'fn-', getObject);
|
|
87
|
+
};
|
|
92
88
|
}
|
|
93
89
|
|
|
94
90
|
// Wrapping the onreadystatechange property of XHRs takes some special tricks.
|
|
@@ -17,10 +17,6 @@ var _stringify = require("../../../common/util/stringify");
|
|
|
17
17
|
class DT {
|
|
18
18
|
constructor(agentIdentifier) {
|
|
19
19
|
this.agentIdentifier = agentIdentifier;
|
|
20
|
-
// Binds this class instance context to the following fn used in an external module (exported);
|
|
21
|
-
// Alternatively, can make them class field arrow functions, but requires experimental features/plugin for eslint.
|
|
22
|
-
this.generateTracePayload = this.generateTracePayload.bind(this);
|
|
23
|
-
this.shouldGenerateTrace = this.shouldGenerateTrace.bind(this);
|
|
24
20
|
}
|
|
25
21
|
generateTracePayload(parsedOrigin) {
|
|
26
22
|
if (!this.shouldGenerateTrace(parsedOrigin)) {
|
|
@@ -26,7 +26,7 @@ var _features = require("../../../loaders/features/features");
|
|
|
26
26
|
var handlers = ['load', 'error', 'abort', 'timeout'];
|
|
27
27
|
var handlersLen = handlers.length;
|
|
28
28
|
var origRequest = _config.originals.REQ;
|
|
29
|
-
var origXHR =
|
|
29
|
+
var origXHR = _config.originals.XHR;
|
|
30
30
|
class Instrument extends _instrumentBase.InstrumentBase {
|
|
31
31
|
static featureName = _constants.FEATURE_NAME;
|
|
32
32
|
constructor(agentIdentifier, aggregator) {
|
|
@@ -193,15 +193,25 @@ function subscribeToEvents(agentIdentifier, ee, handler, dt) {
|
|
|
193
193
|
function onFetchBeforeStart(args) {
|
|
194
194
|
var opts = args[1] || {};
|
|
195
195
|
var url;
|
|
196
|
-
// argument is USVString
|
|
197
196
|
if (typeof args[0] === 'string') {
|
|
197
|
+
// argument is USVString
|
|
198
198
|
url = args[0];
|
|
199
|
-
|
|
199
|
+
if (url.length === 0 && _runtime.isBrowserScope) {
|
|
200
|
+
url = '' + _runtime.globalScope.location.href;
|
|
201
|
+
}
|
|
200
202
|
} else if (args[0] && args[0].url) {
|
|
203
|
+
// argument is Request object
|
|
201
204
|
url = args[0].url;
|
|
202
|
-
// argument is URL object
|
|
203
205
|
} else if (_runtime.globalScope?.URL && args[0] && args[0] instanceof URL) {
|
|
206
|
+
// argument is URL object
|
|
204
207
|
url = args[0].href;
|
|
208
|
+
} else if (typeof args[0].toString === 'function') {
|
|
209
|
+
url = args[0].toString();
|
|
210
|
+
}
|
|
211
|
+
if (typeof url !== 'string' || url.length === 0) {
|
|
212
|
+
// Short-circuit DT since we could not determine the URL of the fetch call
|
|
213
|
+
// this is very unlikely to happen
|
|
214
|
+
return;
|
|
205
215
|
}
|
|
206
216
|
if (url) {
|
|
207
217
|
this.parsedOrigin = (0, _parseUrl.parseUrl)(url);
|
|
@@ -211,7 +221,11 @@ function subscribeToEvents(agentIdentifier, ee, handler, dt) {
|
|
|
211
221
|
if (!payload || !payload.newrelicHeader && !payload.traceContextParentHeader) {
|
|
212
222
|
return;
|
|
213
223
|
}
|
|
214
|
-
if (
|
|
224
|
+
if (args[0] && args[0].headers) {
|
|
225
|
+
if (addHeaders(args[0].headers, payload)) {
|
|
226
|
+
this.dt = payload;
|
|
227
|
+
}
|
|
228
|
+
} else {
|
|
215
229
|
var clone = {};
|
|
216
230
|
for (var key in opts) {
|
|
217
231
|
clone[key] = opts[key];
|
|
@@ -225,10 +239,6 @@ function subscribeToEvents(agentIdentifier, ee, handler, dt) {
|
|
|
225
239
|
} else {
|
|
226
240
|
args.push(clone);
|
|
227
241
|
}
|
|
228
|
-
} else if (args[0] && args[0].headers) {
|
|
229
|
-
if (addHeaders(args[0].headers, payload)) {
|
|
230
|
-
this.dt = payload;
|
|
231
|
-
}
|
|
232
242
|
}
|
|
233
243
|
function addHeaders(headersObj, payload) {
|
|
234
244
|
var added = false;
|
|
@@ -154,6 +154,14 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
154
154
|
// Capture metrics for size of custom attributes
|
|
155
155
|
const jsAttributes = (0, _stringify.stringify)(info.jsAttributes);
|
|
156
156
|
this.storeSupportabilityMetrics('PageSession/Feature/CustomData/Bytes', jsAttributes === '{}' ? 0 : jsAttributes.length);
|
|
157
|
+
|
|
158
|
+
// Capture metrics for performance markers and measures
|
|
159
|
+
if (typeof performance !== 'undefined') {
|
|
160
|
+
const markers = performance.getEntriesByType('mark');
|
|
161
|
+
const measures = performance.getEntriesByType('measure');
|
|
162
|
+
this.storeSupportabilityMetrics('Generic/Performance/Mark/Seen', markers.length);
|
|
163
|
+
this.storeSupportabilityMetrics('Generic/Performance/Measure/Seen', measures.length);
|
|
164
|
+
}
|
|
157
165
|
} catch (e) {
|
|
158
166
|
// do nothing
|
|
159
167
|
}
|
|
@@ -182,11 +182,13 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
182
182
|
this.scheduler.startTimer(this.harvestTimeSeconds);
|
|
183
183
|
}
|
|
184
184
|
try {
|
|
185
|
+
// Do not change the webpackChunkName or it will break the webpack nrba-chunking plugin
|
|
185
186
|
recorder = (await Promise.resolve().then(() => _interopRequireWildcard(require( /* webpackChunkName: "recorder" */'rrweb')))).record;
|
|
186
187
|
} catch (err) {
|
|
187
188
|
return this.abort();
|
|
188
189
|
}
|
|
189
190
|
try {
|
|
191
|
+
// Do not change the webpackChunkName or it will break the webpack nrba-chunking plugin
|
|
190
192
|
const {
|
|
191
193
|
gzipSync,
|
|
192
194
|
strToU8
|
|
@@ -64,9 +64,13 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
64
64
|
this.sentTrace = null;
|
|
65
65
|
this.harvestTimeSeconds = (0, _config.getConfigurationValue)(agentIdentifier, 'session_trace.harvestTimeSeconds') || 10;
|
|
66
66
|
this.maxNodesPerHarvest = (0, _config.getConfigurationValue)(agentIdentifier, 'session_trace.maxNodesPerHarvest') || 1000;
|
|
67
|
+
/**
|
|
68
|
+
* Standalone (mode) refers to the legacy version of ST before the idea of 'session' or the Replay feature existed.
|
|
69
|
+
* It has some different behavior vs when used in tandem with replay. */
|
|
67
70
|
this.isStandalone = false;
|
|
68
71
|
const operationalGate = new _handlerCache.HandlerCache(); // acts as a controller-intermediary that can enable or disable this feature's collection dynamically
|
|
69
72
|
const sessionEntity = this.agentRuntime.session;
|
|
73
|
+
this.operationalGate = operationalGate;
|
|
70
74
|
|
|
71
75
|
/* --- The following section deals with user sessions concept & contains non-trivial control flow. --- */
|
|
72
76
|
const controlTraceOp = traceMode => {
|
|
@@ -250,17 +254,16 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
250
254
|
}
|
|
251
255
|
}
|
|
252
256
|
#prepareHarvest(options) {
|
|
253
|
-
/* Standalone refers to the legacy version of ST before the idea of 'session' or the Replay feature existed.
|
|
254
|
-
It has a different behavior on returning a payload for harvest than when used in tandem with either of those concepts. */
|
|
255
257
|
if (this.isStandalone) {
|
|
256
|
-
if ((0, _now.now)()
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
this.
|
|
258
|
+
if (this.ptid && (0, _now.now)() >= MAX_TRACE_DURATION) {
|
|
259
|
+
// Perform a final harvest once we hit or exceed the max session trace time
|
|
260
|
+
options.isFinalHarvest = true;
|
|
261
|
+
this.operationalGate.permanentlyDecide(false);
|
|
262
|
+
this.#scheduler.stopTimer(true);
|
|
263
|
+
} else if (this.ptid && this.nodeCount <= REQ_THRESHOLD_TO_SEND && !options.isFinalHarvest) {
|
|
264
|
+
// Only harvest when more than some threshold of nodes are pending, after the very first harvest, with the exception of the last outgoing harvest.
|
|
260
265
|
return;
|
|
261
266
|
}
|
|
262
|
-
// Only harvest when more than some threshold of nodes are pending, after the very first harvest.
|
|
263
|
-
if (this.ptid && this.nodeCount <= REQ_THRESHOLD_TO_SEND) return;
|
|
264
267
|
} else {
|
|
265
268
|
// -- *cli May '26 - Update: Not rate limiting backgrounded pages either for now.
|
|
266
269
|
// if (this.ptid && document.visibilityState === 'hidden' && this.nodeCount <= REQ_THRESHOLD_TO_SEND) return
|
|
@@ -450,6 +453,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
450
453
|
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
|
|
451
454
|
if (openedSpace == 0) return;
|
|
452
455
|
}
|
|
456
|
+
if (this.isStandalone && (0, _now.now)() >= MAX_TRACE_DURATION) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
453
459
|
if (this.trace[stn.n]) this.trace[stn.n].push(stn);else this.trace[stn.n] = [stn];
|
|
454
460
|
this.nodeCount++;
|
|
455
461
|
}
|
|
@@ -407,7 +407,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
407
407
|
(0, _registerHandler.registerHandler)(FETCH_DONE, function (err, res) {
|
|
408
408
|
var node = this[SPA_NODE];
|
|
409
409
|
if (node) {
|
|
410
|
-
if (err) {
|
|
410
|
+
if (err || !(0, _denyList.shouldCollectEvent)(this.params)) {
|
|
411
411
|
node.cancel();
|
|
412
412
|
return;
|
|
413
413
|
}
|
|
@@ -56,6 +56,18 @@ class AgentBase {
|
|
|
56
56
|
(0, _console.warn)('Call to agent api setUserId failed. The js errors feature is not currently initialized.');
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Adds a user-defined application version string to subsequent events on the page.
|
|
61
|
+
* This decorates all payloads with an attribute of `application.version` which is queryable in NR1.
|
|
62
|
+
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setapplicationversion/}
|
|
63
|
+
* @param {string|null} value A string identifier for the application version, useful for
|
|
64
|
+
* tying all browser events to a specific release tag. The value parameter does not
|
|
65
|
+
* have to be unique. Passing a null value unsets any existing value.
|
|
66
|
+
*/
|
|
67
|
+
setApplicationVersion(value) {
|
|
68
|
+
(0, _console.warn)('Call to agent api setApplicationVersion failed. The agent is not currently initialized.');
|
|
69
|
+
}
|
|
70
|
+
|
|
59
71
|
/**
|
|
60
72
|
* Allows selective ignoring and grouping of known errors that the browser agent captures.
|
|
61
73
|
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/seterrorhandler/}
|
|
@@ -26,7 +26,7 @@ const CUSTOM_ATTR_GROUP = 'CUSTOM/'; // the subgroup items should be stored unde
|
|
|
26
26
|
exports.CUSTOM_ATTR_GROUP = CUSTOM_ATTR_GROUP;
|
|
27
27
|
function setTopLevelCallers() {
|
|
28
28
|
const nr = (0, _nreum.gosCDN)();
|
|
29
|
-
const funcs = ['setErrorHandler', 'finished', 'addToTrace', 'inlineHit', 'addRelease', 'addPageAction', 'setCurrentRouteName', 'setPageViewName', 'setCustomAttribute', 'interaction', 'noticeError', 'setUserId'];
|
|
29
|
+
const funcs = ['setErrorHandler', 'finished', 'addToTrace', 'inlineHit', 'addRelease', 'addPageAction', 'setCurrentRouteName', 'setPageViewName', 'setCustomAttribute', 'interaction', 'noticeError', 'setUserId', 'setApplicationVersion'];
|
|
30
30
|
funcs.forEach(f => {
|
|
31
31
|
nr[f] = function () {
|
|
32
32
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
@@ -115,6 +115,19 @@ function setAPI(agentIdentifier, forceDrain) {
|
|
|
115
115
|
}
|
|
116
116
|
return appendJsAttribute('enduser.id', value, 'setUserId', true);
|
|
117
117
|
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Attach the 'applcation.version' attribute onto agent payloads. This may be used in NR queries to group all browser events by a specific customer-defined release.
|
|
121
|
+
* @param {string|null} value - Application version -- if null, will "unset" the value
|
|
122
|
+
* @returns @see apiCall
|
|
123
|
+
*/
|
|
124
|
+
apiInterface.setApplicationVersion = function (value) {
|
|
125
|
+
if (!(typeof value === 'string' || value === null)) {
|
|
126
|
+
(0, _console.warn)("Failed to execute setApplicationVersion. Expected <String | null>, but got <".concat(typeof value, ">."));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
return appendJsAttribute('application.version', value, 'setApplicationVersion', false);
|
|
130
|
+
};
|
|
118
131
|
apiInterface.interaction = function () {
|
|
119
132
|
return new InteractionHandle().get();
|
|
120
133
|
};
|