@newrelic/browser-agent 1.276.0 → 1.278.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 (166) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/common/aggregate/event-aggregator.js +1 -1
  3. package/dist/cjs/common/config/init.js +1 -10
  4. package/dist/cjs/common/config/runtime.js +2 -1
  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 +255 -0
  8. package/dist/cjs/common/harvest/types.js +5 -21
  9. package/dist/cjs/features/ajax/aggregate/index.js +2 -11
  10. package/dist/cjs/features/generic_events/aggregate/index.js +17 -13
  11. package/dist/cjs/features/generic_events/constants.js +2 -1
  12. package/dist/cjs/features/jserrors/aggregate/index.js +3 -14
  13. package/dist/cjs/features/logging/aggregate/index.js +4 -12
  14. package/dist/cjs/features/metrics/aggregate/index.js +7 -15
  15. package/dist/cjs/features/page_view_event/aggregate/index.js +46 -48
  16. package/dist/cjs/features/page_view_timing/aggregate/index.js +0 -9
  17. package/dist/cjs/features/session_replay/aggregate/index.js +21 -43
  18. package/dist/cjs/features/session_replay/instrument/index.js +2 -1
  19. package/dist/cjs/features/session_replay/shared/recorder.js +6 -6
  20. package/dist/cjs/features/session_trace/aggregate/index.js +9 -24
  21. package/dist/cjs/features/session_trace/aggregate/trace/storage.js +8 -2
  22. package/dist/cjs/features/soft_navigations/aggregate/index.js +31 -21
  23. package/dist/cjs/features/soft_navigations/aggregate/initial-page-load-interaction.js +2 -1
  24. package/dist/cjs/features/soft_navigations/aggregate/interaction.js +12 -12
  25. package/dist/cjs/features/soft_navigations/constants.js +5 -2
  26. package/dist/cjs/features/spa/aggregate/index.js +7 -10
  27. package/dist/cjs/features/utils/aggregate-base.js +66 -27
  28. package/dist/cjs/features/utils/event-buffer.js +0 -1
  29. package/dist/cjs/features/utils/event-store-manager.js +109 -0
  30. package/dist/cjs/features/utils/instrument-base.js +1 -10
  31. package/dist/cjs/loaders/api/api-methods.js +1 -1
  32. package/dist/cjs/loaders/api/api.js +2 -1
  33. package/dist/cjs/loaders/features/features.js +16 -10
  34. package/dist/cjs/loaders/micro-agent-base.js +10 -0
  35. package/dist/cjs/loaders/micro-agent.js +1 -0
  36. package/dist/esm/common/aggregate/event-aggregator.js +1 -1
  37. package/dist/esm/common/config/init.js +1 -10
  38. package/dist/esm/common/config/runtime.js +2 -1
  39. package/dist/esm/common/constants/env.cdn.js +1 -1
  40. package/dist/esm/common/constants/env.npm.js +1 -1
  41. package/dist/esm/common/harvest/harvester.js +249 -0
  42. package/dist/esm/common/harvest/types.js +5 -21
  43. package/dist/esm/features/ajax/aggregate/index.js +3 -12
  44. package/dist/esm/features/generic_events/aggregate/index.js +18 -14
  45. package/dist/esm/features/generic_events/constants.js +1 -0
  46. package/dist/esm/features/jserrors/aggregate/index.js +4 -15
  47. package/dist/esm/features/logging/aggregate/index.js +4 -12
  48. package/dist/esm/features/metrics/aggregate/index.js +7 -15
  49. package/dist/esm/features/page_view_event/aggregate/index.js +46 -48
  50. package/dist/esm/features/page_view_timing/aggregate/index.js +1 -10
  51. package/dist/esm/features/session_replay/aggregate/index.js +22 -44
  52. package/dist/esm/features/session_replay/instrument/index.js +2 -1
  53. package/dist/esm/features/session_replay/shared/recorder.js +6 -6
  54. package/dist/esm/features/session_trace/aggregate/index.js +9 -24
  55. package/dist/esm/features/session_trace/aggregate/trace/storage.js +8 -2
  56. package/dist/esm/features/soft_navigations/aggregate/index.js +33 -23
  57. package/dist/esm/features/soft_navigations/aggregate/initial-page-load-interaction.js +2 -1
  58. package/dist/esm/features/soft_navigations/aggregate/interaction.js +13 -13
  59. package/dist/esm/features/soft_navigations/constants.js +4 -1
  60. package/dist/esm/features/spa/aggregate/index.js +8 -11
  61. package/dist/esm/features/utils/aggregate-base.js +66 -27
  62. package/dist/esm/features/utils/event-buffer.js +0 -1
  63. package/dist/esm/features/utils/event-store-manager.js +103 -0
  64. package/dist/esm/features/utils/instrument-base.js +1 -10
  65. package/dist/esm/loaders/api/api-methods.js +1 -1
  66. package/dist/esm/loaders/api/api.js +2 -1
  67. package/dist/esm/loaders/features/features.js +15 -9
  68. package/dist/esm/loaders/micro-agent-base.js +10 -0
  69. package/dist/esm/loaders/micro-agent.js +1 -0
  70. package/dist/types/common/aggregate/event-aggregator.d.ts +1 -1
  71. package/dist/types/common/aggregate/event-aggregator.d.ts.map +1 -1
  72. package/dist/types/common/config/init.d.ts.map +1 -1
  73. package/dist/types/common/config/runtime.d.ts.map +1 -1
  74. package/dist/types/common/harvest/harvester.d.ts +16 -0
  75. package/dist/types/common/harvest/harvester.d.ts.map +1 -0
  76. package/dist/types/common/harvest/types.d.ts +8 -45
  77. package/dist/types/common/harvest/types.d.ts.map +1 -1
  78. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  79. package/dist/types/features/generic_events/aggregate/index.d.ts +1 -3
  80. package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
  81. package/dist/types/features/generic_events/constants.d.ts +1 -0
  82. package/dist/types/features/generic_events/constants.d.ts.map +1 -1
  83. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  84. package/dist/types/features/logging/aggregate/index.d.ts +0 -3
  85. package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
  86. package/dist/types/features/metrics/aggregate/index.d.ts +1 -1
  87. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  88. package/dist/types/features/page_view_event/aggregate/index.d.ts +6 -2
  89. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  90. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  91. package/dist/types/features/session_replay/aggregate/index.d.ts +12 -15
  92. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  93. package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
  94. package/dist/types/features/session_trace/aggregate/index.d.ts +0 -5
  95. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  96. package/dist/types/features/session_trace/aggregate/trace/storage.d.ts +8 -5
  97. package/dist/types/features/session_trace/aggregate/trace/storage.d.ts.map +1 -1
  98. package/dist/types/features/soft_navigations/aggregate/index.d.ts +1 -0
  99. package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
  100. package/dist/types/features/soft_navigations/aggregate/initial-page-load-interaction.d.ts.map +1 -1
  101. package/dist/types/features/soft_navigations/aggregate/interaction.d.ts +3 -3
  102. package/dist/types/features/soft_navigations/aggregate/interaction.d.ts.map +1 -1
  103. package/dist/types/features/soft_navigations/constants.d.ts +1 -0
  104. package/dist/types/features/soft_navigations/constants.d.ts.map +1 -1
  105. package/dist/types/features/spa/aggregate/index.d.ts +0 -1
  106. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  107. package/dist/types/features/utils/aggregate-base.d.ts +12 -7
  108. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  109. package/dist/types/features/utils/event-buffer.d.ts +1 -2
  110. package/dist/types/features/utils/event-buffer.d.ts.map +1 -1
  111. package/dist/types/features/utils/event-store-manager.d.ts +43 -0
  112. package/dist/types/features/utils/event-store-manager.d.ts.map +1 -0
  113. package/dist/types/features/utils/instrument-base.d.ts +0 -1
  114. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  115. package/dist/types/loaders/api/api.d.ts +1 -0
  116. package/dist/types/loaders/api/api.d.ts.map +1 -1
  117. package/dist/types/loaders/features/features.d.ts +15 -12
  118. package/dist/types/loaders/features/features.d.ts.map +1 -1
  119. package/dist/types/loaders/micro-agent-base.d.ts +7 -0
  120. package/dist/types/loaders/micro-agent-base.d.ts.map +1 -1
  121. package/dist/types/loaders/micro-agent.d.ts.map +1 -1
  122. package/package.json +6 -6
  123. package/src/common/aggregate/event-aggregator.js +1 -1
  124. package/src/common/config/init.js +9 -10
  125. package/src/common/config/runtime.js +2 -1
  126. package/src/common/harvest/__mocks__/harvester.js +6 -0
  127. package/src/common/harvest/harvester.js +230 -0
  128. package/src/common/harvest/types.js +5 -21
  129. package/src/features/ajax/aggregate/index.js +3 -14
  130. package/src/features/generic_events/aggregate/index.js +20 -17
  131. package/src/features/generic_events/constants.js +2 -0
  132. package/src/features/jserrors/aggregate/index.js +4 -11
  133. package/src/features/logging/aggregate/index.js +4 -12
  134. package/src/features/metrics/aggregate/index.js +5 -12
  135. package/src/features/page_view_event/aggregate/index.js +38 -38
  136. package/src/features/page_view_timing/aggregate/index.js +1 -12
  137. package/src/features/session_replay/aggregate/index.js +19 -42
  138. package/src/features/session_replay/instrument/index.js +1 -1
  139. package/src/features/session_replay/shared/recorder.js +6 -6
  140. package/src/features/session_trace/aggregate/index.js +8 -25
  141. package/src/features/session_trace/aggregate/trace/storage.js +5 -2
  142. package/src/features/soft_navigations/aggregate/index.js +26 -23
  143. package/src/features/soft_navigations/aggregate/initial-page-load-interaction.js +2 -1
  144. package/src/features/soft_navigations/aggregate/interaction.js +13 -12
  145. package/src/features/soft_navigations/constants.js +3 -1
  146. package/src/features/spa/aggregate/index.js +8 -11
  147. package/src/features/utils/aggregate-base.js +59 -27
  148. package/src/features/utils/event-buffer.js +0 -1
  149. package/src/features/utils/event-store-manager.js +101 -0
  150. package/src/features/utils/instrument-base.js +2 -8
  151. package/src/loaders/api/api-methods.js +1 -1
  152. package/src/loaders/api/api.js +3 -1
  153. package/src/loaders/features/features.js +16 -9
  154. package/src/loaders/micro-agent-base.js +10 -0
  155. package/src/loaders/micro-agent.js +1 -0
  156. package/dist/cjs/common/harvest/harvest-scheduler.js +0 -168
  157. package/dist/cjs/common/harvest/harvest.js +0 -295
  158. package/dist/esm/common/harvest/harvest-scheduler.js +0 -160
  159. package/dist/esm/common/harvest/harvest.js +0 -286
  160. package/dist/types/common/harvest/harvest-scheduler.d.ts +0 -50
  161. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +0 -1
  162. package/dist/types/common/harvest/harvest.d.ts +0 -65
  163. package/dist/types/common/harvest/harvest.d.ts.map +0 -1
  164. package/src/common/harvest/__mocks__/harvest.js +0 -13
  165. package/src/common/harvest/harvest-scheduler.js +0 -166
  166. package/src/common/harvest/harvest.js +0 -282
@@ -1,286 +0,0 @@
1
- /*
2
- * Copyright 2020 New Relic Corporation. All rights reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
-
6
- import { obj as encodeObj, param as encodeParam } from '../url/encode';
7
- import { stringify } from '../util/stringify';
8
- import * as submitData from '../util/submit-data';
9
- import { getLocation } from '../url/location';
10
- import { getInfo } from '../config/info';
11
- import { getConfigurationValue, getConfiguration } from '../config/init';
12
- import { getRuntime } from '../config/runtime';
13
- import { cleanURL } from '../url/clean-url';
14
- import { eventListenerOpts } from '../event-listener/event-listener-opts';
15
- import { SharedContext } from '../context/shared-context';
16
- import { VERSION } from "../constants/env.npm";
17
- import { isWorkerScope } from '../constants/runtime';
18
- import { warn } from '../util/console';
19
- import { now } from '../timing/now';
20
- const warnings = {};
21
-
22
- /**
23
- * @typedef {import('./types.js').NetworkSendSpec} NetworkSendSpec
24
- * @typedef {import('./types.js').HarvestEndpointIdentifier} HarvestEndpointIdentifier
25
- * @typedef {import('./types.js').HarvestPayload} HarvestPayload
26
- * @typedef {import('./types.js').FeatureHarvestCallback} FeatureHarvestCallback
27
- * @typedef {import('./types.js').FeatureHarvestCallbackOptions} FeatureHarvestCallbackOptions
28
- */
29
- export class Harvest extends SharedContext {
30
- constructor(parent) {
31
- super(parent); // gets any allowed properties from the parent and stores them in `sharedContext`
32
-
33
- this.tooManyRequestsDelay = getConfigurationValue(this.sharedContext.agentIdentifier, 'harvest.tooManyRequestsDelay') || 60;
34
- this.obfuscator = getRuntime(this.sharedContext.agentIdentifier).obfuscator;
35
- this._events = {};
36
- }
37
-
38
- /**
39
- * Initiate a harvest from multiple sources. An event that corresponds to the endpoint
40
- * name is emitted, which gives any listeners the opportunity to provide payload data.
41
- * Note: Used by page_action
42
- * @param {NetworkSendSpec} spec Specification for sending data
43
- */
44
- sendX(spec = {}) {
45
- const submitMethod = submitData.getSubmitMethod({
46
- isFinalHarvest: spec.opts?.unload
47
- });
48
- const options = {
49
- retry: !spec.opts?.unload && submitMethod === submitData.xhr,
50
- isFinalHarvest: spec.opts?.unload === true
51
- };
52
- const payload = this.createPayload(spec.endpoint, options);
53
- const caller = this._send.bind(this);
54
- return caller({
55
- ...spec,
56
- payload,
57
- submitMethod
58
- });
59
- }
60
-
61
- /**
62
- * Initiate a harvest call.
63
- * @param {NetworkSendSpec} spec Specification for sending data
64
- */
65
- send(spec = {}) {
66
- const caller = this._send.bind(this);
67
- return caller(spec);
68
- }
69
-
70
- /**
71
- * Initiate a harvest call. Typically used by `sendX` and `send` methods or called directly
72
- * for raw network calls.
73
- * @param {NetworkSendSpec} param0 Specification for sending data
74
- * @returns {boolean} True if the network call succeeded. For final harvest calls, the return
75
- * value should not be relied upon because network calls will be made asynchronously.
76
- */
77
- _send({
78
- endpoint,
79
- payload = {},
80
- opts = {},
81
- submitMethod,
82
- cbFinished,
83
- customUrl,
84
- raw,
85
- includeBaseParams = true
86
- }) {
87
- const info = getInfo(this.sharedContext.agentIdentifier);
88
- if (!info.errorBeacon) return false;
89
- const agentRuntime = getRuntime(this.sharedContext.agentIdentifier);
90
- let {
91
- body,
92
- qs
93
- } = this.cleanPayload(payload);
94
- if (Object.keys(body).length === 0 && !opts?.sendEmptyBody) {
95
- // no payload body? nothing to send, just run onfinish stuff and return
96
- if (cbFinished) {
97
- cbFinished({
98
- sent: false
99
- });
100
- }
101
- return false;
102
- }
103
- const init = getConfiguration(this.sharedContext.agentIdentifier);
104
- const protocol = init.ssl === false ? 'http' : 'https';
105
- const perceviedBeacon = init.proxy.beacon || info.errorBeacon;
106
- const endpointURLPart = endpoint !== 'rum' ? "/".concat(endpoint) : '';
107
- let url = "".concat(protocol, "://").concat(perceviedBeacon).concat(endpointURLPart, "/1/").concat(info.licenseKey);
108
- if (customUrl) url = customUrl;
109
- if (raw) url = "".concat(protocol, "://").concat(perceviedBeacon, "/").concat(endpoint);
110
- const baseParams = !raw && includeBaseParams ? this.baseQueryString(qs, endpoint) : '';
111
- let payloadParams = encodeObj(qs, agentRuntime.maxBytes);
112
- if (!submitMethod) {
113
- submitMethod = submitData.getSubmitMethod({
114
- isFinalHarvest: opts.unload
115
- });
116
- }
117
- if (baseParams === '' && payloadParams.startsWith('&')) {
118
- payloadParams = payloadParams.substring(1);
119
- }
120
- const fullUrl = "".concat(url, "?").concat(baseParams).concat(payloadParams);
121
- const gzip = !!qs?.attributes?.includes('gzip');
122
- if (!gzip) {
123
- if (endpoint !== 'events') body = stringify(body); // all features going to /events/ endpoint should already be serialized & stringified
124
- /** Warn --once per endpoint-- if the agent tries to send large payloads */
125
- if (body.length > 750000 && (warnings[endpoint] = (warnings?.[endpoint] || 0) + 1) === 1) warn(28, endpoint);
126
- }
127
- if (!body || body.length === 0 || body === '{}' || body === '[]') {
128
- // If body is null, undefined, or an empty object or array, send an empty string instead
129
- body = '';
130
- }
131
- const headers = [];
132
- headers.push({
133
- key: 'content-type',
134
- value: 'text/plain'
135
- });
136
-
137
- /* Since workers don't support sendBeacon right now, they can only use XHR method.
138
- Because they still do permit synch XHR, the idea is that at final harvest time (worker is closing),
139
- we just make a BLOCKING request--trivial impact--with the remaining data as a temp fill-in for sendBeacon.
140
- Following the removal of img-element method. */
141
- let result = submitMethod({
142
- url: fullUrl,
143
- body,
144
- sync: opts.unload && isWorkerScope,
145
- headers
146
- });
147
- if (!opts.unload && cbFinished && submitMethod === submitData.xhr) {
148
- const harvestScope = this;
149
- result.addEventListener('loadend', function () {
150
- // `this` refers to the XHR object in this scope, do not change this to a fat arrow
151
- // status 0 refers to a local error, such as CORS or network failure, or a blocked request by the browser (e.g. adblocker)
152
- const cbResult = {
153
- sent: this.status !== 0,
154
- status: this.status,
155
- xhr: this,
156
- fullUrl
157
- };
158
- if (this.status === 429) {
159
- cbResult.retry = true;
160
- cbResult.delay = harvestScope.tooManyRequestsDelay;
161
- } else if (this.status === 408 || this.status === 500 || this.status === 503) {
162
- cbResult.retry = true;
163
- }
164
- if (opts.needResponse) {
165
- cbResult.responseText = this.responseText;
166
- }
167
- cbFinished(cbResult);
168
- }, eventListenerOpts(false));
169
- } else if (!opts.unload && cbFinished && submitMethod === submitData.xhrFetch) {
170
- const harvestScope = this;
171
- result.then(async function (response) {
172
- const status = response.status;
173
- const cbResult = {
174
- sent: true,
175
- status,
176
- fullUrl,
177
- fetchResponse: response
178
- };
179
- if (response.status === 429) {
180
- cbResult.retry = true;
181
- cbResult.delay = harvestScope.tooManyRequestsDelay;
182
- } else if (status === 408 || status === 500 || status === 503) {
183
- cbResult.retry = true;
184
- }
185
- if (opts.needResponse) {
186
- cbResult.responseText = await response.text();
187
- }
188
- cbFinished(cbResult);
189
- });
190
- }
191
- return result;
192
- }
193
-
194
- // The stuff that gets sent every time.
195
- baseQueryString(qs, endpoint) {
196
- const runtime = getRuntime(this.sharedContext.agentIdentifier);
197
- const info = getInfo(this.sharedContext.agentIdentifier);
198
- const ref = this.obfuscator.obfuscateString(cleanURL(getLocation()));
199
- const hr = runtime?.session?.state.sessionReplayMode === 1 && endpoint !== 'jserrors';
200
- const qps = ['a=' + info.applicationID, encodeParam('sa', info.sa ? '' + info.sa : ''), encodeParam('v', VERSION), transactionNameParam(info), encodeParam('ct', runtime.customTransaction), '&rst=' + now(), '&ck=0',
201
- // ck param DEPRECATED - still expected by backend
202
- '&s=' + (runtime.session?.state.value || '0'),
203
- // the 0 id encaps all untrackable and default traffic
204
- encodeParam('ref', ref), encodeParam('ptid', runtime.ptid ? '' + runtime.ptid : '')];
205
- if (hr) qps.push(encodeParam('hr', '1', qs));
206
- return qps.join('');
207
- }
208
-
209
- /**
210
- * Calls and accumulates data from registered harvesting functions based on
211
- * the endpoint being harvested.
212
- * @param {HarvestEndpointIdentifier} endpoint BAM endpoint identifier.
213
- * @param {FeatureHarvestCallbackOptions} options Options to be passed to the
214
- * feature harvest listener callback.
215
- * @returns {HarvestPayload} Payload object to transmit to the bam endpoint.
216
- */
217
- createPayload(endpoint, options) {
218
- const listeners = this._events[endpoint];
219
- const payload = {
220
- body: {},
221
- qs: {}
222
- };
223
- if (Array.isArray(listeners) && listeners.length > 0) {
224
- for (let i = 0; i < listeners.length; i++) {
225
- const singlePayload = listeners[i](options);
226
- if (singlePayload) {
227
- payload.body = {
228
- ...payload.body,
229
- ...(singlePayload.body || {})
230
- };
231
- payload.qs = {
232
- ...payload.qs,
233
- ...(singlePayload.qs || {})
234
- };
235
- }
236
- }
237
- }
238
- return payload;
239
- }
240
-
241
- /**
242
- * Cleans and returns a payload object containing a body and qs
243
- * object with key/value pairs. KV pairs where the value is null,
244
- * undefined, or an empty string are removed to save on transmission
245
- * size.
246
- * @param {HarvestPayload} payload Payload to be sent to the endpoint.
247
- * @returns {HarvestPayload} Cleaned payload payload to be sent to the endpoint.
248
- */
249
- cleanPayload(payload = {}) {
250
- const clean = input => {
251
- if (typeof Uint8Array !== 'undefined' && input instanceof Uint8Array || Array.isArray(input)) return input;
252
- if (typeof input === 'string') return input.length > 0 ? input : null;
253
- return Object.entries(input || {}).reduce((accumulator, [key, value]) => {
254
- if (typeof value === 'number' || typeof value === 'string' && value.length > 0 || typeof value === 'object' && Object.keys(value || {}).length > 0) {
255
- accumulator[key] = value;
256
- }
257
- return accumulator;
258
- }, {});
259
- };
260
- return {
261
- body: clean(payload.body),
262
- qs: clean(payload.qs)
263
- };
264
- }
265
-
266
- /**
267
- * Registers a function to be called when harvesting is triggered for a specific
268
- * endpoint.
269
- * @param {HarvestEndpointIdentifier} endpoint
270
- * @param {FeatureHarvestCallback} listener
271
- */
272
- on(endpoint, listener) {
273
- if (!Array.isArray(this._events[endpoint])) {
274
- this._events[endpoint] = [];
275
- }
276
- this._events[endpoint].push(listener);
277
- }
278
- }
279
-
280
- // Constructs the transaction name param for the beacon URL.
281
- // Prefers the obfuscated transaction name over the plain text.
282
- // Falls back to making up a name.
283
- function transactionNameParam(info) {
284
- if (info.transactionName) return encodeParam('to', info.transactionName);
285
- return encodeParam('t', info.tNamePlain || 'Unnamed Transaction');
286
- }
@@ -1,50 +0,0 @@
1
- /**
2
- * Periodically invokes harvest calls and handles retries
3
- */
4
- export class HarvestScheduler extends SharedContext {
5
- /**
6
- * Create a HarvestScheduler
7
- * @param {string} endpoint - The base BAM endpoint name -- ex. 'events'
8
- * @param {object} opts - The options used to configure the HarvestScheduler
9
- * @param {Function} opts.onFinished - The callback to be fired when a harvest has finished
10
- * @param {Function} opts.getPayload - A callback which can be triggered to return a payload for harvesting
11
- * @param {number} opts.retryDelay - The number of seconds to wait before retrying after a network failure
12
- * @param {boolean} opts.raw - Use a prefabricated payload shape as the harvest payload without the need for formatting
13
- * @param {string} opts.customUrl - A custom url that falls outside of the shape of the standard BAM harvester url pattern. Will use directly instead of concatenating various pieces
14
- * @param {*} parent - The parent object, whose state can be passed into SharedContext
15
- */
16
- constructor(endpoint: string, opts: {
17
- onFinished: Function;
18
- getPayload: Function;
19
- retryDelay: number;
20
- raw: boolean;
21
- customUrl: string;
22
- }, parent: any);
23
- endpoint: string;
24
- opts: {
25
- onFinished: Function;
26
- getPayload: Function;
27
- retryDelay: number;
28
- raw: boolean;
29
- customUrl: string;
30
- };
31
- started: boolean;
32
- timeoutHandle: any;
33
- aborted: boolean;
34
- harvesting: boolean;
35
- harvest: Harvest;
36
- /**
37
- * This function is only meant for the last outgoing harvest cycle of a page. It trickles down to using sendBeacon, which should not be used
38
- * to send payloads while the page is still active, due to limitations on how much data can be buffered in the API at any one time.
39
- */
40
- unload(): void;
41
- startTimer(interval: any, initialDelay: any): void;
42
- interval: any;
43
- stopTimer(permanently?: boolean): void;
44
- scheduleHarvest(delay: any, opts: any): void;
45
- runHarvest(opts: any): false | undefined;
46
- onHarvestFinished(opts: any, result: any): void;
47
- }
48
- import { SharedContext } from '../context/shared-context';
49
- import { Harvest } from './harvest';
50
- //# sourceMappingURL=harvest-scheduler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"harvest-scheduler.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/harvest-scheduler.js"],"names":[],"mappings":"AAWA;;GAEG;AACH;IACE;;;;;;;;;;SAUK;IACL,sBATa,MAAM,QAEd;QAAuB,UAAU;QACV,UAAU;QACZ,UAAU,EAAvB,MAAM;QACQ,GAAG,EAAjB,OAAO;QACM,SAAS,EAAtB,MAAM;KACd,UAAQ,GAAC,EAoBb;IAhBC,iBAAwB;IACxB;;;oBARW,MAAM;aACN,OAAO;mBACP,MAAM;MAMK;IACtB,iBAAoB;IACpB,mBAAyB;IACzB,iBAAoB;IACpB,oBAAuB;IACvB,iBAA8C;IAYhD;;;OAGG;IACH,eAGC;IAED,mDAIC;IAHC,cAAwB;IAK1B,uCAMC;IAED,6CAUC;IAED,yCAgEC;IAED,gDAiBC;CACF;8BA/J6B,2BAA2B;wBACjC,WAAW"}
@@ -1,65 +0,0 @@
1
- /**
2
- * @typedef {import('./types.js').NetworkSendSpec} NetworkSendSpec
3
- * @typedef {import('./types.js').HarvestEndpointIdentifier} HarvestEndpointIdentifier
4
- * @typedef {import('./types.js').HarvestPayload} HarvestPayload
5
- * @typedef {import('./types.js').FeatureHarvestCallback} FeatureHarvestCallback
6
- * @typedef {import('./types.js').FeatureHarvestCallbackOptions} FeatureHarvestCallbackOptions
7
- */
8
- export class Harvest extends SharedContext {
9
- tooManyRequestsDelay: any;
10
- obfuscator: any;
11
- _events: {};
12
- /**
13
- * Initiate a harvest from multiple sources. An event that corresponds to the endpoint
14
- * name is emitted, which gives any listeners the opportunity to provide payload data.
15
- * Note: Used by page_action
16
- * @param {NetworkSendSpec} spec Specification for sending data
17
- */
18
- sendX(spec?: NetworkSendSpec): boolean;
19
- /**
20
- * Initiate a harvest call.
21
- * @param {NetworkSendSpec} spec Specification for sending data
22
- */
23
- send(spec?: NetworkSendSpec): boolean;
24
- /**
25
- * Initiate a harvest call. Typically used by `sendX` and `send` methods or called directly
26
- * for raw network calls.
27
- * @param {NetworkSendSpec} param0 Specification for sending data
28
- * @returns {boolean} True if the network call succeeded. For final harvest calls, the return
29
- * value should not be relied upon because network calls will be made asynchronously.
30
- */
31
- _send({ endpoint, payload, opts, submitMethod, cbFinished, customUrl, raw, includeBaseParams }: NetworkSendSpec): boolean;
32
- baseQueryString(qs: any, endpoint: any): string;
33
- /**
34
- * Calls and accumulates data from registered harvesting functions based on
35
- * the endpoint being harvested.
36
- * @param {HarvestEndpointIdentifier} endpoint BAM endpoint identifier.
37
- * @param {FeatureHarvestCallbackOptions} options Options to be passed to the
38
- * feature harvest listener callback.
39
- * @returns {HarvestPayload} Payload object to transmit to the bam endpoint.
40
- */
41
- createPayload(endpoint: HarvestEndpointIdentifier, options: FeatureHarvestCallbackOptions): HarvestPayload;
42
- /**
43
- * Cleans and returns a payload object containing a body and qs
44
- * object with key/value pairs. KV pairs where the value is null,
45
- * undefined, or an empty string are removed to save on transmission
46
- * size.
47
- * @param {HarvestPayload} payload Payload to be sent to the endpoint.
48
- * @returns {HarvestPayload} Cleaned payload payload to be sent to the endpoint.
49
- */
50
- cleanPayload(payload?: HarvestPayload): HarvestPayload;
51
- /**
52
- * Registers a function to be called when harvesting is triggered for a specific
53
- * endpoint.
54
- * @param {HarvestEndpointIdentifier} endpoint
55
- * @param {FeatureHarvestCallback} listener
56
- */
57
- on(endpoint: HarvestEndpointIdentifier, listener: FeatureHarvestCallback): void;
58
- }
59
- export type NetworkSendSpec = import("./types.js").NetworkSendSpec;
60
- export type HarvestEndpointIdentifier = import("./types.js").HarvestEndpointIdentifier;
61
- export type HarvestPayload = import("./types.js").HarvestPayload;
62
- export type FeatureHarvestCallback = import("./types.js").FeatureHarvestCallback;
63
- export type FeatureHarvestCallbackOptions = import("./types.js").FeatureHarvestCallbackOptions;
64
- import { SharedContext } from '../context/shared-context';
65
- //# sourceMappingURL=harvest.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"harvest.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/harvest.js"],"names":[],"mappings":"AAsBA;;;;;;GAMG;AACH;IAII,0BAA2H;IAC3H,gBAA2E;IAE3E,YAAiB;IAGnB;;;;;OAKG;IACH,aAFW,eAAe,WAWzB;IAED;;;OAGG;IACH,YAFW,eAAe,WAMzB;IAED;;;;;;OAMG;IACH,gGAJW,eAAe,GACb,OAAO,CAkGnB;IAGD,gDAqBC;IAED;;;;;;;OAOG;IACH,wBALW,yBAAyB,WACzB,6BAA6B,GAE3B,cAAc,CA2B1B;IAED;;;;;;;OAOG;IACH,uBAHW,cAAc,GACZ,cAAc,CAuB1B;IAED;;;;;OAKG;IACH,aAHW,yBAAyB,YACzB,sBAAsB,QAQhC;CACF;8BA1PY,OAAO,YAAY,EAAE,eAAe;wCACpC,OAAO,YAAY,EAAE,yBAAyB;6BAC9C,OAAO,YAAY,EAAE,cAAc;qCACnC,OAAO,YAAY,EAAE,sBAAsB;4CAC3C,OAAO,YAAY,EAAE,6BAA6B;8BAbjC,2BAA2B"}
@@ -1,13 +0,0 @@
1
- export const Harvest = jest.fn(function () {
2
- this.sharedContext = {
3
- agentIdentifier: 'abcd'
4
- }
5
- this.sendX = jest.fn()
6
- this.send = jest.fn()
7
- this.obfuscateAndSend = jest.fn()
8
- this._send = jest.fn()
9
- this.baseQueryString = jest.fn()
10
- this.createPayload = jest.fn()
11
- this.cleanPayload = jest.fn()
12
- this.on = jest.fn()
13
- })
@@ -1,166 +0,0 @@
1
- /*
2
- * Copyright 2020 New Relic Corporation. All rights reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
-
6
- import * as submitData from '../util/submit-data'
7
- import { SharedContext } from '../context/shared-context'
8
- import { Harvest } from './harvest'
9
- import { subscribeToEOL } from '../unload/eol'
10
- import { SESSION_EVENTS } from '../session/constants'
11
-
12
- /**
13
- * Periodically invokes harvest calls and handles retries
14
- */
15
- export class HarvestScheduler extends SharedContext {
16
- /**
17
- * Create a HarvestScheduler
18
- * @param {string} endpoint - The base BAM endpoint name -- ex. 'events'
19
- * @param {object} opts - The options used to configure the HarvestScheduler
20
- * @param {Function} opts.onFinished - The callback to be fired when a harvest has finished
21
- * @param {Function} opts.getPayload - A callback which can be triggered to return a payload for harvesting
22
- * @param {number} opts.retryDelay - The number of seconds to wait before retrying after a network failure
23
- * @param {boolean} opts.raw - Use a prefabricated payload shape as the harvest payload without the need for formatting
24
- * @param {string} opts.customUrl - A custom url that falls outside of the shape of the standard BAM harvester url pattern. Will use directly instead of concatenating various pieces
25
- * @param {*} parent - The parent object, whose state can be passed into SharedContext
26
- */
27
- constructor (endpoint, opts, parent) {
28
- super(parent) // gets any allowed properties from the parent and stores them in `sharedContext`
29
- this.endpoint = endpoint
30
- this.opts = opts || {}
31
- this.started = false
32
- this.timeoutHandle = null
33
- this.aborted = false // this controls the per-interval and final harvests for the scheduler (currently per feature specific!)
34
- this.harvesting = false
35
- this.harvest = new Harvest(this.sharedContext)
36
-
37
- // If a feature specifies stuff to be done on page unload, those are frontrunned (via capture phase) before ANY feature final harvests.
38
- if (typeof this.opts.onUnload === 'function') subscribeToEOL(this.opts.onUnload, true)
39
- subscribeToEOL(this.unload.bind(this)) // this should consist only of sending final harvest
40
-
41
- /* Flush all buffered data if session resets and give up retries. This should be synchronous to ensure that the correct `session` value is sent.
42
- Since session-reset generates a new session ID and the ID is grabbed at send-time, any delays or retries would cause the payload to be sent under
43
- the wrong session ID. */
44
- this.sharedContext?.ee.on(SESSION_EVENTS.RESET, () => this.runHarvest({ forceNoRetry: true }))
45
- }
46
-
47
- /**
48
- * This function is only meant for the last outgoing harvest cycle of a page. It trickles down to using sendBeacon, which should not be used
49
- * to send payloads while the page is still active, due to limitations on how much data can be buffered in the API at any one time.
50
- */
51
- unload () {
52
- if (this.aborted) return
53
- this.runHarvest({ unload: true })
54
- }
55
-
56
- startTimer (interval, initialDelay) {
57
- this.interval = interval
58
- this.started = true
59
- this.scheduleHarvest(initialDelay != null ? initialDelay : this.interval)
60
- }
61
-
62
- stopTimer (permanently = false) {
63
- this.aborted = permanently // stopping permanently is same as aborting, but this function also cleans up the setTimeout loop
64
- this.started = false
65
- if (this.timeoutHandle) {
66
- clearTimeout(this.timeoutHandle)
67
- }
68
- }
69
-
70
- scheduleHarvest (delay, opts) {
71
- if (this.timeoutHandle) return
72
-
73
- if (delay == null) {
74
- delay = this.interval
75
- }
76
- this.timeoutHandle = setTimeout(() => {
77
- this.timeoutHandle = null
78
- this.runHarvest(opts)
79
- }, delay * 1000)
80
- }
81
-
82
- runHarvest (opts) {
83
- if (this.aborted) return
84
- this.harvesting = true
85
-
86
- /**
87
- * This is executed immediately after harvest sends the data via XHR, or if there's nothing to send. Note that this excludes on unloading / sendBeacon.
88
- * @param {Object} result
89
- */
90
- const cbRanAfterSend = (result) => {
91
- this.harvesting = false
92
- if (opts?.forceNoRetry) result.retry = false // discard unsent data rather than re-queuing for next harvest attempt
93
- this.onHarvestFinished(opts, result)
94
- }
95
-
96
- let harvests = []
97
- let submitMethod
98
- let payload
99
-
100
- if (this.opts.getPayload) {
101
- // Ajax, PVT, Softnav, Logging, SR & ST features provide a single callback function to get data for harvesting
102
- submitMethod = submitData.getSubmitMethod({ isFinalHarvest: opts?.unload })
103
- if (!submitMethod) return false
104
-
105
- const retry = !opts?.unload && submitMethod === submitData.xhr
106
- payload = this.opts.getPayload({ retry, ...opts })
107
-
108
- if (!payload) {
109
- if (this.started) {
110
- this.scheduleHarvest()
111
- }
112
- return
113
- }
114
-
115
- payload = Object.prototype.toString.call(payload) === '[object Array]' ? payload : [payload]
116
- harvests.push(...payload)
117
- }
118
-
119
- /** sendX is used for features that do not supply a preformatted payload via "getPayload" */
120
- let send = args => this.harvest.sendX(args)
121
- if (harvests.length) {
122
- /** _send is the underlying method for sending in the harvest, if sending raw we can bypass the other helpers completely which format the payloads */
123
- if (this.opts.raw) send = args => this.harvest._send(args)
124
- /** send is used to formated the payloads from "getPayload" and obfuscate before sending */
125
- else send = args => this.harvest.send(args)
126
- } else {
127
- // force it to run at least once in sendX mode
128
- harvests.push(undefined)
129
- }
130
-
131
- harvests.forEach(payload => {
132
- send({
133
- endpoint: this.endpoint,
134
- payload,
135
- opts,
136
- submitMethod,
137
- cbFinished: cbRanAfterSend,
138
- customUrl: this.opts.customUrl,
139
- raw: this.opts.raw
140
- })
141
- })
142
-
143
- if (this.started) {
144
- this.scheduleHarvest()
145
- }
146
- }
147
-
148
- onHarvestFinished (opts, result) {
149
- if (this.opts.onFinished) {
150
- this.opts.onFinished(result)
151
- }
152
-
153
- if (result.sent && result.retry) {
154
- const delay = result.delay || this.opts.retryDelay
155
- // reschedule next harvest if should be delayed longer
156
- if (this.started && delay) {
157
- clearTimeout(this.timeoutHandle)
158
- this.timeoutHandle = null
159
- this.scheduleHarvest(delay, opts)
160
- } else if (!this.started && delay) {
161
- // if not running on a timer, schedule a single retry
162
- this.scheduleHarvest(delay, opts)
163
- }
164
- }
165
- }
166
- }