Skip to content

Commit 44786ae

Browse files
authored
feat: Erase .api property on agent instance (#1425)
1 parent 395c009 commit 44786ae

File tree

15 files changed

+264
-325
lines changed

15 files changed

+264
-325
lines changed

src/features/utils/aggregate-base.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,14 @@ export class AggregateBase extends FeatureBase {
136136
} catch (err) {
137137
// do nothing
138138
}
139-
configure({ agentIdentifier: this.agentIdentifier }, {
139+
configure(existingAgent, {
140140
...cdn,
141141
info: {
142142
...cdn.info,
143143
jsAttributes
144144
},
145145
runtime: existingAgent.runtime
146-
})
146+
}, existingAgent.runtime.loaderType)
147147
}
148148
}
149149

src/features/utils/nr1-debugger.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { gosCDN } from '../../common/window/nreum'
77
const debugId = 1
88
const newrelic = gosCDN()
99
export function debugNR1 (agentIdentifier, location, event, otherprops = {}, debugName = 'SR') {
10-
const api = agentIdentifier ? newrelic.initializedAgents[agentIdentifier].api.addPageAction : newrelic.addPageAction
10+
const api = agentIdentifier ? newrelic.initializedAgents[agentIdentifier].addPageAction : newrelic.addPageAction
1111
let url
1212
try {
1313
const locURL = new URL(window.location)

src/loaders/agent-base.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ export class AgentBase extends MicroAgentBase {
2020
* @param {...any} args
2121
*/
2222
#callMethod (methodName, ...args) {
23-
if (typeof this.api?.[methodName] !== 'function') warn(35, methodName)
24-
else return this.api[methodName](...args)
23+
if (this[methodName] === AgentBase.prototype[methodName] || this[methodName] === MicroAgentBase.prototype[methodName]) warn(35, methodName)
24+
else return this[methodName](...args)
2525
}
2626

2727
/**

src/loaders/agent.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ export class Agent extends AgentBase {
7272
}
7373
}
7474

75+
get api () {
76+
return this
77+
}
78+
7579
run () {
7680
// Attempt to initialize all the requested features (sequentially in prio order & synchronously), with any failure aborting the whole process.
7781
try {
@@ -102,7 +106,6 @@ export class Agent extends AgentBase {
102106
}
103107

104108
const newrelic = gosNREUM()
105-
delete newrelic.initializedAgents[this.agentIdentifier]?.api // prevent further calls to agent-specific APIs (see "configure.js")
106109
delete newrelic.initializedAgents[this.agentIdentifier]?.features // GC mem used internally by features
107110
delete this.sharedAggregator
108111
// Keep the initialized agent object with its configs for troubleshooting purposes.

src/loaders/api/api.js

+55-59
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55
import { FEATURE_NAMES } from '../features/features'
6-
import { getInfo, setInfo } from '../../common/config/info'
7-
import { getRuntime } from '../../common/config/runtime'
6+
import { setInfo } from '../../common/config/info'
87
import { handle } from '../../common/event-emitter/handle'
9-
import { ee } from '../../common/event-emitter/contextual-ee'
108
import { drain, registerDrain } from '../../common/drain/drain'
119
import { onWindowLoad } from '../../common/window/load'
1210
import { isBrowserScope } from '../../common/constants/runtime'
@@ -31,11 +29,11 @@ export function setTopLevelCallers () {
3129

3230
function caller (fnName, ...args) {
3331
let returnVals = []
34-
Object.values(nr.initializedAgents).forEach(val => {
35-
if (!val || !val.api || !val.runtime) {
32+
Object.values(nr.initializedAgents).forEach(agt => {
33+
if (!agt || !agt.runtime) {
3634
warn(38, fnName)
37-
} else if (val.exposed && val.api[fnName] && val.runtime.loaderType !== 'micro-agent') {
38-
returnVals.push(val.api[fnName](...args))
35+
} else if (agt.exposed && agt[fnName] && agt.runtime.loaderType !== 'micro-agent') {
36+
returnVals.push(agt[fnName](...args))
3937
}
4038
})
4139
return returnVals[0]
@@ -44,42 +42,40 @@ export function setTopLevelCallers () {
4442

4543
const replayRunning = {}
4644

47-
export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
48-
if (!forceDrain) registerDrain(agentIdentifier, 'api')
49-
const apiInterface = {}
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')
5248

53-
replayRunning[agentIdentifier] = MODE.OFF
49+
replayRunning[agent.agentIdentifier] = MODE.OFF
5450

55-
instanceEE.on(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, (isRunning) => {
56-
replayRunning[agentIdentifier] = isRunning
51+
agent.ee.on(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, (isRunning) => {
52+
replayRunning[agent.agentIdentifier] = isRunning
5753
})
5854

59-
var prefix = 'api-'
60-
var spaPrefix = prefix + 'ixn-'
55+
const prefix = 'api-'
56+
const spaPrefix = prefix + 'ixn-'
6157

62-
apiInterface.log = function (message, { customAttributes = {}, level = LOG_LEVELS.INFO } = {}) {
63-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/log/called'], undefined, FEATURE_NAMES.metrics, instanceEE)
64-
bufferLog(instanceEE, message, customAttributes, level)
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)
6561
}
6662

67-
apiInterface.wrapLogger = (parent, functionName, { customAttributes = {}, level = LOG_LEVELS.INFO } = {}) => {
68-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/wrapLogger/called'], undefined, FEATURE_NAMES.metrics, instanceEE)
69-
wrapLogger(instanceEE, parent, functionName, { customAttributes, level })
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 })
7066
}
7167

7268
// Setup stub functions that queue calls for later processing.
73-
asyncApiMethods.forEach(fnName => { apiInterface[fnName] = apiCall(prefix, fnName, true, 'api') })
69+
asyncApiMethods.forEach(fnName => { agent[fnName] = apiCall(prefix, fnName, true, 'api') })
7470

75-
apiInterface.addPageAction = apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.genericEvents)
71+
agent.addPageAction = apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.genericEvents)
7672

77-
apiInterface.recordCustomEvent = apiCall(prefix, 'recordCustomEvent', true, FEATURE_NAMES.genericEvents)
73+
agent.recordCustomEvent = apiCall(prefix, 'recordCustomEvent', true, FEATURE_NAMES.genericEvents)
7874

79-
apiInterface.setPageViewName = function (name, host) {
75+
agent.setPageViewName = function (name, host) {
8076
if (typeof name !== 'string') return
8177
if (name.charAt(0) !== '/') name = '/' + name
82-
getRuntime(agentIdentifier).customTransaction = (host || 'http://custom.transaction') + name
78+
agent.runtime.customTransaction = (host || 'http://custom.transaction') + name
8379
return apiCall(prefix, 'setPageViewName', true)()
8480
}
8581

@@ -92,15 +88,15 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
9288
* @returns @see apiCall
9389
*/
9490
function appendJsAttribute (key, value, apiName, addToBrowserStorage) {
95-
const currentInfo = getInfo(agentIdentifier)
91+
const currentInfo = agent.info
9692
if (value === null) {
9793
delete currentInfo.jsAttributes[key]
9894
} else {
99-
setInfo(agentIdentifier, { ...currentInfo, jsAttributes: { ...currentInfo.jsAttributes, [key]: value } })
95+
setInfo(agent.agentIdentifier, { ...currentInfo, jsAttributes: { ...currentInfo.jsAttributes, [key]: value } })
10096
}
10197
return apiCall(prefix, apiName, true, (!!addToBrowserStorage || value === null) ? 'session' : undefined)(key, value)
10298
}
103-
apiInterface.setCustomAttribute = function (name, value, persistAttribute = false) {
99+
agent.setCustomAttribute = function (name, value, persistAttribute = false) {
104100
if (typeof name !== 'string') {
105101
warn(39, typeof name)
106102
return
@@ -116,7 +112,7 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
116112
* @param {string} value - unique user identifier; a null user id suggests none should exist
117113
* @returns @see apiCall
118114
*/
119-
apiInterface.setUserId = function (value) {
115+
agent.setUserId = function (value) {
120116
if (!(typeof value === 'string' || value === null)) {
121117
warn(41, typeof value)
122118
return
@@ -129,34 +125,34 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
129125
* @param {string|null} value - Application version -- if null, will "unset" the value
130126
* @returns @see apiCall
131127
*/
132-
apiInterface.setApplicationVersion = function (value) {
128+
agent.setApplicationVersion = function (value) {
133129
if (!(typeof value === 'string' || value === null)) {
134130
warn(42, typeof value)
135131
return
136132
}
137133
return appendJsAttribute('application.version', value, 'setApplicationVersion', false)
138134
}
139135

140-
apiInterface.start = () => {
136+
agent.start = () => {
141137
try {
142-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/start/called'], undefined, FEATURE_NAMES.metrics, instanceEE)
143-
instanceEE.emit('manual-start-all')
138+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/start/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
139+
agent.ee.emit('manual-start-all')
144140
} catch (err) {
145141
warn(23, err)
146142
}
147143
}
148144

149-
apiInterface[SR_EVENT_EMITTER_TYPES.RECORD] = function () {
150-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/recordReplay/called'], undefined, FEATURE_NAMES.metrics, instanceEE)
151-
handle(SR_EVENT_EMITTER_TYPES.RECORD, [], undefined, FEATURE_NAMES.sessionReplay, instanceEE)
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)
152148
}
153149

154-
apiInterface[SR_EVENT_EMITTER_TYPES.PAUSE] = function () {
155-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/pauseReplay/called'], undefined, FEATURE_NAMES.metrics, instanceEE)
156-
handle(SR_EVENT_EMITTER_TYPES.PAUSE, [], undefined, FEATURE_NAMES.sessionReplay, instanceEE)
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)
157153
}
158154

159-
apiInterface.interaction = function (options) {
155+
agent.interaction = function (options) {
160156
return new InteractionHandle().get(typeof options === 'object' ? options : {})
161157
}
162158

@@ -167,9 +163,9 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
167163
var contextStore = {}
168164
var ixn = this
169165
var hasCb = typeof cb === 'function'
170-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/createTracer/called'], undefined, FEATURE_NAMES.metrics, instanceEE)
166+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/createTracer/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
171167
// 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, instanceEE)
168+
if (!agent.runSoftNavOverSpa) handle(spaPrefix + 'tracer', [now(), name, contextStore], ixn, FEATURE_NAMES.spa, agent.ee)
173169
return function () {
174170
tracerEE.emit((hasCb ? '' : 'no-') + 'fn-start', [now(), ixn, hasCb], contextStore)
175171
if (hasCb) {
@@ -189,30 +185,30 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
189185
}
190186

191187
;['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)
193189
})
194-
apiInterface.setCurrentRouteName = runSoftNavOverSpa ? apiCall(spaPrefix, 'routeName', undefined, FEATURE_NAMES.softNav) : apiCall(prefix, 'routeName', true, FEATURE_NAMES.spa)
190+
agent.setCurrentRouteName = agent.runSoftNavOverSpa ? apiCall(spaPrefix, 'routeName', undefined, FEATURE_NAMES.softNav) : apiCall(prefix, 'routeName', true, FEATURE_NAMES.spa)
195191

196192
function apiCall (prefix, name, notSpa, bufferGroup) {
197193
return function () {
198-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, FEATURE_NAMES.metrics, instanceEE)
194+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
199195
dispatchGlobalEvent({
200-
agentIdentifier,
201-
loaded: !!activatedFeatures?.[agentIdentifier],
196+
agentIdentifier: agent.agentIdentifier,
197+
loaded: !!activatedFeatures?.[agent.agentIdentifier],
202198
type: 'data',
203199
name: 'api',
204200
feature: prefix + name,
205201
data: { notSpa, bufferGroup }
206202
})
207-
if (bufferGroup) handle(prefix + name, [notSpa ? now() : performance.now(), ...arguments], notSpa ? null : this, bufferGroup, instanceEE) // no bufferGroup means only the SM is emitted
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
208204
return notSpa ? undefined : this // returns the InteractionHandle which allows these methods to be chained
209205
}
210206
}
211207

212-
apiInterface.noticeError = function (err, customAttributes) {
208+
agent.noticeError = function (err, customAttributes) {
213209
if (typeof err === 'string') err = new Error(err)
214-
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, FEATURE_NAMES.metrics, instanceEE)
215-
handle('err', [err, now(), false, customAttributes, !!replayRunning[agentIdentifier]], undefined, FEATURE_NAMES.jserrors, instanceEE)
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)
216212
}
217213

218214
// theres no window.load event on non-browser scopes, lazy load immediately
@@ -221,14 +217,14 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
221217
else onWindowLoad(() => lazyLoad(), true)
222218

223219
function lazyLoad () {
224-
import(/* webpackChunkName: "async-api" */'./apiAsync').then(({ setAPI }) => {
225-
setAPI(agentIdentifier)
226-
drain(agentIdentifier, 'api')
220+
import(/* webpackChunkName: "async-api" */'./apiAsync').then(({ setAsyncAPI }) => {
221+
setAsyncAPI(agent)
222+
drain(agent.agentIdentifier, 'api')
227223
}).catch((err) => {
228224
warn(27, err)
229-
instanceEE.abort()
225+
agent.ee.abort()
230226
})
231227
}
232228

233-
return apiInterface
229+
return true
234230
}

src/loaders/api/apiAsync.js

+14-18
Original file line numberDiff line numberDiff line change
@@ -3,58 +3,54 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55
import { FEATURE_NAMES } from '../features/features'
6-
import { getRuntime } from '../../common/config/runtime'
7-
import { ee } from '../../common/event-emitter/contextual-ee'
86
import { handle } from '../../common/event-emitter/handle'
97
import { registerHandler } from '../../common/event-emitter/register-handler'
108
import { single } from '../../common/util/invoke'
119
import { CUSTOM_METRIC_CHANNEL } from '../../features/metrics/constants'
1210
import { originTime } from '../../common/constants/runtime'
1311

14-
export function setAPI (agentIdentifier) {
15-
var instanceEE = ee.get(agentIdentifier)
16-
17-
var api = {
12+
export function setAsyncAPI (agent) {
13+
const api = {
1814
finished: single(finished),
1915
setErrorHandler,
2016
addToTrace,
2117
addRelease
2218
}
2319

2420
// 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', instanceEE))
21+
Object.entries(api).forEach(([fnName, fnCall]) => registerHandler('api-' + fnName, fnCall, 'api', agent.ee))
2622

2723
// All API functions get passed the time they were called as their
2824
// first parameter. These functions can be called asynchronously.
2925

3026
function finished (t, providedTime) {
31-
var time = providedTime ? providedTime - originTime : t
32-
handle(CUSTOM_METRIC_CHANNEL, ['finished', { time }], undefined, FEATURE_NAMES.metrics, instanceEE)
27+
const time = providedTime ? providedTime - originTime : t
28+
handle(CUSTOM_METRIC_CHANNEL, ['finished', { time }], undefined, FEATURE_NAMES.metrics, agent.ee)
3329
addToTrace(t, { name: 'finished', start: time + originTime, origin: 'nr' })
34-
handle('api-addPageAction', [time, 'finished'], undefined, FEATURE_NAMES.genericEvents, instanceEE)
30+
handle('api-addPageAction', [time, 'finished'], undefined, FEATURE_NAMES.genericEvents, agent.ee)
3531
}
3632

37-
function addToTrace (t, evt) {
33+
function addToTrace (_, evt) {
3834
if (!(evt && typeof evt === 'object' && evt.name && evt.start)) return
3935

40-
var report = {
36+
const report = {
4137
n: evt.name,
4238
s: evt.start - originTime,
4339
e: (evt.end || evt.start) - originTime,
4440
o: evt.origin || '',
4541
t: 'api'
4642
}
4743

48-
handle('bstApi', [report], undefined, FEATURE_NAMES.sessionTrace, instanceEE)
44+
handle('bstApi', [report], undefined, FEATURE_NAMES.sessionTrace, agent.ee)
4945
}
5046

51-
function setErrorHandler (t, handler) {
52-
getRuntime(agentIdentifier).onerror = handler
47+
function setErrorHandler (_, handler) {
48+
agent.runtime.onerror = handler
5349
}
5450

55-
var releaseCount = 0
56-
function addRelease (t, name, id) {
51+
let releaseCount = 0
52+
function addRelease (_, name, id) {
5753
if (++releaseCount > 10) return
58-
getRuntime(agentIdentifier).releaseIds[name.slice(-200)] = ('' + id).slice(-200)
54+
agent.runtime.releaseIds[name.slice(-200)] = ('' + id).slice(-200)
5955
}
6056
}

0 commit comments

Comments
 (0)