@newrelic/browser-agent 1.286.0 → 1.288.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/common/config/init-types.js +96 -0
  3. package/dist/cjs/common/config/init.js +9 -79
  4. package/dist/cjs/common/config/runtime.js +7 -6
  5. package/dist/cjs/common/constants/env.cdn.js +1 -1
  6. package/dist/cjs/common/constants/env.npm.js +1 -1
  7. package/dist/cjs/common/harvest/harvester.js +2 -2
  8. package/dist/cjs/common/session/session-entity.js +10 -3
  9. package/dist/cjs/common/util/feature-flags.js +4 -5
  10. package/dist/cjs/common/util/target.js +34 -0
  11. package/dist/cjs/features/ajax/aggregate/index.js +2 -1
  12. package/dist/cjs/features/generic_events/aggregate/index.js +10 -6
  13. package/dist/cjs/features/jserrors/aggregate/index.js +44 -22
  14. package/dist/cjs/features/logging/aggregate/index.js +21 -13
  15. package/dist/cjs/features/logging/shared/utils.js +3 -2
  16. package/dist/cjs/features/metrics/aggregate/index.js +6 -4
  17. package/dist/cjs/features/page_view_event/aggregate/index.js +60 -11
  18. package/dist/cjs/features/page_view_event/instrument/index.js +4 -0
  19. package/dist/cjs/features/session_replay/aggregate/index.js +9 -7
  20. package/dist/cjs/features/session_replay/instrument/index.js +1 -1
  21. package/dist/cjs/features/session_replay/shared/recorder-events.js +4 -2
  22. package/dist/cjs/features/session_replay/shared/recorder.js +17 -11
  23. package/dist/cjs/features/session_trace/aggregate/trace/storage.js +8 -1
  24. package/dist/cjs/features/soft_navigations/aggregate/index.js +13 -2
  25. package/dist/cjs/features/spa/aggregate/index.js +4 -3
  26. package/dist/cjs/features/spa/aggregate/interaction.js +6 -9
  27. package/dist/cjs/features/utils/aggregate-base.js +49 -20
  28. package/dist/cjs/features/utils/entity-manager.js +47 -0
  29. package/dist/cjs/features/utils/event-store-manager.js +79 -54
  30. package/dist/cjs/interfaces/registered-entity.js +114 -0
  31. package/dist/cjs/loaders/api/api-methods.js +1 -1
  32. package/dist/cjs/loaders/api/api.js +50 -18
  33. package/dist/cjs/loaders/api/register-api-types.js +35 -0
  34. package/dist/cjs/loaders/api/register-api.js +165 -0
  35. package/dist/cjs/loaders/micro-agent-base.js +16 -0
  36. package/dist/cjs/loaders/micro-agent.js +1 -0
  37. package/dist/esm/common/config/init-types.js +92 -0
  38. package/dist/esm/common/config/init.js +9 -79
  39. package/dist/esm/common/config/runtime.js +7 -6
  40. package/dist/esm/common/constants/env.cdn.js +1 -1
  41. package/dist/esm/common/constants/env.npm.js +1 -1
  42. package/dist/esm/common/harvest/harvester.js +2 -2
  43. package/dist/esm/common/session/session-entity.js +10 -3
  44. package/dist/esm/common/util/feature-flags.js +4 -5
  45. package/dist/esm/common/util/target.js +27 -0
  46. package/dist/esm/features/ajax/aggregate/index.js +2 -1
  47. package/dist/esm/features/generic_events/aggregate/index.js +10 -6
  48. package/dist/esm/features/jserrors/aggregate/index.js +44 -22
  49. package/dist/esm/features/logging/aggregate/index.js +21 -13
  50. package/dist/esm/features/logging/shared/utils.js +3 -2
  51. package/dist/esm/features/metrics/aggregate/index.js +6 -4
  52. package/dist/esm/features/page_view_event/aggregate/index.js +60 -11
  53. package/dist/esm/features/page_view_event/instrument/index.js +4 -0
  54. package/dist/esm/features/session_replay/aggregate/index.js +9 -7
  55. package/dist/esm/features/session_replay/instrument/index.js +1 -1
  56. package/dist/esm/features/session_replay/shared/recorder-events.js +4 -2
  57. package/dist/esm/features/session_replay/shared/recorder.js +17 -11
  58. package/dist/esm/features/session_trace/aggregate/trace/storage.js +8 -1
  59. package/dist/esm/features/soft_navigations/aggregate/index.js +13 -2
  60. package/dist/esm/features/spa/aggregate/index.js +4 -3
  61. package/dist/esm/features/spa/aggregate/interaction.js +6 -9
  62. package/dist/esm/features/utils/aggregate-base.js +49 -20
  63. package/dist/esm/features/utils/entity-manager.js +40 -0
  64. package/dist/esm/features/utils/event-store-manager.js +79 -54
  65. package/dist/esm/interfaces/registered-entity.js +107 -0
  66. package/dist/esm/loaders/api/api-methods.js +1 -1
  67. package/dist/esm/loaders/api/api.js +50 -18
  68. package/dist/esm/loaders/api/register-api-types.js +33 -0
  69. package/dist/esm/loaders/api/register-api.js +159 -0
  70. package/dist/esm/loaders/micro-agent-base.js +16 -0
  71. package/dist/esm/loaders/micro-agent.js +1 -0
  72. package/dist/tsconfig.tsbuildinfo +1 -1
  73. package/dist/types/common/config/init-types.d.ts +275 -0
  74. package/dist/types/common/config/init-types.d.ts.map +1 -0
  75. package/dist/types/common/config/init.d.ts +1 -262
  76. package/dist/types/common/config/init.d.ts.map +1 -1
  77. package/dist/types/common/config/runtime.d.ts.map +1 -1
  78. package/dist/types/common/session/session-entity.d.ts +3 -1
  79. package/dist/types/common/session/session-entity.d.ts.map +1 -1
  80. package/dist/types/common/util/feature-flags.d.ts +1 -1
  81. package/dist/types/common/util/feature-flags.d.ts.map +1 -1
  82. package/dist/types/common/util/target.d.ts +18 -0
  83. package/dist/types/common/util/target.d.ts.map +1 -0
  84. package/dist/types/features/ajax/aggregate/index.d.ts +1 -1
  85. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  86. package/dist/types/features/generic_events/aggregate/index.d.ts +2 -1
  87. package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
  88. package/dist/types/features/jserrors/aggregate/index.d.ts +9 -1
  89. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  90. package/dist/types/features/logging/aggregate/index.d.ts +3 -3
  91. package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
  92. package/dist/types/features/logging/shared/utils.d.ts +2 -1
  93. package/dist/types/features/logging/shared/utils.d.ts.map +1 -1
  94. package/dist/types/features/metrics/aggregate/index.d.ts +1 -0
  95. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  96. package/dist/types/features/page_view_event/aggregate/index.d.ts +10 -2
  97. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  98. package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
  99. package/dist/types/features/session_replay/aggregate/index.d.ts +3 -12
  100. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  101. package/dist/types/features/session_replay/shared/recorder-events.d.ts +1 -0
  102. package/dist/types/features/session_replay/shared/recorder-events.d.ts.map +1 -1
  103. package/dist/types/features/session_replay/shared/recorder.d.ts +5 -5
  104. package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
  105. package/dist/types/features/session_trace/aggregate/trace/storage.d.ts +1 -0
  106. package/dist/types/features/session_trace/aggregate/trace/storage.d.ts.map +1 -1
  107. package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
  108. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  109. package/dist/types/features/spa/aggregate/interaction.d.ts +3 -4
  110. package/dist/types/features/spa/aggregate/interaction.d.ts.map +1 -1
  111. package/dist/types/features/utils/aggregate-base.d.ts +22 -5
  112. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  113. package/dist/types/features/utils/entity-manager.d.ts +15 -0
  114. package/dist/types/features/utils/entity-manager.d.ts.map +1 -0
  115. package/dist/types/features/utils/event-store-manager.d.ts +48 -24
  116. package/dist/types/features/utils/event-store-manager.d.ts.map +1 -1
  117. package/dist/types/interfaces/registered-entity.d.ts +72 -0
  118. package/dist/types/interfaces/registered-entity.d.ts.map +1 -0
  119. package/dist/types/loaders/agent.d.ts +1 -1
  120. package/dist/types/loaders/api/api.d.ts.map +1 -1
  121. package/dist/types/loaders/api/register-api-types.d.ts +56 -0
  122. package/dist/types/loaders/api/register-api-types.d.ts.map +1 -0
  123. package/dist/types/loaders/api/register-api.d.ts +14 -0
  124. package/dist/types/loaders/api/register-api.d.ts.map +1 -0
  125. package/dist/types/loaders/micro-agent-base.d.ts +17 -0
  126. package/dist/types/loaders/micro-agent-base.d.ts.map +1 -1
  127. package/dist/types/loaders/micro-agent.d.ts +1 -0
  128. package/dist/types/loaders/micro-agent.d.ts.map +1 -1
  129. package/package.json +10 -1
  130. package/src/common/config/init-types.js +92 -0
  131. package/src/common/config/init.js +9 -79
  132. package/src/common/config/runtime.js +7 -6
  133. package/src/common/harvest/harvester.js +2 -2
  134. package/src/common/session/session-entity.js +10 -3
  135. package/src/common/util/feature-flags.js +4 -5
  136. package/src/common/util/target.js +27 -0
  137. package/src/features/ajax/aggregate/index.js +2 -1
  138. package/src/features/generic_events/aggregate/index.js +8 -6
  139. package/src/features/jserrors/aggregate/index.js +42 -20
  140. package/src/features/logging/aggregate/index.js +18 -12
  141. package/src/features/logging/shared/utils.js +3 -2
  142. package/src/features/metrics/aggregate/index.js +7 -5
  143. package/src/features/page_view_event/aggregate/index.js +50 -8
  144. package/src/features/page_view_event/instrument/index.js +4 -0
  145. package/src/features/session_replay/aggregate/index.js +7 -4
  146. package/src/features/session_replay/instrument/index.js +1 -1
  147. package/src/features/session_replay/shared/recorder-events.js +5 -2
  148. package/src/features/session_replay/shared/recorder.js +17 -11
  149. package/src/features/session_trace/aggregate/trace/storage.js +9 -1
  150. package/src/features/soft_navigations/aggregate/index.js +12 -2
  151. package/src/features/spa/aggregate/index.js +4 -3
  152. package/src/features/spa/aggregate/interaction.js +6 -9
  153. package/src/features/utils/aggregate-base.js +54 -22
  154. package/src/features/utils/entity-manager.js +45 -0
  155. package/src/features/utils/event-store-manager.js +72 -49
  156. package/src/interfaces/registered-entity.js +107 -0
  157. package/src/loaders/api/api-methods.js +1 -1
  158. package/src/loaders/api/api.js +49 -13
  159. package/src/loaders/api/register-api-types.js +33 -0
  160. package/src/loaders/api/register-api.js +152 -0
  161. package/src/loaders/micro-agent-base.js +16 -0
  162. package/src/loaders/micro-agent.js +1 -0
@@ -3,7 +3,6 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { FEATURE_NAMES } from '../features/features'
6
- import { setInfo } from '../../common/config/info'
7
6
  import { handle } from '../../common/event-emitter/handle'
8
7
  import { drain, registerDrain } from '../../common/drain/drain'
9
8
  import { onWindowLoad } from '../../common/window/load'
@@ -18,6 +17,7 @@ import { MODE } from '../../common/session/constants'
18
17
  import { LOG_LEVELS } from '../../features/logging/constants'
19
18
  import { bufferLog } from '../../features/logging/shared/utils'
20
19
  import { wrapLogger } from '../../common/wrap/wrap-logger'
20
+ import { buildRegisterApi } from './register-api'
21
21
  import { dispatchGlobalEvent } from '../../common/dispatch/global-event'
22
22
  import { activatedFeatures } from '../../common/util/feature-flags'
23
23
 
@@ -55,9 +55,37 @@ export function setAPI (agent, forceDrain) {
55
55
  const prefix = 'api-'
56
56
  const spaPrefix = prefix + 'ixn-'
57
57
 
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)
58
+ /** Shared handlers are used by both the base agent instance as well as "registered" entities
59
+ * We isolate them like this so that the public interface methods are unchanged and still dont require
60
+ * a target, but the register APIs `can` supply a target.
61
+ */
62
+ const sharedHandlers = {
63
+ addPageAction: function (name, attributes, targetEntityGuid, timestamp = now()) {
64
+ apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.genericEvents, timestamp)(name, attributes, targetEntityGuid)
65
+ },
66
+ log: function (message, { customAttributes = {}, level = LOG_LEVELS.INFO } = {}, targetEntityGuid, timestamp = now()) {
67
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/log/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
68
+ bufferLog(agent.ee, message, customAttributes, level, targetEntityGuid, timestamp)
69
+ },
70
+ noticeError: function (err, customAttributes, targetEntityGuid, timestamp = now()) {
71
+ if (typeof err === 'string') err = new Error(err)
72
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
73
+ handle('err', [err, timestamp, false, customAttributes, !!replayRunning[agent.agentIdentifier], undefined, targetEntityGuid], undefined, FEATURE_NAMES.jserrors, agent.ee)
74
+ }
75
+ }
76
+
77
+ /**
78
+ * @experimental
79
+ * IMPORTANT: This feature is being developed for use internally and is not in a public-facing production-ready state.
80
+ * It is not recommended for use in production environments and will not receive support for issues.
81
+ */
82
+ agent.register = function (target) {
83
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/register/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
84
+ return buildRegisterApi(agent, sharedHandlers, target)
85
+ }
86
+
87
+ agent.log = function (message, options) {
88
+ sharedHandlers.log(message, options)
61
89
  }
62
90
 
63
91
  agent.wrapLogger = (parent, functionName, { customAttributes = {}, level = LOG_LEVELS.INFO } = {}) => {
@@ -68,7 +96,9 @@ export function setAPI (agent, forceDrain) {
68
96
  // Setup stub functions that queue calls for later processing.
69
97
  asyncApiMethods.forEach(fnName => { agent[fnName] = apiCall(prefix, fnName, true, 'api') })
70
98
 
71
- agent.addPageAction = apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.genericEvents)
99
+ agent.addPageAction = function (name, attributes) {
100
+ sharedHandlers.addPageAction(name, attributes)
101
+ }
72
102
 
73
103
  agent.recordCustomEvent = apiCall(prefix, 'recordCustomEvent', true, FEATURE_NAMES.genericEvents)
74
104
 
@@ -92,7 +122,7 @@ export function setAPI (agent, forceDrain) {
92
122
  if (value === null) {
93
123
  delete currentInfo.jsAttributes[key]
94
124
  } else {
95
- setInfo(agent.agentIdentifier, { ...currentInfo, jsAttributes: { ...currentInfo.jsAttributes, [key]: value } })
125
+ agent.info = { ...agent.info, jsAttributes: { ...currentInfo.jsAttributes, [key]: value } }
96
126
  }
97
127
  return apiCall(prefix, apiName, true, (!!addToBrowserStorage || value === null) ? 'session' : undefined)(key, value)
98
128
  }
@@ -185,11 +215,19 @@ export function setAPI (agent, forceDrain) {
185
215
  }
186
216
 
187
217
  ;['actionText', 'setName', 'setAttribute', 'save', 'ignore', 'onEnd', 'getContext', 'end', 'get'].forEach(name => {
188
- InteractionApiProto[name] = apiCall(spaPrefix, name, undefined, agent.runSoftNavOverSpa ? FEATURE_NAMES.softNav : FEATURE_NAMES.spa)
218
+ InteractionApiProto[name] = function () {
219
+ return apiCall
220
+ .apply(this, [spaPrefix, name, undefined, agent.runSoftNavOverSpa ? FEATURE_NAMES.softNav : FEATURE_NAMES.spa])
221
+ .apply(this, arguments)
222
+ }
189
223
  })
190
- agent.setCurrentRouteName = agent.runSoftNavOverSpa ? apiCall(spaPrefix, 'routeName', undefined, FEATURE_NAMES.softNav) : apiCall(prefix, 'routeName', true, FEATURE_NAMES.spa)
224
+ agent.setCurrentRouteName = function () {
225
+ return agent.runSoftNavOverSpa
226
+ ? apiCall(spaPrefix, 'routeName', undefined, FEATURE_NAMES.softNav)(...arguments)
227
+ : apiCall(prefix, 'routeName', true, FEATURE_NAMES.spa)(...arguments)
228
+ }
191
229
 
192
- function apiCall (prefix, name, notSpa, bufferGroup) {
230
+ function apiCall (prefix, name, notSpa, bufferGroup, timestamp = now()) {
193
231
  return function () {
194
232
  handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, FEATURE_NAMES.metrics, agent.ee)
195
233
  dispatchGlobalEvent({
@@ -200,15 +238,13 @@ export function setAPI (agent, forceDrain) {
200
238
  feature: prefix + name,
201
239
  data: { notSpa, bufferGroup }
202
240
  })
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
241
+ if (bufferGroup) handle(prefix + name, [timestamp, ...arguments], notSpa ? null : this, bufferGroup, agent.ee) // no bufferGroup means only the SM is emitted
204
242
  return notSpa ? undefined : this // returns the InteractionHandle which allows these methods to be chained
205
243
  }
206
244
  }
207
245
 
208
246
  agent.noticeError = function (err, customAttributes) {
209
- if (typeof err === 'string') err = new Error(err)
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)
247
+ sharedHandlers.noticeError(err, customAttributes)
212
248
  }
213
249
 
214
250
  // theres no window.load event on non-browser scopes, lazy load immediately
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Copyright 2020-2025 New Relic, Inc. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ /**
7
+ * @typedef {Object} RegisterAPI
8
+ * @property {Function} addPageAction - Add a page action for the registered entity.
9
+ * @property {Function} log - Capture a log for the registered entity.
10
+ * @property {Function} noticeError - Notice an error for the registered entity.
11
+ * @property {Function} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
12
+ * @property {Function} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
13
+ * @property {Function} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
14
+ * @property {RegisterAPIMetadata} metadata - The metadata object containing the custom attributes and target information for the registered entity.
15
+ */
16
+
17
+ /**
18
+ * @typedef {Object} RegisterAPIConstructor
19
+ * @property {Object} opts - The options for the registered entity.
20
+ * @property {string} opts.licenseKey - The license key for the registered entity.
21
+ * @property {string} opts.applicationID - The application ID for the registered entity.
22
+ */
23
+
24
+ /**
25
+ * @typedef {Object} RegisterAPIMetadata
26
+ * @property {Object} customAttributes - The custom attributes for the registered entity.
27
+ * @property {Object} target - The options for the registered entity.
28
+ * @property {string} target.licenseKey - The license key for the registered entity.
29
+ * @property {string} target.applicationID - The application ID for the registered entity.
30
+ * @property {string} target.entityGuid - The entity guid returned for the registered entity.
31
+ */
32
+
33
+ export default {}
@@ -0,0 +1,152 @@
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 { warn } from '../../common/util/console'
7
+ import { isContainerAgentTarget, isValidTarget } from '../../common/util/target'
8
+ import { FEATURE_NAMES } from '../features/features'
9
+ import { now } from '../../common/timing/now'
10
+ import { SUPPORTABILITY_METRIC_CHANNEL } from '../../features/metrics/constants'
11
+
12
+ /**
13
+ * @typedef {import('./register-api-types').RegisterAPI} RegisterAPI
14
+ */
15
+
16
+ /**
17
+ * Builds the api object that will be returned from the register api method.
18
+ * Also conducts certain side-effects, such as harvesting a PageView event when triggered and gathering metadata for the registered entity.
19
+ * @param {Object} agentRef the reference to the base agent instance
20
+ * @param {Object} handlers the shared handlers to be used by both the base agent's API and the external target's API
21
+ * @param {Object} target the target information to be used by the external target's API to send data to the correct location
22
+ * @returns {RegisterAPI} the api object to be returned from the register api method
23
+ */
24
+ export function buildRegisterApi (agentRef, handlers, target) {
25
+ const attrs = {}
26
+ warn(54, 'newrelic.register')
27
+
28
+ /** @type {Function|undefined} a function that is set and reports when APIs are triggered -- warns the customer of the invalid state */
29
+ let invalidApiResponse
30
+
31
+ /**
32
+ * A promise that indicates when all needed connections for the registered child to be ready to report data
33
+ * 1. The main agent to be ready (made a RUM call and got its entity guid)
34
+ * 2. The child to be registered with the main agent (made its own RUM call and got its entity guid)
35
+ * @type {Promise<RegisterAPI>}
36
+ */
37
+ let _connected
38
+ if (!agentRef.init.api.allow_registered_children) invalidApiResponse = () => warn(55)
39
+ if (!target || !isValidTarget(target)) invalidApiResponse = () => warn(48, target)
40
+
41
+ /** @type {RegisterAPI} */
42
+ const api = {
43
+ addPageAction: (name, attributes = {}) => {
44
+ report(handlers.addPageAction, [name, { ...attrs, ...attributes }], target)
45
+ },
46
+ log: (message, options = {}) => {
47
+ report(handlers.log, [message, { ...options, customAttributes: { ...attrs, ...(options.customAttributes || {}) } }], target)
48
+ },
49
+ noticeError: (error, attributes = {}) => {
50
+ report(handlers.noticeError, [error, { ...attrs, ...attributes }], target)
51
+ },
52
+ setApplicationVersion: (value) => {
53
+ attrs['application.version'] = value
54
+ },
55
+ setCustomAttribute: (key, value) => {
56
+ attrs[key] = value
57
+ },
58
+ setUserId: (value) => {
59
+ attrs['enduser.id'] = value
60
+ },
61
+ /** metadata */
62
+ metadata: {
63
+ customAttributes: attrs,
64
+ target,
65
+ /** set in a getter so that later access of the Promise is not polluted before customer is allowed to set a catch block */
66
+ get connected () {
67
+ return _connected || Promise.reject(new Error('Failed to connect'))
68
+ }
69
+ }
70
+ }
71
+
72
+ if (invalidApiResponse) {
73
+ invalidApiResponse()
74
+ } else {
75
+ _connected = new Promise((resolve, reject) => {
76
+ try {
77
+ const entityManager = agentRef.runtime?.entityManager
78
+ /** check if main agent already has main agent entity guid */
79
+ let mainAgentReady = !!entityManager?.get().entityGuid
80
+ /** check if registered target already has entity guid */
81
+ let registeredEntityGuid = entityManager?.getEntityGuidFor(target.licenseKey, target.applicationID)
82
+ let registrationReady = !!registeredEntityGuid
83
+
84
+ /** check if we can just resolve immediately without making another connect call */
85
+ if (mainAgentReady && registrationReady) {
86
+ target.entityGuid = registeredEntityGuid
87
+ resolve(api)
88
+ } else {
89
+ /** we need to make a new connection call since we dont already have a registered entity for this call */
90
+
91
+ /** if the connect callback doesnt resolve in 15 seconds... reject */
92
+ const timeout = setTimeout(() => reject(new Error('Failed to connect - Timeout')), 15000)
93
+
94
+ // tell the main agent to send a rum call for this target
95
+ // when the rum call resolves, it will emit an "entity-added" event, see below
96
+ agentRef.ee.emit('api-send-rum', [attrs, target])
97
+
98
+ // wait for entity events to emit to see when main agent and/or API registration is ready
99
+ agentRef.ee.on('entity-added', entityEventHandler)
100
+
101
+ function entityEventHandler (entity) {
102
+ if (isContainerAgentTarget(entity, agentRef)) mainAgentReady ||= true
103
+ else {
104
+ if (target.licenseKey === entity.licenseKey && target.applicationID === entity.applicationID) {
105
+ registrationReady = true
106
+ target.entityGuid = entity.entityGuid
107
+ }
108
+ }
109
+
110
+ if (mainAgentReady && registrationReady) {
111
+ clearTimeout(timeout)
112
+ // unsubscribe from the event emitter
113
+ agentRef.ee.removeEventListener('entity-added', entityEventHandler)
114
+ resolve(api)
115
+ }
116
+ }
117
+ }
118
+ } catch (err) {
119
+ reject(err)
120
+ }
121
+ })
122
+ }
123
+
124
+ /**
125
+ * The reporter method that will be used to report the data to the container agent's API method. If invalid, will log a warning and not execute.
126
+ * If the api.duplicate_registered_data configuration value is set to true, the data will be reported to BOTH the container and the external target
127
+ * @param {*} methodToCall the container agent's API method to call
128
+ * @param {*} args the arguments to supply to the container agent's API method
129
+ * @param {string} targetEntityGuid the target entity guid, which looks up the target to report the data to from the entity manager. If undefined, will report to the container agent's target.
130
+ * @returns
131
+ */
132
+ const report = async (methodToCall, args, target) => {
133
+ if (invalidApiResponse) return invalidApiResponse()
134
+ /** set the timestamp before the async part of waiting for the rum response for better accuracy */
135
+ const timestamp = now()
136
+ handle(SUPPORTABILITY_METRIC_CHANNEL, [`API/register/${methodToCall.name}/called`], undefined, FEATURE_NAMES.metrics, agentRef.ee)
137
+ try {
138
+ await _connected
139
+ // target should be decorated with entityGuid by the rum resp at this point
140
+ const shouldDuplicate = agentRef.init.api.duplicate_registered_data
141
+ if (shouldDuplicate === true || (Array.isArray(shouldDuplicate) && shouldDuplicate.includes(target.entityGuid))) {
142
+ // also report to container by providing undefined target
143
+ methodToCall(...args, undefined, timestamp)
144
+ }
145
+ methodToCall(...args, target.entityGuid, timestamp) // always report to target
146
+ } catch (err) {
147
+ warn(50, err)
148
+ }
149
+ }
150
+
151
+ return api
152
+ }
@@ -34,6 +34,22 @@ export class MicroAgentBase {
34
34
  return this.#callMethod('addPageAction', name, attributes)
35
35
  }
36
36
 
37
+ /**
38
+ * @experimental
39
+ * IMPORTANT: This feature is being developed for use internally and is not in a public-facing production-ready state.
40
+ * It is not recommended for use in production environments and will not receive support for issues.
41
+ *
42
+ * Registers an external caller to report through the base agent to a different target than the base agent.
43
+ * @param {object} target the target object to report data to
44
+ * @param {string} target.licenseKey The licenseKey to report data to
45
+ * @param {string} target.applicationID The applicationID to report data to
46
+ * @param {string=} target.entityGuid The entityGuid to report data to
47
+ * @returns {object} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
48
+ */
49
+ register (target) {
50
+ return this.#callMethod('register', target)
51
+ }
52
+
37
53
  /**
38
54
  * Records a custom event with a specified eventType and attributes.
39
55
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
@@ -21,6 +21,7 @@ const nonAutoFeatures = [
21
21
  ]
22
22
 
23
23
  /**
24
+ * @deprecated This feature has been deprecated and will be removed in a future release. A future product centralizing around a single agent instance will be released as a replacement, at which time this loader will be removed.
24
25
  * A minimal agent class designed to only respond to manual user input. As such, this class does not
25
26
  * automatically instrument. Instead, each MicroAgent instance will lazy load the required features and can support loading multiple instances on one page.
26
27
  * Out of the box, it can manually handle and report Page View, Page Action, and Error events.