@newrelic/browser-agent 1.285.0 → 1.286.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 +15 -0
- package/README.md +6 -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/dom/selector-path.js +1 -1
- package/dist/cjs/common/harvest/harvester.js +1 -1
- package/dist/cjs/common/util/feature-flags.js +2 -1
- package/dist/cjs/features/session_replay/shared/recorder.js +5 -0
- package/dist/cjs/features/session_trace/aggregate/trace/storage.js +3 -2
- package/dist/cjs/features/utils/aggregate-base.js +2 -4
- package/dist/cjs/features/utils/event-store-manager.js +1 -1
- package/dist/cjs/features/utils/nr1-debugger.js +1 -1
- package/dist/cjs/loaders/agent-base.js +1 -1
- package/dist/cjs/loaders/agent.js +3 -1
- package/dist/cjs/loaders/api/api.js +57 -61
- package/dist/cjs/loaders/api/apiAsync.js +19 -22
- package/dist/cjs/loaders/configure/configure.js +12 -15
- package/dist/cjs/loaders/micro-agent-base.js +1 -1
- package/dist/cjs/loaders/micro-agent.js +3 -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/dom/selector-path.js +1 -1
- package/dist/esm/common/harvest/harvester.js +1 -1
- package/dist/esm/common/util/feature-flags.js +2 -1
- package/dist/esm/features/session_replay/shared/recorder.js +5 -0
- package/dist/esm/features/session_trace/aggregate/trace/storage.js +3 -2
- package/dist/esm/features/utils/aggregate-base.js +2 -4
- package/dist/esm/features/utils/event-store-manager.js +1 -1
- package/dist/esm/features/utils/nr1-debugger.js +1 -1
- package/dist/esm/loaders/agent-base.js +1 -1
- package/dist/esm/loaders/agent.js +3 -1
- package/dist/esm/loaders/api/api.js +56 -60
- package/dist/esm/loaders/api/apiAsync.js +14 -17
- package/dist/esm/loaders/configure/configure.js +13 -16
- package/dist/esm/loaders/micro-agent-base.js +1 -1
- package/dist/esm/loaders/micro-agent.js +3 -1
- package/dist/types/common/dom/selector-path.d.ts.map +1 -1
- package/dist/types/common/util/feature-flags.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/loaders/agent.d.ts +1 -0
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts +1 -20
- package/dist/types/loaders/api/api.d.ts.map +1 -1
- package/dist/types/loaders/api/apiAsync.d.ts +1 -1
- package/dist/types/loaders/api/apiAsync.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/micro-agent.d.ts +1 -0
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/common/dom/selector-path.js +1 -3
- package/src/common/harvest/harvester.js +1 -1
- package/src/common/util/feature-flags.js +2 -1
- package/src/features/session_replay/shared/recorder.js +5 -0
- package/src/features/session_trace/aggregate/trace/storage.js +2 -2
- package/src/features/utils/aggregate-base.js +2 -2
- package/src/features/utils/event-store-manager.js +1 -1
- package/src/features/utils/nr1-debugger.js +1 -1
- package/src/loaders/agent-base.js +2 -2
- package/src/loaders/agent.js +4 -1
- package/src/loaders/api/api.js +56 -60
- package/src/loaders/api/apiAsync.js +14 -18
- package/src/loaders/configure/configure.js +12 -12
- package/src/loaders/micro-agent-base.js +2 -2
- package/src/loaders/micro-agent.js +4 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Sets or re-sets the agent's configuration values from global settings. This also attach those as properties to the agent instance.
|
|
3
|
+
* IMPORTANT: setNREUMInitializedAgent must be called on the agent prior to calling this function.
|
|
3
4
|
*/
|
|
4
5
|
export function configure(agent: any, opts: {} | undefined, loaderType: any, forceDrain: any): void;
|
|
5
6
|
//# sourceMappingURL=configure.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../../../src/loaders/configure/configure.js"],"names":[],"mappings":"AAkBA
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../../../src/loaders/configure/configure.js"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,oGA8DC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"micro-agent.d.ts","sourceRoot":"","sources":["../../../src/loaders/micro-agent.js"],"names":[],"mappings":"AAsBA;;;;GAIG;AACH;IACE;;OAEG;IACH,qBAFW,OAAO,SAAS,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"micro-agent.d.ts","sourceRoot":"","sources":["../../../src/loaders/micro-agent.js"],"names":[],"mappings":"AAsBA;;;;GAIG;AACH;IACE;;OAEG;IACH,qBAFW,OAAO,SAAS,EAAE,YAAY,EAqDxC;IAhDC,aAAkB;IAKlB;;;;OAIG;IACH,uBAFW,MAAM,GAAC,MAAM,EAAE,aAqCzB;IAKH;;;;;MAOC;IAED,gBAEC;CACF;+BAnF8B,oBAAoB"}
|
package/package.json
CHANGED
|
@@ -34,9 +34,7 @@ export const generateSelectorPath = (elem, targetFields = []) => {
|
|
|
34
34
|
try {
|
|
35
35
|
while (elem?.tagName) {
|
|
36
36
|
const { id, localName } = elem
|
|
37
|
-
targetFields.forEach(field => {
|
|
38
|
-
nearestFields[nearestAttrName(field)] ||= elem[field]
|
|
39
|
-
})
|
|
37
|
+
targetFields.forEach(field => { nearestFields[nearestAttrName(field)] ||= (elem[field]?.baseVal || elem[field]) })
|
|
40
38
|
const selector = [
|
|
41
39
|
localName,
|
|
42
40
|
id ? `#${id}` : '',
|
|
@@ -178,7 +178,7 @@ function send (agentRef, { endpoint, targetApp, payload, localOpts = {}, submitM
|
|
|
178
178
|
|
|
179
179
|
dispatchGlobalEvent({
|
|
180
180
|
agentIdentifier: agentRef.agentIdentifier,
|
|
181
|
-
|
|
181
|
+
drained: !!activatedFeatures?.[agentRef.agentIdentifier],
|
|
182
182
|
type: 'data',
|
|
183
183
|
name: 'harvest',
|
|
184
184
|
feature: featureName,
|
|
@@ -28,10 +28,11 @@ export function activateFeatures (flags, agentIdentifier) {
|
|
|
28
28
|
|
|
29
29
|
sentIds.add(agentIdentifier)
|
|
30
30
|
|
|
31
|
-
// let any window level subscribers know that the agent is running
|
|
31
|
+
// let any window level subscribers know that the agent is running, per install docs
|
|
32
32
|
dispatchGlobalEvent({
|
|
33
33
|
agentIdentifier,
|
|
34
34
|
loaded: true,
|
|
35
|
+
drained: true,
|
|
35
36
|
type: 'lifecycle',
|
|
36
37
|
name: 'load',
|
|
37
38
|
feature: undefined,
|
|
@@ -14,6 +14,8 @@ import { FEATURE_NAMES } from '../../../loaders/features/features'
|
|
|
14
14
|
import { buildNRMetaNode, customMasker } from './utils'
|
|
15
15
|
import { IDEAL_PAYLOAD_SIZE } from '../../../common/constants/agent-constants'
|
|
16
16
|
import { AggregateBase } from '../../utils/aggregate-base'
|
|
17
|
+
import { warn } from '../../../common/util/console'
|
|
18
|
+
import { single } from '../../../common/util/invoke'
|
|
17
19
|
|
|
18
20
|
export class Recorder {
|
|
19
21
|
/** Each page mutation or event will be stored (raw) in this array. This array will be cleared on each harvest */
|
|
@@ -25,6 +27,8 @@ export class Recorder {
|
|
|
25
27
|
/** flag that if true, blocks events from being "stored". Only set to true when a full snapshot has incomplete nodes (only stylesheets ATM) */
|
|
26
28
|
#fixing = false
|
|
27
29
|
|
|
30
|
+
#warnCSSOnce = single(() => warn(47)) // notifies user of potential replayer issue if fix_stylesheets is off
|
|
31
|
+
|
|
28
32
|
constructor (parent) {
|
|
29
33
|
this.#events = new RecorderEvents()
|
|
30
34
|
this.#backloggedEvents = new RecorderEvents()
|
|
@@ -120,6 +124,7 @@ export class Recorder {
|
|
|
120
124
|
if (!this.shouldFix) {
|
|
121
125
|
if (incompletes > 0) {
|
|
122
126
|
this.currentBufferTarget.inlinedAllStylesheets = false
|
|
127
|
+
this.#warnCSSOnce()
|
|
123
128
|
handle(SUPPORTABILITY_METRIC_CHANNEL, [missingInlineSMTag + 'Skipped', incompletes], undefined, FEATURE_NAMES.metrics, this.parent.ee)
|
|
124
129
|
}
|
|
125
130
|
return this.store(event, isCheckout)
|
|
@@ -15,7 +15,7 @@ const SUPPORTS_PERFORMANCE_OBSERVER = typeof globalScope.PerformanceObserver ===
|
|
|
15
15
|
|
|
16
16
|
const ignoredEvents = {
|
|
17
17
|
// we find that certain events make the data too noisy to be useful
|
|
18
|
-
global: { mouseup: true, mousedown: true },
|
|
18
|
+
global: { mouseup: true, mousedown: true, mousemove: true },
|
|
19
19
|
// certain events are present both in the window and in PVT metrics. PVT metrics are prefered so the window events should be ignored
|
|
20
20
|
window: { load: true, pagehide: true },
|
|
21
21
|
// when ajax instrumentation is disabled, all XMLHttpRequest events will return with origin = xhrOriginMissing and should be ignored
|
|
@@ -182,8 +182,8 @@ export class TraceStorage {
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
shouldIgnoreEvent (event, target) {
|
|
185
|
-
const origin = eventOrigin(event.target, target, this.parent.ee)
|
|
186
185
|
if (event.type in ignoredEvents.global) return true
|
|
186
|
+
const origin = eventOrigin(event.target, target, this.parent.ee)
|
|
187
187
|
if (!!ignoredEvents[origin] && ignoredEvents[origin].ignoreAll) return true
|
|
188
188
|
return !!(!!ignoredEvents[origin] && event.type in ignoredEvents[origin])
|
|
189
189
|
}
|
|
@@ -136,14 +136,14 @@ export class AggregateBase extends FeatureBase {
|
|
|
136
136
|
} catch (err) {
|
|
137
137
|
// do nothing
|
|
138
138
|
}
|
|
139
|
-
configure(
|
|
139
|
+
configure(existingAgent, {
|
|
140
140
|
...cdn,
|
|
141
141
|
info: {
|
|
142
142
|
...cdn.info,
|
|
143
143
|
jsAttributes
|
|
144
144
|
},
|
|
145
145
|
runtime: existingAgent.runtime
|
|
146
|
-
})
|
|
146
|
+
}, existingAgent.runtime.loaderType)
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -53,7 +53,7 @@ export class EventStoreManager {
|
|
|
53
53
|
add (event, target) {
|
|
54
54
|
dispatchGlobalEvent({
|
|
55
55
|
agentIdentifier: this.agentIdentifier,
|
|
56
|
-
|
|
56
|
+
drained: !!activatedFeatures?.[this.agentIdentifier],
|
|
57
57
|
type: 'data',
|
|
58
58
|
name: 'buffer',
|
|
59
59
|
feature: this.featureName,
|
|
@@ -7,7 +7,7 @@ import { gosCDN } from '../../common/window/nreum'
|
|
|
7
7
|
const debugId = 1
|
|
8
8
|
const newrelic = gosCDN()
|
|
9
9
|
export function debugNR1 (agentIdentifier, location, event, otherprops = {}, debugName = 'SR') {
|
|
10
|
-
const api = agentIdentifier ? newrelic.initializedAgents[agentIdentifier].
|
|
10
|
+
const api = agentIdentifier ? newrelic.initializedAgents[agentIdentifier].addPageAction : newrelic.addPageAction
|
|
11
11
|
let url
|
|
12
12
|
try {
|
|
13
13
|
const locURL = new URL(window.location)
|
|
@@ -20,8 +20,8 @@ export class AgentBase extends MicroAgentBase {
|
|
|
20
20
|
* @param {...any} args
|
|
21
21
|
*/
|
|
22
22
|
#callMethod (methodName, ...args) {
|
|
23
|
-
if (
|
|
24
|
-
else return this
|
|
23
|
+
if (this[methodName] === AgentBase.prototype[methodName] || this[methodName] === MicroAgentBase.prototype[methodName]) warn(35, methodName)
|
|
24
|
+
else return this[methodName](...args)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
package/src/loaders/agent.js
CHANGED
|
@@ -72,6 +72,10 @@ export class Agent extends AgentBase {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
get api () {
|
|
76
|
+
return this
|
|
77
|
+
}
|
|
78
|
+
|
|
75
79
|
run () {
|
|
76
80
|
// Attempt to initialize all the requested features (sequentially in prio order & synchronously), with any failure aborting the whole process.
|
|
77
81
|
try {
|
|
@@ -102,7 +106,6 @@ export class Agent extends AgentBase {
|
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
const newrelic = gosNREUM()
|
|
105
|
-
delete newrelic.initializedAgents[this.agentIdentifier]?.api // prevent further calls to agent-specific APIs (see "configure.js")
|
|
106
109
|
delete newrelic.initializedAgents[this.agentIdentifier]?.features // GC mem used internally by features
|
|
107
110
|
delete this.sharedAggregator
|
|
108
111
|
// Keep the initialized agent object with its configs for troubleshooting purposes.
|
package/src/loaders/api/api.js
CHANGED
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { FEATURE_NAMES } from '../features/features'
|
|
6
|
-
import {
|
|
7
|
-
import { getRuntime } from '../../common/config/runtime'
|
|
6
|
+
import { setInfo } from '../../common/config/info'
|
|
8
7
|
import { handle } from '../../common/event-emitter/handle'
|
|
9
|
-
import { ee } from '../../common/event-emitter/contextual-ee'
|
|
10
8
|
import { drain, registerDrain } from '../../common/drain/drain'
|
|
11
9
|
import { onWindowLoad } from '../../common/window/load'
|
|
12
10
|
import { isBrowserScope } from '../../common/constants/runtime'
|
|
@@ -31,55 +29,53 @@ export function setTopLevelCallers () {
|
|
|
31
29
|
|
|
32
30
|
function caller (fnName, ...args) {
|
|
33
31
|
let returnVals = []
|
|
34
|
-
Object.values(nr.initializedAgents).forEach(
|
|
35
|
-
if (!
|
|
32
|
+
Object.values(nr.initializedAgents).forEach(agt => {
|
|
33
|
+
if (!agt || !agt.runtime) {
|
|
36
34
|
warn(38, fnName)
|
|
37
|
-
} else if (
|
|
38
|
-
returnVals.push(
|
|
35
|
+
} else if (agt.exposed && agt[fnName] && agt.runtime.loaderType !== 'micro-agent') {
|
|
36
|
+
returnVals.push(agt[fnName](...args))
|
|
39
37
|
}
|
|
40
38
|
})
|
|
41
|
-
return returnVals
|
|
39
|
+
return returnVals[0]
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
const replayRunning = {}
|
|
46
44
|
|
|
47
|
-
export function setAPI (
|
|
48
|
-
if (!forceDrain) registerDrain(agentIdentifier, 'api')
|
|
49
|
-
const
|
|
50
|
-
var instanceEE = ee.get(agentIdentifier)
|
|
51
|
-
var tracerEE = instanceEE.get('tracer')
|
|
45
|
+
export function setAPI (agent, forceDrain) {
|
|
46
|
+
if (!forceDrain) registerDrain(agent.agentIdentifier, 'api')
|
|
47
|
+
const tracerEE = agent.ee.get('tracer')
|
|
52
48
|
|
|
53
|
-
replayRunning[agentIdentifier] = MODE.OFF
|
|
49
|
+
replayRunning[agent.agentIdentifier] = MODE.OFF
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
replayRunning[agentIdentifier] = isRunning
|
|
51
|
+
agent.ee.on(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, (isRunning) => {
|
|
52
|
+
replayRunning[agent.agentIdentifier] = isRunning
|
|
57
53
|
})
|
|
58
54
|
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
const prefix = 'api-'
|
|
56
|
+
const spaPrefix = prefix + 'ixn-'
|
|
61
57
|
|
|
62
|
-
|
|
63
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/log/called'], undefined, FEATURE_NAMES.metrics,
|
|
64
|
-
bufferLog(
|
|
58
|
+
agent.log = function (message, { customAttributes = {}, level = LOG_LEVELS.INFO } = {}) {
|
|
59
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/log/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
|
|
60
|
+
bufferLog(agent.ee, message, customAttributes, level)
|
|
65
61
|
}
|
|
66
62
|
|
|
67
|
-
|
|
68
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/wrapLogger/called'], undefined, FEATURE_NAMES.metrics,
|
|
69
|
-
wrapLogger(
|
|
63
|
+
agent.wrapLogger = (parent, functionName, { customAttributes = {}, level = LOG_LEVELS.INFO } = {}) => {
|
|
64
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/wrapLogger/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
|
|
65
|
+
wrapLogger(agent.ee, parent, functionName, { customAttributes, level })
|
|
70
66
|
}
|
|
71
67
|
|
|
72
68
|
// Setup stub functions that queue calls for later processing.
|
|
73
|
-
asyncApiMethods.forEach(fnName => {
|
|
69
|
+
asyncApiMethods.forEach(fnName => { agent[fnName] = apiCall(prefix, fnName, true, 'api') })
|
|
74
70
|
|
|
75
|
-
|
|
71
|
+
agent.addPageAction = apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.genericEvents)
|
|
76
72
|
|
|
77
|
-
|
|
73
|
+
agent.recordCustomEvent = apiCall(prefix, 'recordCustomEvent', true, FEATURE_NAMES.genericEvents)
|
|
78
74
|
|
|
79
|
-
|
|
75
|
+
agent.setPageViewName = function (name, host) {
|
|
80
76
|
if (typeof name !== 'string') return
|
|
81
77
|
if (name.charAt(0) !== '/') name = '/' + name
|
|
82
|
-
|
|
78
|
+
agent.runtime.customTransaction = (host || 'http://custom.transaction') + name
|
|
83
79
|
return apiCall(prefix, 'setPageViewName', true)()
|
|
84
80
|
}
|
|
85
81
|
|
|
@@ -92,15 +88,15 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
|
|
|
92
88
|
* @returns @see apiCall
|
|
93
89
|
*/
|
|
94
90
|
function appendJsAttribute (key, value, apiName, addToBrowserStorage) {
|
|
95
|
-
const currentInfo =
|
|
91
|
+
const currentInfo = agent.info
|
|
96
92
|
if (value === null) {
|
|
97
93
|
delete currentInfo.jsAttributes[key]
|
|
98
94
|
} else {
|
|
99
|
-
setInfo(agentIdentifier, { ...currentInfo, jsAttributes: { ...currentInfo.jsAttributes, [key]: value } })
|
|
95
|
+
setInfo(agent.agentIdentifier, { ...currentInfo, jsAttributes: { ...currentInfo.jsAttributes, [key]: value } })
|
|
100
96
|
}
|
|
101
97
|
return apiCall(prefix, apiName, true, (!!addToBrowserStorage || value === null) ? 'session' : undefined)(key, value)
|
|
102
98
|
}
|
|
103
|
-
|
|
99
|
+
agent.setCustomAttribute = function (name, value, persistAttribute = false) {
|
|
104
100
|
if (typeof name !== 'string') {
|
|
105
101
|
warn(39, typeof name)
|
|
106
102
|
return
|
|
@@ -116,7 +112,7 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
|
|
|
116
112
|
* @param {string} value - unique user identifier; a null user id suggests none should exist
|
|
117
113
|
* @returns @see apiCall
|
|
118
114
|
*/
|
|
119
|
-
|
|
115
|
+
agent.setUserId = function (value) {
|
|
120
116
|
if (!(typeof value === 'string' || value === null)) {
|
|
121
117
|
warn(41, typeof value)
|
|
122
118
|
return
|
|
@@ -129,7 +125,7 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
|
|
|
129
125
|
* @param {string|null} value - Application version -- if null, will "unset" the value
|
|
130
126
|
* @returns @see apiCall
|
|
131
127
|
*/
|
|
132
|
-
|
|
128
|
+
agent.setApplicationVersion = function (value) {
|
|
133
129
|
if (!(typeof value === 'string' || value === null)) {
|
|
134
130
|
warn(42, typeof value)
|
|
135
131
|
return
|
|
@@ -137,26 +133,26 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
|
|
|
137
133
|
return appendJsAttribute('application.version', value, 'setApplicationVersion', false)
|
|
138
134
|
}
|
|
139
135
|
|
|
140
|
-
|
|
136
|
+
agent.start = () => {
|
|
141
137
|
try {
|
|
142
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/start/called'], undefined, FEATURE_NAMES.metrics,
|
|
143
|
-
|
|
138
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/start/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
|
|
139
|
+
agent.ee.emit('manual-start-all')
|
|
144
140
|
} catch (err) {
|
|
145
141
|
warn(23, err)
|
|
146
142
|
}
|
|
147
143
|
}
|
|
148
144
|
|
|
149
|
-
|
|
150
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/recordReplay/called'], undefined, FEATURE_NAMES.metrics,
|
|
151
|
-
handle(SR_EVENT_EMITTER_TYPES.RECORD, [], undefined, FEATURE_NAMES.sessionReplay,
|
|
145
|
+
agent[SR_EVENT_EMITTER_TYPES.RECORD] = function () {
|
|
146
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/recordReplay/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
|
|
147
|
+
handle(SR_EVENT_EMITTER_TYPES.RECORD, [], undefined, FEATURE_NAMES.sessionReplay, agent.ee)
|
|
152
148
|
}
|
|
153
149
|
|
|
154
|
-
|
|
155
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/pauseReplay/called'], undefined, FEATURE_NAMES.metrics,
|
|
156
|
-
handle(SR_EVENT_EMITTER_TYPES.PAUSE, [], undefined, FEATURE_NAMES.sessionReplay,
|
|
150
|
+
agent[SR_EVENT_EMITTER_TYPES.PAUSE] = function () {
|
|
151
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/pauseReplay/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
|
|
152
|
+
handle(SR_EVENT_EMITTER_TYPES.PAUSE, [], undefined, FEATURE_NAMES.sessionReplay, agent.ee)
|
|
157
153
|
}
|
|
158
154
|
|
|
159
|
-
|
|
155
|
+
agent.interaction = function (options) {
|
|
160
156
|
return new InteractionHandle().get(typeof options === 'object' ? options : {})
|
|
161
157
|
}
|
|
162
158
|
|
|
@@ -167,9 +163,9 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
|
|
|
167
163
|
var contextStore = {}
|
|
168
164
|
var ixn = this
|
|
169
165
|
var hasCb = typeof cb === 'function'
|
|
170
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/createTracer/called'], undefined, FEATURE_NAMES.metrics,
|
|
166
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/createTracer/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
|
|
171
167
|
// Soft navigations won't support Tracer nodes, but this fn should still work the same otherwise (e.g., run the orig cb).
|
|
172
|
-
if (!runSoftNavOverSpa) handle(spaPrefix + 'tracer', [now(), name, contextStore], ixn, FEATURE_NAMES.spa,
|
|
168
|
+
if (!agent.runSoftNavOverSpa) handle(spaPrefix + 'tracer', [now(), name, contextStore], ixn, FEATURE_NAMES.spa, agent.ee)
|
|
173
169
|
return function () {
|
|
174
170
|
tracerEE.emit((hasCb ? '' : 'no-') + 'fn-start', [now(), ixn, hasCb], contextStore)
|
|
175
171
|
if (hasCb) {
|
|
@@ -189,30 +185,30 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
|
|
|
189
185
|
}
|
|
190
186
|
|
|
191
187
|
;['actionText', 'setName', 'setAttribute', 'save', 'ignore', 'onEnd', 'getContext', 'end', 'get'].forEach(name => {
|
|
192
|
-
InteractionApiProto[name] = apiCall(spaPrefix, name, undefined, runSoftNavOverSpa ? FEATURE_NAMES.softNav : FEATURE_NAMES.spa)
|
|
188
|
+
InteractionApiProto[name] = apiCall(spaPrefix, name, undefined, agent.runSoftNavOverSpa ? FEATURE_NAMES.softNav : FEATURE_NAMES.spa)
|
|
193
189
|
})
|
|
194
|
-
|
|
190
|
+
agent.setCurrentRouteName = agent.runSoftNavOverSpa ? apiCall(spaPrefix, 'routeName', undefined, FEATURE_NAMES.softNav) : apiCall(prefix, 'routeName', true, FEATURE_NAMES.spa)
|
|
195
191
|
|
|
196
192
|
function apiCall (prefix, name, notSpa, bufferGroup) {
|
|
197
193
|
return function () {
|
|
198
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, FEATURE_NAMES.metrics,
|
|
194
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
|
|
199
195
|
dispatchGlobalEvent({
|
|
200
|
-
agentIdentifier,
|
|
201
|
-
|
|
196
|
+
agentIdentifier: agent.agentIdentifier,
|
|
197
|
+
drained: !!activatedFeatures?.[agent.agentIdentifier],
|
|
202
198
|
type: 'data',
|
|
203
199
|
name: 'api',
|
|
204
200
|
feature: prefix + name,
|
|
205
201
|
data: { notSpa, bufferGroup }
|
|
206
202
|
})
|
|
207
|
-
if (bufferGroup) handle(prefix + name, [notSpa ? now() : performance.now(), ...arguments], notSpa ? null : this, bufferGroup,
|
|
203
|
+
if (bufferGroup) handle(prefix + name, [notSpa ? now() : performance.now(), ...arguments], notSpa ? null : this, bufferGroup, agent.ee) // no bufferGroup means only the SM is emitted
|
|
208
204
|
return notSpa ? undefined : this // returns the InteractionHandle which allows these methods to be chained
|
|
209
205
|
}
|
|
210
206
|
}
|
|
211
207
|
|
|
212
|
-
|
|
208
|
+
agent.noticeError = function (err, customAttributes) {
|
|
213
209
|
if (typeof err === 'string') err = new Error(err)
|
|
214
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, FEATURE_NAMES.metrics,
|
|
215
|
-
handle('err', [err, now(), false, customAttributes, !!replayRunning[agentIdentifier]], undefined, FEATURE_NAMES.jserrors,
|
|
210
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
|
|
211
|
+
handle('err', [err, now(), false, customAttributes, !!replayRunning[agent.agentIdentifier]], undefined, FEATURE_NAMES.jserrors, agent.ee)
|
|
216
212
|
}
|
|
217
213
|
|
|
218
214
|
// theres no window.load event on non-browser scopes, lazy load immediately
|
|
@@ -221,14 +217,14 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
|
|
|
221
217
|
else onWindowLoad(() => lazyLoad(), true)
|
|
222
218
|
|
|
223
219
|
function lazyLoad () {
|
|
224
|
-
import(/* webpackChunkName: "async-api" */'./apiAsync').then(({
|
|
225
|
-
|
|
226
|
-
drain(agentIdentifier, 'api')
|
|
220
|
+
import(/* webpackChunkName: "async-api" */'./apiAsync').then(({ setAsyncAPI }) => {
|
|
221
|
+
setAsyncAPI(agent)
|
|
222
|
+
drain(agent.agentIdentifier, 'api')
|
|
227
223
|
}).catch((err) => {
|
|
228
224
|
warn(27, err)
|
|
229
|
-
|
|
225
|
+
agent.ee.abort()
|
|
230
226
|
})
|
|
231
227
|
}
|
|
232
228
|
|
|
233
|
-
return
|
|
229
|
+
return true
|
|
234
230
|
}
|
|
@@ -3,18 +3,14 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { FEATURE_NAMES } from '../features/features'
|
|
6
|
-
import { getRuntime } from '../../common/config/runtime'
|
|
7
|
-
import { ee } from '../../common/event-emitter/contextual-ee'
|
|
8
6
|
import { handle } from '../../common/event-emitter/handle'
|
|
9
7
|
import { registerHandler } from '../../common/event-emitter/register-handler'
|
|
10
8
|
import { single } from '../../common/util/invoke'
|
|
11
9
|
import { CUSTOM_METRIC_CHANNEL } from '../../features/metrics/constants'
|
|
12
10
|
import { originTime } from '../../common/constants/runtime'
|
|
13
11
|
|
|
14
|
-
export function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
var api = {
|
|
12
|
+
export function setAsyncAPI (agent) {
|
|
13
|
+
const api = {
|
|
18
14
|
finished: single(finished),
|
|
19
15
|
setErrorHandler,
|
|
20
16
|
addToTrace,
|
|
@@ -22,22 +18,22 @@ export function setAPI (agentIdentifier) {
|
|
|
22
18
|
}
|
|
23
19
|
|
|
24
20
|
// Hook all of the api functions up to the queues/stubs created in loader/api.js
|
|
25
|
-
Object.entries(api).forEach(([fnName, fnCall]) => registerHandler('api-' + fnName, fnCall, 'api',
|
|
21
|
+
Object.entries(api).forEach(([fnName, fnCall]) => registerHandler('api-' + fnName, fnCall, 'api', agent.ee))
|
|
26
22
|
|
|
27
23
|
// All API functions get passed the time they were called as their
|
|
28
24
|
// first parameter. These functions can be called asynchronously.
|
|
29
25
|
|
|
30
26
|
function finished (t, providedTime) {
|
|
31
|
-
|
|
32
|
-
handle(CUSTOM_METRIC_CHANNEL, ['finished', { time }], undefined, FEATURE_NAMES.metrics,
|
|
27
|
+
const time = providedTime ? providedTime - originTime : t
|
|
28
|
+
handle(CUSTOM_METRIC_CHANNEL, ['finished', { time }], undefined, FEATURE_NAMES.metrics, agent.ee)
|
|
33
29
|
addToTrace(t, { name: 'finished', start: time + originTime, origin: 'nr' })
|
|
34
|
-
handle('api-addPageAction', [time, 'finished'], undefined, FEATURE_NAMES.genericEvents,
|
|
30
|
+
handle('api-addPageAction', [time, 'finished'], undefined, FEATURE_NAMES.genericEvents, agent.ee)
|
|
35
31
|
}
|
|
36
32
|
|
|
37
|
-
function addToTrace (
|
|
33
|
+
function addToTrace (_, evt) {
|
|
38
34
|
if (!(evt && typeof evt === 'object' && evt.name && evt.start)) return
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
const report = {
|
|
41
37
|
n: evt.name,
|
|
42
38
|
s: evt.start - originTime,
|
|
43
39
|
e: (evt.end || evt.start) - originTime,
|
|
@@ -45,16 +41,16 @@ export function setAPI (agentIdentifier) {
|
|
|
45
41
|
t: 'api'
|
|
46
42
|
}
|
|
47
43
|
|
|
48
|
-
handle('bstApi', [report], undefined, FEATURE_NAMES.sessionTrace,
|
|
44
|
+
handle('bstApi', [report], undefined, FEATURE_NAMES.sessionTrace, agent.ee)
|
|
49
45
|
}
|
|
50
46
|
|
|
51
|
-
function setErrorHandler (
|
|
52
|
-
|
|
47
|
+
function setErrorHandler (_, handler) {
|
|
48
|
+
agent.runtime.onerror = handler
|
|
53
49
|
}
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
function addRelease (
|
|
51
|
+
let releaseCount = 0
|
|
52
|
+
function addRelease (_, name, id) {
|
|
57
53
|
if (++releaseCount > 10) return
|
|
58
|
-
|
|
54
|
+
agent.runtime.releaseIds[name.slice(-200)] = ('' + id).slice(-200)
|
|
59
55
|
}
|
|
60
56
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { setAPI, setTopLevelCallers } from '../api/api'
|
|
6
6
|
import { addToNREUM, gosCDN } from '../../common/window/nreum'
|
|
7
7
|
import { setInfo } from '../../common/config/info'
|
|
8
|
-
import {
|
|
8
|
+
import { setConfiguration } from '../../common/config/init'
|
|
9
9
|
import { setLoaderConfig } from '../../common/config/loader-config'
|
|
10
10
|
import { setRuntime } from '../../common/config/runtime'
|
|
11
11
|
import { activatedFeatures } from '../../common/util/feature-flags'
|
|
@@ -14,10 +14,11 @@ import { redefinePublicPath } from './public-path'
|
|
|
14
14
|
import { ee } from '../../common/event-emitter/contextual-ee'
|
|
15
15
|
import { dispatchGlobalEvent } from '../../common/dispatch/global-event'
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const alreadySetOnce = new Set() // the configure() function can run multiple times in agent lifecycle for different agents
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Sets or re-sets the agent's configuration values from global settings. This also attach those as properties to the agent instance.
|
|
21
|
+
* IMPORTANT: setNREUMInitializedAgent must be called on the agent prior to calling this function.
|
|
21
22
|
*/
|
|
22
23
|
export function configure (agent, opts = {}, loaderType, forceDrain) {
|
|
23
24
|
// eslint-disable-next-line camelcase
|
|
@@ -41,10 +42,10 @@ export function configure (agent, opts = {}, loaderType, forceDrain) {
|
|
|
41
42
|
}
|
|
42
43
|
setInfo(agent.agentIdentifier, info)
|
|
43
44
|
|
|
44
|
-
const updatedInit =
|
|
45
|
+
const updatedInit = agent.init
|
|
45
46
|
const internalTrafficList = [info.beacon, info.errorBeacon]
|
|
46
47
|
|
|
47
|
-
if (!alreadySetOnce) {
|
|
48
|
+
if (!alreadySetOnce.has(agent.agentIdentifier)) {
|
|
48
49
|
if (updatedInit.proxy.assets) {
|
|
49
50
|
redefinePublicPath(updatedInit.proxy.assets)
|
|
50
51
|
internalTrafficList.push(updatedInit.proxy.assets)
|
|
@@ -65,21 +66,20 @@ export function configure (agent, opts = {}, loaderType, forceDrain) {
|
|
|
65
66
|
runtime.ptid = agent.agentIdentifier
|
|
66
67
|
setRuntime(agent.agentIdentifier, runtime)
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
if (!alreadySetOnce.has(agent.agentIdentifier)) {
|
|
70
|
+
agent.ee = ee.get(agent.agentIdentifier)
|
|
71
|
+
agent.exposed = exposed
|
|
72
|
+
setAPI(agent, forceDrain) // assign our API functions to the agent instance
|
|
69
73
|
|
|
70
|
-
if (agent.api === undefined) agent.api = setAPI(agent.agentIdentifier, forceDrain, agent.runSoftNavOverSpa)
|
|
71
|
-
if (agent.exposed === undefined) agent.exposed = exposed
|
|
72
|
-
|
|
73
|
-
if (!alreadySetOnce) {
|
|
74
74
|
dispatchGlobalEvent({
|
|
75
75
|
agentIdentifier: agent.agentIdentifier,
|
|
76
|
-
|
|
76
|
+
drained: !!activatedFeatures?.[agent.agentIdentifier],
|
|
77
77
|
type: 'lifecycle',
|
|
78
78
|
name: 'initialize',
|
|
79
79
|
feature: undefined,
|
|
80
|
-
data:
|
|
80
|
+
data: agent.config
|
|
81
81
|
})
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
alreadySetOnce
|
|
84
|
+
alreadySetOnce.add(agent.agentIdentifier)
|
|
85
85
|
}
|
|
@@ -18,8 +18,8 @@ export class MicroAgentBase {
|
|
|
18
18
|
* @param {...any} args
|
|
19
19
|
*/
|
|
20
20
|
#callMethod (methodName, ...args) {
|
|
21
|
-
if (
|
|
22
|
-
else return this
|
|
21
|
+
if (this[methodName] === MicroAgentBase.prototype[methodName]) warn(35, methodName)
|
|
22
|
+
else return this[methodName](...args)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// MicroAgent class custom defines its own start
|
|
@@ -36,7 +36,6 @@ export class MicroAgent extends MicroAgentBase {
|
|
|
36
36
|
setNREUMInitializedAgent(this.agentIdentifier, this)
|
|
37
37
|
|
|
38
38
|
configure(this, { ...options, runtime: { isolatedBacklog: true } }, options.loaderType || 'micro-agent')
|
|
39
|
-
Object.assign(this, this.api) // the APIs should be available at the class level for micro-agent
|
|
40
39
|
|
|
41
40
|
/**
|
|
42
41
|
* Starts a set of agent features if not running in "autoStart" mode
|
|
@@ -91,4 +90,8 @@ export class MicroAgent extends MicroAgentBase {
|
|
|
91
90
|
runtime: this.runtime
|
|
92
91
|
}
|
|
93
92
|
}
|
|
93
|
+
|
|
94
|
+
get api () {
|
|
95
|
+
return this
|
|
96
|
+
}
|
|
94
97
|
}
|