@newrelic/browser-agent 1.277.0 → 1.278.1
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 +14 -0
- package/dist/cjs/common/aggregate/event-aggregator.js +1 -1
- package/dist/cjs/common/config/init.js +1 -10
- package/dist/cjs/common/config/runtime.js +2 -1
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/harvest/harvester.js +255 -0
- package/dist/cjs/common/harvest/types.js +5 -21
- package/dist/cjs/features/ajax/aggregate/index.js +2 -11
- package/dist/cjs/features/generic_events/aggregate/index.js +3 -10
- package/dist/cjs/features/jserrors/aggregate/index.js +3 -14
- package/dist/cjs/features/logging/aggregate/index.js +4 -12
- package/dist/cjs/features/metrics/aggregate/index.js +7 -15
- package/dist/cjs/features/page_view_event/aggregate/index.js +46 -48
- package/dist/cjs/features/page_view_timing/aggregate/index.js +0 -9
- package/dist/cjs/features/session_replay/aggregate/index.js +21 -43
- package/dist/cjs/features/session_replay/instrument/index.js +2 -1
- package/dist/cjs/features/session_replay/shared/recorder.js +6 -6
- package/dist/cjs/features/session_trace/aggregate/index.js +9 -24
- package/dist/cjs/features/session_trace/aggregate/trace/storage.js +8 -2
- package/dist/cjs/features/soft_navigations/aggregate/index.js +4 -11
- package/dist/cjs/features/spa/aggregate/index.js +7 -10
- package/dist/cjs/features/utils/aggregate-base.js +66 -27
- package/dist/cjs/features/utils/event-buffer.js +0 -1
- package/dist/cjs/features/utils/event-store-manager.js +109 -0
- package/dist/cjs/features/utils/instrument-base.js +1 -10
- package/dist/cjs/loaders/features/features.js +16 -10
- package/dist/cjs/loaders/micro-agent.js +1 -0
- package/dist/esm/common/aggregate/event-aggregator.js +1 -1
- package/dist/esm/common/config/init.js +1 -10
- package/dist/esm/common/config/runtime.js +2 -1
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/harvest/harvester.js +249 -0
- package/dist/esm/common/harvest/types.js +5 -21
- package/dist/esm/features/ajax/aggregate/index.js +3 -12
- package/dist/esm/features/generic_events/aggregate/index.js +3 -10
- package/dist/esm/features/jserrors/aggregate/index.js +4 -15
- package/dist/esm/features/logging/aggregate/index.js +4 -12
- package/dist/esm/features/metrics/aggregate/index.js +7 -15
- package/dist/esm/features/page_view_event/aggregate/index.js +46 -48
- package/dist/esm/features/page_view_timing/aggregate/index.js +1 -10
- package/dist/esm/features/session_replay/aggregate/index.js +22 -44
- package/dist/esm/features/session_replay/instrument/index.js +2 -1
- package/dist/esm/features/session_replay/shared/recorder.js +6 -6
- package/dist/esm/features/session_trace/aggregate/index.js +9 -24
- package/dist/esm/features/session_trace/aggregate/trace/storage.js +8 -2
- package/dist/esm/features/soft_navigations/aggregate/index.js +5 -12
- package/dist/esm/features/spa/aggregate/index.js +8 -11
- package/dist/esm/features/utils/aggregate-base.js +66 -27
- package/dist/esm/features/utils/event-buffer.js +0 -1
- package/dist/esm/features/utils/event-store-manager.js +103 -0
- package/dist/esm/features/utils/instrument-base.js +1 -10
- package/dist/esm/loaders/features/features.js +15 -9
- package/dist/esm/loaders/micro-agent.js +1 -0
- package/dist/types/common/aggregate/event-aggregator.d.ts +1 -1
- package/dist/types/common/aggregate/event-aggregator.d.ts.map +1 -1
- package/dist/types/common/config/init.d.ts.map +1 -1
- package/dist/types/common/config/runtime.d.ts.map +1 -1
- package/dist/types/common/harvest/harvester.d.ts +16 -0
- package/dist/types/common/harvest/harvester.d.ts.map +1 -0
- package/dist/types/common/harvest/types.d.ts +8 -45
- package/dist/types/common/harvest/types.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/aggregate/index.d.ts +0 -3
- package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/logging/aggregate/index.d.ts +0 -3
- package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +6 -2
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +12 -15
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +0 -5
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/trace/storage.d.ts +8 -5
- package/dist/types/features/session_trace/aggregate/trace/storage.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/index.d.ts +0 -1
- package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +12 -7
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/event-buffer.d.ts +1 -2
- package/dist/types/features/utils/event-buffer.d.ts.map +1 -1
- package/dist/types/features/utils/event-store-manager.d.ts +43 -0
- package/dist/types/features/utils/event-store-manager.d.ts.map +1 -0
- package/dist/types/features/utils/instrument-base.d.ts +0 -1
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts +15 -12
- package/dist/types/loaders/features/features.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/common/aggregate/event-aggregator.js +1 -1
- package/src/common/config/init.js +9 -10
- package/src/common/config/runtime.js +2 -1
- package/src/common/harvest/__mocks__/harvester.js +6 -0
- package/src/common/harvest/harvester.js +230 -0
- package/src/common/harvest/types.js +5 -21
- package/src/features/ajax/aggregate/index.js +3 -14
- package/src/features/generic_events/aggregate/index.js +3 -13
- package/src/features/jserrors/aggregate/index.js +4 -11
- package/src/features/logging/aggregate/index.js +4 -12
- package/src/features/metrics/aggregate/index.js +5 -12
- package/src/features/page_view_event/aggregate/index.js +38 -38
- package/src/features/page_view_timing/aggregate/index.js +1 -12
- package/src/features/session_replay/aggregate/index.js +19 -42
- package/src/features/session_replay/instrument/index.js +1 -1
- package/src/features/session_replay/shared/recorder.js +6 -6
- package/src/features/session_trace/aggregate/index.js +8 -25
- package/src/features/session_trace/aggregate/trace/storage.js +5 -2
- package/src/features/soft_navigations/aggregate/index.js +4 -12
- package/src/features/spa/aggregate/index.js +8 -11
- package/src/features/utils/aggregate-base.js +59 -27
- package/src/features/utils/event-buffer.js +0 -1
- package/src/features/utils/event-store-manager.js +101 -0
- package/src/features/utils/instrument-base.js +2 -8
- package/src/loaders/features/features.js +16 -9
- package/src/loaders/micro-agent.js +1 -0
- package/dist/cjs/common/harvest/harvest-scheduler.js +0 -168
- package/dist/cjs/common/harvest/harvest.js +0 -295
- package/dist/esm/common/harvest/harvest-scheduler.js +0 -160
- package/dist/esm/common/harvest/harvest.js +0 -286
- package/dist/types/common/harvest/harvest-scheduler.d.ts +0 -50
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +0 -1
- package/dist/types/common/harvest/harvest.d.ts +0 -65
- package/dist/types/common/harvest/harvest.d.ts.map +0 -1
- package/src/common/harvest/__mocks__/harvest.js +0 -13
- package/src/common/harvest/harvest-scheduler.js +0 -166
- package/src/common/harvest/harvest.js +0 -282
|
@@ -1,282 +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'
|
|
17
|
-
import { isWorkerScope } from '../constants/runtime'
|
|
18
|
-
import { warn } from '../util/console'
|
|
19
|
-
import { now } from '../timing/now'
|
|
20
|
-
|
|
21
|
-
const warnings = {}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @typedef {import('./types.js').NetworkSendSpec} NetworkSendSpec
|
|
25
|
-
* @typedef {import('./types.js').HarvestEndpointIdentifier} HarvestEndpointIdentifier
|
|
26
|
-
* @typedef {import('./types.js').HarvestPayload} HarvestPayload
|
|
27
|
-
* @typedef {import('./types.js').FeatureHarvestCallback} FeatureHarvestCallback
|
|
28
|
-
* @typedef {import('./types.js').FeatureHarvestCallbackOptions} FeatureHarvestCallbackOptions
|
|
29
|
-
*/
|
|
30
|
-
export class Harvest extends SharedContext {
|
|
31
|
-
constructor (parent) {
|
|
32
|
-
super(parent) // gets any allowed properties from the parent and stores them in `sharedContext`
|
|
33
|
-
|
|
34
|
-
this.tooManyRequestsDelay = getConfigurationValue(this.sharedContext.agentIdentifier, 'harvest.tooManyRequestsDelay') || 60
|
|
35
|
-
this.obfuscator = getRuntime(this.sharedContext.agentIdentifier).obfuscator
|
|
36
|
-
|
|
37
|
-
this._events = {}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Initiate a harvest from multiple sources. An event that corresponds to the endpoint
|
|
42
|
-
* name is emitted, which gives any listeners the opportunity to provide payload data.
|
|
43
|
-
* Note: Used by page_action
|
|
44
|
-
* @param {NetworkSendSpec} spec Specification for sending data
|
|
45
|
-
*/
|
|
46
|
-
sendX (spec = {}) {
|
|
47
|
-
const submitMethod = submitData.getSubmitMethod({ isFinalHarvest: spec.opts?.unload })
|
|
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({ ...spec, payload, submitMethod })
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Initiate a harvest call.
|
|
59
|
-
* @param {NetworkSendSpec} spec Specification for sending data
|
|
60
|
-
*/
|
|
61
|
-
send (spec = {}) {
|
|
62
|
-
const caller = this._send.bind(this)
|
|
63
|
-
|
|
64
|
-
return caller(spec)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Initiate a harvest call. Typically used by `sendX` and `send` methods or called directly
|
|
69
|
-
* for raw network calls.
|
|
70
|
-
* @param {NetworkSendSpec} param0 Specification for sending data
|
|
71
|
-
* @returns {boolean} True if the network call succeeded. For final harvest calls, the return
|
|
72
|
-
* value should not be relied upon because network calls will be made asynchronously.
|
|
73
|
-
*/
|
|
74
|
-
_send ({ endpoint, payload = {}, opts = {}, submitMethod, cbFinished, customUrl, raw, includeBaseParams = true }) {
|
|
75
|
-
const info = getInfo(this.sharedContext.agentIdentifier)
|
|
76
|
-
if (!info.errorBeacon) return false
|
|
77
|
-
|
|
78
|
-
const agentRuntime = getRuntime(this.sharedContext.agentIdentifier)
|
|
79
|
-
let { body, qs } = this.cleanPayload(payload)
|
|
80
|
-
|
|
81
|
-
if (Object.keys(body).length === 0 && !opts?.sendEmptyBody) { // no payload body? nothing to send, just run onfinish stuff and return
|
|
82
|
-
if (cbFinished) {
|
|
83
|
-
cbFinished({ sent: false })
|
|
84
|
-
}
|
|
85
|
-
return false
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const init = getConfiguration(this.sharedContext.agentIdentifier)
|
|
89
|
-
const protocol = init.ssl === false ? 'http' : 'https'
|
|
90
|
-
const perceviedBeacon = init.proxy.beacon || info.errorBeacon
|
|
91
|
-
const endpointURLPart = endpoint !== 'rum' ? `/${endpoint}` : ''
|
|
92
|
-
let url = `${protocol}://${perceviedBeacon}${endpointURLPart}/1/${info.licenseKey}`
|
|
93
|
-
if (customUrl) url = customUrl
|
|
94
|
-
if (raw) url = `${protocol}://${perceviedBeacon}/${endpoint}`
|
|
95
|
-
|
|
96
|
-
const baseParams = !raw && includeBaseParams ? this.baseQueryString(qs, endpoint) : ''
|
|
97
|
-
let payloadParams = encodeObj(qs, agentRuntime.maxBytes)
|
|
98
|
-
if (!submitMethod) {
|
|
99
|
-
submitMethod = submitData.getSubmitMethod({ isFinalHarvest: opts.unload })
|
|
100
|
-
}
|
|
101
|
-
if (baseParams === '' && payloadParams.startsWith('&')) {
|
|
102
|
-
payloadParams = payloadParams.substring(1)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const fullUrl = `${url}?${baseParams}${payloadParams}`
|
|
106
|
-
const gzip = !!qs?.attributes?.includes('gzip')
|
|
107
|
-
|
|
108
|
-
if (!gzip) {
|
|
109
|
-
if (endpoint !== 'events') body = stringify(body) // all features going to /events/ endpoint should already be serialized & stringified
|
|
110
|
-
/** Warn --once per endpoint-- if the agent tries to send large payloads */
|
|
111
|
-
if (body.length > 750000 && (warnings[endpoint] = (warnings?.[endpoint] || 0) + 1) === 1) warn(28, endpoint)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (!body || body.length === 0 || body === '{}' || body === '[]') {
|
|
115
|
-
// If body is null, undefined, or an empty object or array, send an empty string instead
|
|
116
|
-
body = ''
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const headers = []
|
|
120
|
-
|
|
121
|
-
headers.push({ key: 'content-type', value: 'text/plain' })
|
|
122
|
-
|
|
123
|
-
/* Since workers don't support sendBeacon right now, they can only use XHR method.
|
|
124
|
-
Because they still do permit synch XHR, the idea is that at final harvest time (worker is closing),
|
|
125
|
-
we just make a BLOCKING request--trivial impact--with the remaining data as a temp fill-in for sendBeacon.
|
|
126
|
-
Following the removal of img-element method. */
|
|
127
|
-
let result = submitMethod({ url: fullUrl, body, sync: opts.unload && (isWorkerScope), headers })
|
|
128
|
-
|
|
129
|
-
if (!opts.unload && cbFinished && submitMethod === submitData.xhr) {
|
|
130
|
-
const harvestScope = this
|
|
131
|
-
result.addEventListener('loadend', function () {
|
|
132
|
-
// `this` refers to the XHR object in this scope, do not change this to a fat arrow
|
|
133
|
-
// status 0 refers to a local error, such as CORS or network failure, or a blocked request by the browser (e.g. adblocker)
|
|
134
|
-
const cbResult = { sent: this.status !== 0, status: this.status, xhr: this, fullUrl }
|
|
135
|
-
if (this.status === 429) {
|
|
136
|
-
cbResult.retry = true
|
|
137
|
-
cbResult.delay = harvestScope.tooManyRequestsDelay
|
|
138
|
-
} else if (this.status === 408 || this.status === 500 || this.status === 503) {
|
|
139
|
-
cbResult.retry = true
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (opts.needResponse) {
|
|
143
|
-
cbResult.responseText = this.responseText
|
|
144
|
-
}
|
|
145
|
-
cbFinished(cbResult)
|
|
146
|
-
}, eventListenerOpts(false))
|
|
147
|
-
} else if (!opts.unload && cbFinished && submitMethod === submitData.xhrFetch) {
|
|
148
|
-
const harvestScope = this
|
|
149
|
-
result.then(async function (response) {
|
|
150
|
-
const status = response.status
|
|
151
|
-
const cbResult = { sent: true, status, fullUrl, fetchResponse: response }
|
|
152
|
-
|
|
153
|
-
if (response.status === 429) {
|
|
154
|
-
cbResult.retry = true
|
|
155
|
-
cbResult.delay = harvestScope.tooManyRequestsDelay
|
|
156
|
-
} else if (status === 408 || status === 500 || status === 503) {
|
|
157
|
-
cbResult.retry = true
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (opts.needResponse) {
|
|
161
|
-
cbResult.responseText = await response.text()
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
cbFinished(cbResult)
|
|
165
|
-
})
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return result
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// The stuff that gets sent every time.
|
|
172
|
-
baseQueryString (qs, endpoint) {
|
|
173
|
-
const runtime = getRuntime(this.sharedContext.agentIdentifier)
|
|
174
|
-
const info = getInfo(this.sharedContext.agentIdentifier)
|
|
175
|
-
|
|
176
|
-
const ref = this.obfuscator.obfuscateString(cleanURL(getLocation()))
|
|
177
|
-
const hr = runtime?.session?.state.sessionReplayMode === 1 && endpoint !== 'jserrors'
|
|
178
|
-
|
|
179
|
-
const qps = [
|
|
180
|
-
'a=' + info.applicationID,
|
|
181
|
-
encodeParam('sa', (info.sa ? '' + info.sa : '')),
|
|
182
|
-
encodeParam('v', VERSION),
|
|
183
|
-
transactionNameParam(info),
|
|
184
|
-
encodeParam('ct', runtime.customTransaction),
|
|
185
|
-
'&rst=' + now(),
|
|
186
|
-
'&ck=0', // ck param DEPRECATED - still expected by backend
|
|
187
|
-
'&s=' + (runtime.session?.state.value || '0'), // the 0 id encaps all untrackable and default traffic
|
|
188
|
-
encodeParam('ref', ref),
|
|
189
|
-
encodeParam('ptid', (runtime.ptid ? '' + runtime.ptid : ''))
|
|
190
|
-
]
|
|
191
|
-
if (hr) qps.push(encodeParam('hr', '1', qs))
|
|
192
|
-
return qps.join('')
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Calls and accumulates data from registered harvesting functions based on
|
|
197
|
-
* the endpoint being harvested.
|
|
198
|
-
* @param {HarvestEndpointIdentifier} endpoint BAM endpoint identifier.
|
|
199
|
-
* @param {FeatureHarvestCallbackOptions} options Options to be passed to the
|
|
200
|
-
* feature harvest listener callback.
|
|
201
|
-
* @returns {HarvestPayload} Payload object to transmit to the bam endpoint.
|
|
202
|
-
*/
|
|
203
|
-
createPayload (endpoint, options) {
|
|
204
|
-
const listeners = this._events[endpoint]
|
|
205
|
-
const payload = {
|
|
206
|
-
body: {},
|
|
207
|
-
qs: {}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (Array.isArray(listeners) && listeners.length > 0) {
|
|
211
|
-
for (let i = 0; i < listeners.length; i++) {
|
|
212
|
-
const singlePayload = listeners[i](options)
|
|
213
|
-
|
|
214
|
-
if (singlePayload) {
|
|
215
|
-
payload.body = {
|
|
216
|
-
...payload.body,
|
|
217
|
-
...(singlePayload.body || {})
|
|
218
|
-
}
|
|
219
|
-
payload.qs = {
|
|
220
|
-
...payload.qs,
|
|
221
|
-
...(singlePayload.qs || {})
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return payload
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Cleans and returns a payload object containing a body and qs
|
|
232
|
-
* object with key/value pairs. KV pairs where the value is null,
|
|
233
|
-
* undefined, or an empty string are removed to save on transmission
|
|
234
|
-
* size.
|
|
235
|
-
* @param {HarvestPayload} payload Payload to be sent to the endpoint.
|
|
236
|
-
* @returns {HarvestPayload} Cleaned payload payload to be sent to the endpoint.
|
|
237
|
-
*/
|
|
238
|
-
cleanPayload (payload = {}) {
|
|
239
|
-
const clean = (input) => {
|
|
240
|
-
if ((typeof Uint8Array !== 'undefined' && input instanceof Uint8Array) || Array.isArray(input)) return input
|
|
241
|
-
if (typeof input === 'string') return input.length > 0 ? input : null
|
|
242
|
-
return Object.entries(input || {})
|
|
243
|
-
.reduce((accumulator, [key, value]) => {
|
|
244
|
-
if ((typeof value === 'number') ||
|
|
245
|
-
(typeof value === 'string' && value.length > 0) ||
|
|
246
|
-
(typeof value === 'object' && Object.keys(value || {}).length > 0)
|
|
247
|
-
) {
|
|
248
|
-
accumulator[key] = value
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return accumulator
|
|
252
|
-
}, {})
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return {
|
|
256
|
-
body: clean(payload.body),
|
|
257
|
-
qs: clean(payload.qs)
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Registers a function to be called when harvesting is triggered for a specific
|
|
263
|
-
* endpoint.
|
|
264
|
-
* @param {HarvestEndpointIdentifier} endpoint
|
|
265
|
-
* @param {FeatureHarvestCallback} listener
|
|
266
|
-
*/
|
|
267
|
-
on (endpoint, listener) {
|
|
268
|
-
if (!Array.isArray(this._events[endpoint])) {
|
|
269
|
-
this._events[endpoint] = []
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
this._events[endpoint].push(listener)
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// Constructs the transaction name param for the beacon URL.
|
|
277
|
-
// Prefers the obfuscated transaction name over the plain text.
|
|
278
|
-
// Falls back to making up a name.
|
|
279
|
-
function transactionNameParam (info) {
|
|
280
|
-
if (info.transactionName) return encodeParam('to', info.transactionName)
|
|
281
|
-
return encodeParam('t', info.tNamePlain || 'Unnamed Transaction')
|
|
282
|
-
}
|