@newrelic/browser-agent 1.238.0 → 1.239.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/common/config/state/init.js +21 -13
- package/dist/cjs/common/config/state/runtime.js +0 -4
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/constants/runtime.js +3 -3
- package/dist/cjs/common/constants/shared-channel.js +3 -1
- package/dist/cjs/common/deny-list/deny-list.js +2 -8
- package/dist/cjs/common/drain/drain.js +1 -1
- package/dist/cjs/common/event-emitter/contextual-ee.js +6 -6
- package/dist/cjs/common/harvest/harvest-scheduler.js +2 -4
- package/dist/cjs/common/harvest/harvest.js +2 -6
- package/dist/cjs/common/serialize/bel-serializer.js +1 -1
- package/dist/cjs/common/session/session-entity.js +16 -12
- package/dist/cjs/common/storage/first-party-cookies.js +5 -4
- package/dist/cjs/common/storage/local-storage.js +3 -2
- package/dist/cjs/common/timer/interaction-timer.js +14 -6
- package/dist/cjs/common/timing/nav-timing.js +1 -1
- package/dist/cjs/common/unload/eol.js +4 -30
- package/dist/cjs/common/util/feature-flags.js +14 -15
- package/dist/cjs/common/util/invoke.js +3 -1
- package/dist/cjs/common/util/obfuscate.js +3 -5
- package/dist/cjs/common/util/traverse.js +1 -0
- package/dist/cjs/common/window/page-visibility.js +1 -2
- package/dist/cjs/common/wrap/wrap-jsonp.js +1 -1
- package/dist/cjs/features/ajax/aggregate/index.js +5 -7
- package/dist/cjs/features/ajax/instrument/distributed-tracing.js +8 -8
- package/dist/cjs/features/ajax/instrument/index.js +47 -15
- package/dist/cjs/features/jserrors/aggregate/canonical-function-name.js +0 -1
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +4 -4
- package/dist/cjs/features/jserrors/aggregate/index.js +4 -5
- package/dist/cjs/features/metrics/aggregate/framework-detection.js +103 -7
- package/dist/cjs/features/metrics/aggregate/index.js +20 -37
- package/dist/cjs/features/metrics/instrument/index.js +0 -2
- package/dist/cjs/features/page_action/aggregate/index.js +17 -19
- package/dist/cjs/features/page_view_event/aggregate/index.js +1 -2
- package/dist/cjs/features/page_view_event/instrument/index.js +4 -2
- package/dist/cjs/features/page_view_timing/aggregate/index.js +6 -7
- package/dist/cjs/features/session_replay/aggregate/index.js +3 -3
- package/dist/cjs/features/session_trace/aggregate/index.js +8 -8
- package/dist/cjs/features/spa/aggregate/index.js +14 -20
- package/dist/cjs/features/spa/aggregate/interaction.js +0 -2
- package/dist/cjs/features/spa/aggregate/serializer.js +1 -1
- package/dist/cjs/features/utils/aggregate-base.js +4 -0
- package/dist/cjs/features/utils/handler-cache.js +3 -1
- package/dist/cjs/features/utils/instrument-base.js +24 -6
- package/dist/cjs/loaders/agent-base.js +11 -0
- package/dist/cjs/loaders/agent.js +7 -7
- package/dist/cjs/loaders/api/api.js +21 -4
- package/dist/cjs/loaders/api/apiAsync.js +19 -20
- package/dist/cjs/loaders/configure/configure.js +3 -0
- package/dist/cjs/loaders/micro-agent.js +20 -3
- package/dist/esm/common/config/state/init.js +21 -13
- package/dist/esm/common/config/state/runtime.js +0 -4
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/constants/runtime.js +1 -1
- package/dist/esm/common/constants/shared-channel.js +3 -1
- package/dist/esm/common/deny-list/deny-list.js +2 -8
- package/dist/esm/common/drain/drain.js +1 -1
- package/dist/esm/common/event-emitter/contextual-ee.js +6 -6
- package/dist/esm/common/harvest/harvest-scheduler.js +2 -4
- package/dist/esm/common/harvest/harvest.js +2 -6
- package/dist/esm/common/serialize/bel-serializer.js +1 -1
- package/dist/esm/common/session/session-entity.js +16 -12
- package/dist/esm/common/storage/first-party-cookies.js +5 -4
- package/dist/esm/common/storage/local-storage.js +3 -2
- package/dist/esm/common/timer/interaction-timer.js +14 -6
- package/dist/esm/common/timing/nav-timing.js +1 -1
- package/dist/esm/common/unload/eol.js +5 -31
- package/dist/esm/common/util/feature-flags.js +14 -15
- package/dist/esm/common/util/invoke.js +3 -1
- package/dist/esm/common/util/obfuscate.js +3 -5
- package/dist/esm/common/util/traverse.js +1 -0
- package/dist/esm/common/window/page-visibility.js +1 -2
- package/dist/esm/common/wrap/wrap-jsonp.js +1 -1
- package/dist/esm/features/ajax/aggregate/index.js +5 -7
- package/dist/esm/features/ajax/instrument/distributed-tracing.js +8 -8
- package/dist/esm/features/ajax/instrument/index.js +47 -15
- package/dist/esm/features/jserrors/aggregate/canonical-function-name.js +0 -1
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +4 -4
- package/dist/esm/features/jserrors/aggregate/index.js +4 -5
- package/dist/esm/features/metrics/aggregate/framework-detection.js +103 -7
- package/dist/esm/features/metrics/aggregate/index.js +22 -39
- package/dist/esm/features/metrics/instrument/index.js +1 -3
- package/dist/esm/features/page_action/aggregate/index.js +17 -19
- package/dist/esm/features/page_view_event/aggregate/index.js +1 -2
- package/dist/esm/features/page_view_event/instrument/index.js +4 -2
- package/dist/esm/features/page_view_timing/aggregate/index.js +7 -8
- package/dist/esm/features/session_replay/aggregate/index.js +2 -2
- package/dist/esm/features/session_trace/aggregate/index.js +8 -8
- package/dist/esm/features/spa/aggregate/index.js +14 -20
- package/dist/esm/features/spa/aggregate/interaction.js +0 -2
- package/dist/esm/features/spa/aggregate/serializer.js +1 -1
- package/dist/esm/features/utils/aggregate-base.js +4 -0
- package/dist/esm/features/utils/handler-cache.js +3 -1
- package/dist/esm/features/utils/instrument-base.js +24 -6
- package/dist/esm/loaders/agent-base.js +11 -0
- package/dist/esm/loaders/agent.js +7 -7
- package/dist/esm/loaders/api/api.js +21 -4
- package/dist/esm/loaders/api/apiAsync.js +19 -20
- package/dist/esm/loaders/configure/configure.js +3 -0
- package/dist/esm/loaders/features/enabled-features.js +1 -1
- package/dist/esm/loaders/micro-agent.js +21 -4
- package/dist/types/common/config/state/init.d.ts.map +1 -1
- package/dist/types/common/config/state/runtime.d.ts.map +1 -1
- package/dist/types/common/constants/runtime.d.ts +1 -1
- package/dist/types/common/constants/runtime.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts +6 -9
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/storage/first-party-cookies.d.ts +1 -1
- package/dist/types/common/storage/first-party-cookies.d.ts.map +1 -1
- package/dist/types/common/storage/local-storage.d.ts.map +1 -1
- package/dist/types/common/timer/interaction-timer.d.ts +3 -0
- package/dist/types/common/timer/interaction-timer.d.ts.map +1 -1
- package/dist/types/common/unload/eol.d.ts +1 -2
- package/dist/types/common/unload/eol.d.ts.map +1 -1
- package/dist/types/common/util/feature-flags.d.ts.map +1 -1
- package/dist/types/common/util/obfuscate.d.ts.map +1 -1
- package/dist/types/common/util/traverse.d.ts.map +1 -1
- package/dist/types/common/window/page-visibility.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/canonical-function-name.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/framework-detection.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_action/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_action/aggregate/index.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/interaction.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +1 -0
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/handler-cache.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/agent-base.d.ts +6 -0
- package/dist/types/loaders/agent-base.d.ts.map +1 -1
- package/dist/types/loaders/agent.d.ts +1 -1
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts +1 -0
- package/dist/types/loaders/api/api.d.ts.map +1 -1
- package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts +1 -0
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent.d.ts +7 -1
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +41 -12
- package/src/common/aggregate/aggregator.test.js +107 -0
- package/src/common/config/state/configurable.test.js +73 -0
- package/src/common/config/state/info.test.js +31 -0
- package/src/common/config/state/init.js +13 -12
- package/src/common/config/state/init.test.js +28 -0
- package/src/common/config/state/loader-config.test.js +21 -0
- package/src/common/config/state/runtime.js +0 -2
- package/src/common/config/state/runtime.test.js +21 -0
- package/src/common/constants/__mocks__/runtime.js +1 -1
- package/src/common/constants/runtime.js +1 -1
- package/src/common/constants/runtime.test.js +2 -2
- package/src/common/constants/shared-channel.js +1 -1
- package/src/common/deny-list/deny-list.js +2 -10
- package/src/common/drain/drain.js +1 -1
- package/src/common/drain/drain.test.js +74 -0
- package/src/common/event-emitter/contextual-ee.js +6 -6
- package/src/common/harvest/harvest-scheduler.js +2 -5
- package/src/common/harvest/harvest-scheduler.test.js +2 -6
- package/src/common/harvest/harvest.js +2 -6
- package/src/common/harvest/harvest.test.js +0 -2
- package/src/common/ids/id.test.js +6 -6
- package/src/common/serialize/bel-serializer.js +1 -1
- package/src/common/session/session-entity.component-test.js +3 -2
- package/src/common/session/session-entity.js +11 -9
- package/src/common/storage/first-party-cookies.js +5 -4
- package/src/common/storage/local-storage.js +3 -2
- package/src/common/timer/interaction-timer.component-test.js +52 -7
- package/src/common/timer/interaction-timer.js +15 -6
- package/src/common/timer/timer.test.js +0 -1
- package/src/common/timing/nav-timing.js +1 -1
- package/src/common/unload/eol.js +5 -31
- package/src/common/url/encode.test.js +1 -0
- package/src/common/util/__mocks__/invoke.js +1 -0
- package/src/common/util/data-size.test.js +0 -1
- package/src/common/util/feature-flags.js +15 -17
- package/src/common/util/feature-flags.test.js +4 -8
- package/src/common/util/invoke.js +1 -1
- package/src/common/util/obfuscate.js +3 -5
- package/src/common/util/submit-data.test.js +1 -1
- package/src/common/util/traverse.js +1 -0
- package/src/common/window/__mocks__/nreum.js +3 -1
- package/src/common/window/page-visibility.js +1 -2
- package/src/common/wrap/wrap-jsonp.js +1 -1
- package/src/features/ajax/aggregate/index.js +5 -7
- package/src/features/ajax/instrument/distributed-tracing.js +8 -8
- package/src/features/ajax/instrument/index.js +40 -17
- package/src/features/jserrors/aggregate/canonical-function-name.js +0 -2
- package/src/features/jserrors/aggregate/compute-stack-trace.js +4 -4
- package/src/features/jserrors/aggregate/compute-stack-trace.test.js +1 -1
- package/src/features/jserrors/aggregate/index.js +4 -5
- package/src/features/metrics/aggregate/framework-detection.js +129 -8
- package/src/features/metrics/aggregate/framework-detection.test.js +213 -82
- package/src/features/metrics/aggregate/index.js +22 -45
- package/src/features/metrics/instrument/index.js +1 -3
- package/src/features/page_action/aggregate/index.js +12 -13
- package/src/features/page_view_event/aggregate/index.js +1 -2
- package/src/features/page_view_event/instrument/index.js +2 -2
- package/src/features/page_view_timing/aggregate/index.js +7 -8
- package/src/features/session_replay/aggregate/index.component-test.js +3 -15
- package/src/features/session_replay/aggregate/index.js +2 -2
- package/src/features/session_trace/aggregate/index.js +6 -9
- package/src/features/spa/aggregate/index.js +14 -20
- package/src/features/spa/aggregate/interaction.js +0 -2
- package/src/features/spa/aggregate/serializer.js +1 -1
- package/src/features/utils/aggregate-base.js +5 -0
- package/src/features/utils/aggregate-base.test.js +2 -1
- package/src/features/utils/handler-cache.js +3 -2
- package/src/features/utils/instrument-base.js +25 -6
- package/src/features/utils/instrument-base.test.js +2 -2
- package/src/loaders/agent-base.js +11 -0
- package/src/loaders/agent.js +7 -7
- package/src/loaders/api/api.js +21 -4
- package/src/loaders/api/api.test.js +85 -0
- package/src/loaders/api/apiAsync.js +19 -20
- package/src/loaders/api/apiAsync.test.js +17 -0
- package/src/loaders/configure/configure.js +3 -0
- package/src/loaders/features/enabled-features.js +1 -1
- package/src/loaders/micro-agent.js +22 -4
- package/dist/cjs/features/metrics/aggregate/endpoint-map.js +0 -14
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.js +0 -14
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.js +0 -53
- package/dist/esm/features/metrics/aggregate/endpoint-map.js +0 -7
- package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.js +0 -8
- package/dist/esm/features/metrics/aggregate/polyfill-detection.js +0 -47
- package/dist/types/features/metrics/aggregate/endpoint-map.d.ts +0 -8
- package/dist/types/features/metrics/aggregate/endpoint-map.d.ts.map +0 -1
- package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts +0 -6
- package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts.map +0 -1
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts +0 -7
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts.map +0 -1
- package/src/features/metrics/aggregate/endpoint-map.js +0 -7
- package/src/features/metrics/aggregate/polyfill-detection.es5.js +0 -8
- package/src/features/metrics/aggregate/polyfill-detection.es5.test.js +0 -16
- package/src/features/metrics/aggregate/polyfill-detection.js +0 -48
- package/src/features/metrics/aggregate/polyfill-detection.test.js +0 -163
|
@@ -41,29 +41,25 @@ describe('constructor', () => {
|
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
test('refresh type timers set event listeners', () => {
|
|
44
|
-
// eslint-disable-next-line
|
|
45
44
|
let ee = { on: jest.fn().mockImplementation((evt, cb) => { cb([{ type: 'click' }]) }) }
|
|
46
45
|
let it = new InteractionTimer({ onEnd: jest.fn(), onRefresh: jest.fn(), ee }, 100)
|
|
47
46
|
// scroll, keypress, click
|
|
48
47
|
expect(ee.on).toHaveBeenCalledTimes(1)
|
|
49
48
|
expect(it.onRefresh).toHaveBeenCalledTimes(1)
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
ee = { on: jest.fn().mockImplementation((evt, cb) => { cb([{ type: 'scroll' }]) }) }
|
|
50
|
+
ee = { on: jest.fn().mockImplementation((evt, cb) => { cb([{ type: 'scroll' }]) }) }
|
|
53
51
|
it = new InteractionTimer({ onEnd: jest.fn(), onRefresh: jest.fn(), ee }, 100)
|
|
54
52
|
// scroll, keypress, click
|
|
55
53
|
expect(ee.on).toHaveBeenCalledTimes(1)
|
|
56
54
|
expect(it.onRefresh).toHaveBeenCalledTimes(1)
|
|
57
55
|
|
|
58
|
-
|
|
59
|
-
ee = { on: jest.fn().mockImplementation((evt, cb) => { cb([{ type: 'keydown' }]) }) }
|
|
56
|
+
ee = { on: jest.fn().mockImplementation((evt, cb) => { cb([{ type: 'keydown' }]) }) }
|
|
60
57
|
it = new InteractionTimer({ onEnd: jest.fn(), onRefresh: jest.fn(), ee }, 100)
|
|
61
58
|
// scroll, keypress, click
|
|
62
59
|
expect(ee.on).toHaveBeenCalledTimes(1)
|
|
63
60
|
expect(it.onRefresh).toHaveBeenCalledTimes(1)
|
|
64
61
|
|
|
65
62
|
const aelSpy = jest.spyOn(document, 'addEventListener')
|
|
66
|
-
// eslint-disable-next-line
|
|
67
63
|
ee = { on: jest.fn().mockImplementation((evt, cb) => { cb([{ type: 'keydown' }]) }) }
|
|
68
64
|
it = new InteractionTimer({ onEnd: jest.fn(), onRefresh: jest.fn(), ee }, 100)
|
|
69
65
|
// visibility change
|
|
@@ -81,7 +77,6 @@ describe('create()', () => {
|
|
|
81
77
|
})
|
|
82
78
|
|
|
83
79
|
test('Create can fallback to use defaults', () => {
|
|
84
|
-
let called = 0
|
|
85
80
|
const timer1 = new InteractionTimer({ onEnd: jest.fn() }, 100)
|
|
86
81
|
timer1.create()
|
|
87
82
|
|
|
@@ -136,6 +131,26 @@ describe('pause()', () => {
|
|
|
136
131
|
})
|
|
137
132
|
})
|
|
138
133
|
|
|
134
|
+
describe('resume()', () => {
|
|
135
|
+
test('resume allows the callback continue firing', () => {
|
|
136
|
+
const timer = new InteractionTimer({ onEnd: jest.fn() }, 100)
|
|
137
|
+
expect(timer.onEnd).toHaveBeenCalledTimes(0)
|
|
138
|
+
timer.pause()
|
|
139
|
+
jest.advanceTimersByTime(150)
|
|
140
|
+
expect(timer.onEnd).toHaveBeenCalledTimes(0)
|
|
141
|
+
timer.resume()
|
|
142
|
+
jest.advanceTimersByTime(150)
|
|
143
|
+
expect(timer.onEnd).toHaveBeenCalledTimes(1)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
test('resume fires the refresh callback', () => {
|
|
147
|
+
const timer = new InteractionTimer({ onEnd: jest.fn(), onRefresh: jest.fn() }, 100)
|
|
148
|
+
timer.pause()
|
|
149
|
+
timer.resume()
|
|
150
|
+
expect(timer.onRefresh).toHaveBeenCalledTimes(1)
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
|
|
139
154
|
describe('clear()', () => {
|
|
140
155
|
test('clear prevents the callback from firing and deletes the pointer', () => {
|
|
141
156
|
const timer = new InteractionTimer({ onEnd: jest.fn() }, 100)
|
|
@@ -165,3 +180,33 @@ describe('isValid', () => {
|
|
|
165
180
|
expect(timer.isValid()).toEqual(false)
|
|
166
181
|
})
|
|
167
182
|
})
|
|
183
|
+
|
|
184
|
+
describe('abort()', () => {
|
|
185
|
+
test('should unregister the event emitter listener', () => {
|
|
186
|
+
const ee = { on: jest.fn(), removeEventListener: jest.fn() }
|
|
187
|
+
const it = new InteractionTimer({ onEnd: jest.fn(), onRefresh: jest.fn(), ee }, 100)
|
|
188
|
+
|
|
189
|
+
it.abort()
|
|
190
|
+
|
|
191
|
+
expect(ee.on).toHaveBeenCalledTimes(1)
|
|
192
|
+
expect(ee.on).toHaveBeenCalledWith('fn-end', expect.any(Function))
|
|
193
|
+
|
|
194
|
+
expect(ee.removeEventListener).toHaveBeenCalledTimes(1)
|
|
195
|
+
expect(ee.removeEventListener).toHaveBeenCalledWith('fn-end', expect.any(Function))
|
|
196
|
+
|
|
197
|
+
// Verify the same function is passed to both methods
|
|
198
|
+
expect(jest.mocked(ee.on).mock.calls[0][1]).toEqual(jest.mocked(ee.removeEventListener).mock.calls[0][1])
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
test('should not attempt to unregister the event emitter listener when an event emitter was not supplied', () => {
|
|
202
|
+
const it = new InteractionTimer({ onEnd: jest.fn(), onRefresh: jest.fn() }, 100)
|
|
203
|
+
|
|
204
|
+
expect(it.ee).toBeUndefined()
|
|
205
|
+
expect(it.refreshHandler).toBeUndefined()
|
|
206
|
+
|
|
207
|
+
it.abort()
|
|
208
|
+
|
|
209
|
+
expect(it.ee).toBeUndefined()
|
|
210
|
+
expect(it.refreshHandler).toBeUndefined()
|
|
211
|
+
})
|
|
212
|
+
})
|
|
@@ -24,12 +24,14 @@ export class InteractionTimer extends Timer {
|
|
|
24
24
|
|
|
25
25
|
if (isBrowserScope && opts.ee) {
|
|
26
26
|
if (opts.ee) {
|
|
27
|
+
this.ee = opts.ee
|
|
27
28
|
const debouncedRefresh = debounce(this.refresh.bind(this), 500, { leading: true })
|
|
28
|
-
|
|
29
|
+
this.refreshHandler = (evts) => {
|
|
29
30
|
if (opts.refreshEvents.includes(evts?.[0]?.type)) {
|
|
30
31
|
debouncedRefresh()
|
|
31
32
|
}
|
|
32
|
-
}
|
|
33
|
+
}
|
|
34
|
+
opts.ee.on('fn-end', this.refreshHandler)
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
// watch for the vis state changing. If the page is hidden, the local inactivity timer should be paused
|
|
@@ -43,10 +45,7 @@ export class InteractionTimer extends Timer {
|
|
|
43
45
|
subscribeToVisibilityChange((state) => {
|
|
44
46
|
if (state === 'hidden') this.pause()
|
|
45
47
|
// vis change --> visible is treated like a new interaction with the page
|
|
46
|
-
else
|
|
47
|
-
this.refresh()
|
|
48
|
-
this.onResume() // emit resume event after state updated
|
|
49
|
-
}
|
|
48
|
+
else this.resume()
|
|
50
49
|
}, false, false, this.abortController?.signal)
|
|
51
50
|
}
|
|
52
51
|
}
|
|
@@ -54,6 +53,11 @@ export class InteractionTimer extends Timer {
|
|
|
54
53
|
abort () {
|
|
55
54
|
this.clear()
|
|
56
55
|
this.abortController?.abort()
|
|
56
|
+
|
|
57
|
+
if (this.refreshHandler) {
|
|
58
|
+
this.ee.removeEventListener('fn-end', this.refreshHandler)
|
|
59
|
+
this.refreshHandler = this.ee = null
|
|
60
|
+
}
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
pause () {
|
|
@@ -62,6 +66,11 @@ export class InteractionTimer extends Timer {
|
|
|
62
66
|
this.remainingMs = this.initialMs - (Date.now() - this.startTimestamp)
|
|
63
67
|
}
|
|
64
68
|
|
|
69
|
+
resume () {
|
|
70
|
+
this.refresh()
|
|
71
|
+
this.onResume() // emit resume event after state updated
|
|
72
|
+
}
|
|
73
|
+
|
|
65
74
|
refresh (cb, ms) {
|
|
66
75
|
this.clear()
|
|
67
76
|
this.timer = this.create(cb, ms)
|
|
@@ -28,7 +28,7 @@ var DOM_CONTENT_LOAD_EVENT = 'domContentLoadedEvent'
|
|
|
28
28
|
export var navTimingValues = []
|
|
29
29
|
|
|
30
30
|
function getPntType (type) {
|
|
31
|
-
if (typeof type
|
|
31
|
+
if (typeof type === 'number') return type
|
|
32
32
|
const types = {
|
|
33
33
|
navigate: undefined,
|
|
34
34
|
reload: 1,
|
package/src/common/unload/eol.js
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { windowAddEventListener } from '../event-listener/event-listener-opts'
|
|
6
|
-
import {
|
|
7
|
-
import { ffVersion, globalScope, isWorkerScope, isBrowserScope } from '../constants/runtime'
|
|
6
|
+
import { globalScope, isWorkerScope, isBrowserScope } from '../constants/runtime'
|
|
8
7
|
import { subscribeToVisibilityChange } from '../window/page-visibility'
|
|
9
8
|
|
|
10
9
|
if (isWorkerScope) {
|
|
@@ -23,37 +22,12 @@ if (isWorkerScope) {
|
|
|
23
22
|
* Subscribes a provided callback to the time/event when the agent should treat it as end-of-life.
|
|
24
23
|
* This is used, for example, to submit a final harvest and send all remaining data on best-effort.
|
|
25
24
|
* @param {function} cb - func to run before or during the last reliable event or time of an env's life span
|
|
26
|
-
* @param {boolean} allowBFCache - (temp) feature flag to gate new v1222 BFC support
|
|
27
25
|
*/
|
|
28
|
-
export function subscribeToEOL (cb
|
|
26
|
+
export function subscribeToEOL (cb) {
|
|
29
27
|
if (isBrowserScope) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// --this ought to be removed once support for version below 14.5 phases out
|
|
34
|
-
} else {
|
|
35
|
-
var oneCall = single(cb)
|
|
36
|
-
|
|
37
|
-
// Firefox has a bug wherein a slow-loading resource loaded from the 'pagehide'
|
|
38
|
-
// or 'unload' event will delay the 'load' event firing on the next page load.
|
|
39
|
-
// In Firefox versions that support sendBeacon, this doesn't matter, because
|
|
40
|
-
// we'll use it instead of an image load for our final harvest.
|
|
41
|
-
//
|
|
42
|
-
// Some Safari versions never fire the 'unload' event for pages that are being
|
|
43
|
-
// put into the WebKit page cache, so we *need* to use the pagehide event for
|
|
44
|
-
// the final submission from Safari.
|
|
45
|
-
//
|
|
46
|
-
// Generally speaking, we will try to submit our final harvest from either
|
|
47
|
-
// pagehide or unload, whichever comes first, but in Firefox, we need to avoid
|
|
48
|
-
// attempting to submit from pagehide to ensure that we don't slow down loading
|
|
49
|
-
// of the next page.
|
|
50
|
-
if (!ffVersion || navigator.sendBeacon) {
|
|
51
|
-
windowAddEventListener('pagehide', oneCall)
|
|
52
|
-
} else {
|
|
53
|
-
windowAddEventListener('beforeunload', oneCall)
|
|
54
|
-
}
|
|
55
|
-
windowAddEventListener('unload', oneCall)
|
|
56
|
-
}
|
|
28
|
+
subscribeToVisibilityChange(cb, true) // when user switches tab or hides window, esp. mobile scenario
|
|
29
|
+
windowAddEventListener('pagehide', cb) // when user navigates away, and because safari iOS v14.4- doesn't fully support vis change
|
|
30
|
+
// --this ought to be removed once support for version below 14.5 phases out
|
|
57
31
|
} else if (isWorkerScope) {
|
|
58
32
|
globalScope.cleanupTasks.push(cb) // close() should run these tasks before quitting thread
|
|
59
33
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const single = jest.fn(cb => cb)
|
|
@@ -47,7 +47,6 @@ describe('dataSize', () => {
|
|
|
47
47
|
const input = {
|
|
48
48
|
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
49
49
|
}
|
|
50
|
-
const expectedSize = faker.datatype.number({ min: 1000, max: 10000 })
|
|
51
50
|
|
|
52
51
|
jest.spyOn(stringifyModule, 'stringify').mockImplementation(() => { throw new Error(faker.lorem.sentence()) })
|
|
53
52
|
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { ee } from '../event-emitter/contextual-ee'
|
|
6
6
|
import { handle } from '../event-emitter/handle'
|
|
7
|
-
import { drain } from '../drain/drain'
|
|
8
7
|
import { FEATURE_NAMES } from '../../loaders/features/features'
|
|
9
8
|
|
|
10
9
|
const bucketMap = {
|
|
@@ -15,26 +14,25 @@ const bucketMap = {
|
|
|
15
14
|
sr: [FEATURE_NAMES.sessionReplay, FEATURE_NAMES.sessionTrace]
|
|
16
15
|
}
|
|
17
16
|
|
|
17
|
+
const sentIds = new Set()
|
|
18
|
+
|
|
18
19
|
/** Note that this function only processes each unique flag ONCE, with the first occurrence of each flag and numeric value determining its switch on/off setting. */
|
|
19
20
|
export function activateFeatures (flags, agentIdentifier) {
|
|
20
21
|
const sharedEE = ee.get(agentIdentifier)
|
|
21
22
|
if (!(flags && typeof flags === 'object')) return
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
activatedFeatures[flag] = Boolean(num)
|
|
37
|
-
})
|
|
24
|
+
if (!sentIds.has(agentIdentifier)) {
|
|
25
|
+
Object.entries(flags).forEach(([flag, num]) => {
|
|
26
|
+
if (bucketMap[flag]) {
|
|
27
|
+
bucketMap[flag].forEach(feat => {
|
|
28
|
+
if (!num) handle('block-' + flag, [], undefined, feat, sharedEE)
|
|
29
|
+
else handle('feat-' + flag, [], undefined, feat, sharedEE)
|
|
30
|
+
handle('rumresp-' + flag, [Boolean(num)], undefined, feat, sharedEE) // this is a duplicate of feat-/block- but makes awaiting for 1 event easier than 2
|
|
31
|
+
})
|
|
32
|
+
} else if (num) handle('feat-' + flag, [], undefined, undefined, sharedEE) // not sure what other flags are overlooked, but there's a test for ones not in the map --
|
|
33
|
+
activatedFeatures[flag] = Boolean(num)
|
|
34
|
+
})
|
|
35
|
+
}
|
|
38
36
|
|
|
39
37
|
// Let the features waiting on their respective flags know that RUM response was received and that any missing flags are interpreted as bad entitlement / "off".
|
|
40
38
|
// Hence, those features will not be hanging forever if their flags aren't included in the response.
|
|
@@ -44,7 +42,7 @@ export function activateFeatures (flags, agentIdentifier) {
|
|
|
44
42
|
activatedFeatures[flag] = false
|
|
45
43
|
}
|
|
46
44
|
})
|
|
47
|
-
|
|
45
|
+
sentIds.add(agentIdentifier)
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
export const activatedFeatures = {}
|
|
@@ -48,7 +48,7 @@ const bucketMap = {
|
|
|
48
48
|
|
|
49
49
|
test('emits the right events when feature flag = 1', () => {
|
|
50
50
|
const flags = {}
|
|
51
|
-
Object.keys(bucketMap).forEach(flag => flags[flag] = 1)
|
|
51
|
+
Object.keys(bucketMap).forEach(flag => { flags[flag] = 1 })
|
|
52
52
|
activateFeatures(flags, agentIdentifier)
|
|
53
53
|
|
|
54
54
|
const sharedEE = jest.mocked(eventEmitterModule.ee.get).mock.results[0].value
|
|
@@ -57,15 +57,14 @@ test('emits the right events when feature flag = 1', () => {
|
|
|
57
57
|
expect(handleModule.handle).toHaveBeenCalledTimes(14)
|
|
58
58
|
expect(handleModule.handle).toHaveBeenNthCalledWith(1, 'feat-stn', [], undefined, FEATURE_NAMES.sessionTrace, sharedEE)
|
|
59
59
|
expect(handleModule.handle).toHaveBeenLastCalledWith('rumresp-sr', [true], undefined, FEATURE_NAMES.sessionTrace, sharedEE)
|
|
60
|
-
expect(drainModule.drain).toHaveBeenCalledWith(agentIdentifier, 'page_view_event')
|
|
61
60
|
|
|
62
|
-
Object.keys(flags).forEach(flag => flags[flag] = true)
|
|
61
|
+
Object.keys(flags).forEach(flag => { flags[flag] = true })
|
|
63
62
|
expect(activatedFeatures).toEqual(flags)
|
|
64
63
|
})
|
|
65
64
|
|
|
66
65
|
test('emits the right events when feature flag = 0', () => {
|
|
67
66
|
const flags = {}
|
|
68
|
-
Object.keys(bucketMap).forEach(flag => flags[flag] = 0)
|
|
67
|
+
Object.keys(bucketMap).forEach(flag => { flags[flag] = 0 })
|
|
69
68
|
activateFeatures(flags, agentIdentifier)
|
|
70
69
|
|
|
71
70
|
const sharedEE = jest.mocked(eventEmitterModule.ee.get).mock.results[0].value
|
|
@@ -74,9 +73,8 @@ test('emits the right events when feature flag = 0', () => {
|
|
|
74
73
|
expect(handleModule.handle).toHaveBeenCalledTimes(14)
|
|
75
74
|
expect(handleModule.handle).toHaveBeenNthCalledWith(1, 'block-stn', [], undefined, FEATURE_NAMES.sessionTrace, sharedEE)
|
|
76
75
|
expect(handleModule.handle).toHaveBeenLastCalledWith('rumresp-sr', [false], undefined, FEATURE_NAMES.sessionTrace, sharedEE)
|
|
77
|
-
expect(drainModule.drain).toHaveBeenCalledWith(agentIdentifier, 'page_view_event')
|
|
78
76
|
|
|
79
|
-
Object.keys(flags).forEach(flag => flags[flag] = false)
|
|
77
|
+
Object.keys(flags).forEach(flag => { flags[flag] = false })
|
|
80
78
|
expect(activatedFeatures).toEqual(flags)
|
|
81
79
|
})
|
|
82
80
|
|
|
@@ -92,7 +90,5 @@ test('only the first activate of the same feature is respected', () => {
|
|
|
92
90
|
expect(handleModule.handle).toHaveBeenNthCalledWith(1, 'feat-stn', [], undefined, 'session_trace', sharedEE1)
|
|
93
91
|
expect(handleModule.handle).toHaveBeenNthCalledWith(2, 'rumresp-stn', [true], undefined, 'session_trace', sharedEE1)
|
|
94
92
|
expect(handleModule.handle).not.toHaveBeenNthCalledWith(1, 'feat-stn', [], undefined, 'session_trace', sharedEE2)
|
|
95
|
-
expect(drainModule.drain).toHaveBeenCalledWith(agentIdentifier, 'page_view_event')
|
|
96
|
-
expect(drainModule.drain).toHaveBeenCalledTimes(2)
|
|
97
93
|
expect(activatedFeatures.stn).toBeTruthy()
|
|
98
94
|
})
|
|
@@ -26,7 +26,7 @@ export function debounce (func, timeout = 500, options = {}) {
|
|
|
26
26
|
return (...args) => {
|
|
27
27
|
if (leading && timer === undefined) {
|
|
28
28
|
func.apply(this, args)
|
|
29
|
-
timer = setTimeout(() => timer = clearTimeout(timer), timeout)
|
|
29
|
+
timer = setTimeout(() => { timer = clearTimeout(timer) }, timeout)
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
if (!leading) {
|
|
@@ -57,11 +57,9 @@ export function validateRules (rules) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
var replacement = rules[i].replacement
|
|
60
|
-
if (replacement) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
invalidReplacementDetected = true
|
|
64
|
-
}
|
|
60
|
+
if (replacement && typeof replacement !== 'string') {
|
|
61
|
+
warn('An obfuscation replacement rule contains a "replacement" value with an invalid type (must be a string)')
|
|
62
|
+
invalidReplacementDetected = true
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
65
|
|
|
@@ -66,7 +66,7 @@ describe('xhr', () => {
|
|
|
66
66
|
this._withCredentials = false
|
|
67
67
|
Object.defineProperty(this, 'withCredentials', {
|
|
68
68
|
get: jest.fn(() => this._withCredentials),
|
|
69
|
-
set: jest.fn((val) => this._withCredentials = val)
|
|
69
|
+
set: jest.fn((val) => { this._withCredentials = val })
|
|
70
70
|
})
|
|
71
71
|
})
|
|
72
72
|
})
|
|
@@ -19,6 +19,7 @@ export function applyFnToProps (obj, fn, type = 'string', ignoreKeys = []) {
|
|
|
19
19
|
if (typeof obj[property] === 'object') {
|
|
20
20
|
applyFnToProps(obj[property], fn, type, ignoreKeys)
|
|
21
21
|
} else {
|
|
22
|
+
// eslint-disable-next-line valid-typeof
|
|
22
23
|
if (typeof obj[property] === type && !ignoreKeys.includes(property)) obj[property] = fn(obj[property])
|
|
23
24
|
}
|
|
24
25
|
})
|
|
@@ -7,4 +7,6 @@ export const gosNREUMOriginals = jest.fn(() => ({}))
|
|
|
7
7
|
export const gosNREUMInitializedAgents = jest.fn(() => ({}))
|
|
8
8
|
export const addToNREUM = jest.fn(() => ({}))
|
|
9
9
|
export const NREUMinitialized = jest.fn(() => ({}))
|
|
10
|
-
export const gosCDN = jest.fn(() => (
|
|
10
|
+
export const gosCDN = jest.fn(() => (newrelicGlob))
|
|
11
|
+
|
|
12
|
+
const newrelicGlob = {}
|
|
@@ -12,11 +12,10 @@ import { documentAddEventListener } from '../event-listener/event-listener-opts'
|
|
|
12
12
|
*/
|
|
13
13
|
export function subscribeToVisibilityChange (cb, toHiddenOnly = false, capture, abortSignal) {
|
|
14
14
|
documentAddEventListener('visibilitychange', handleVisibilityChange, capture, abortSignal)
|
|
15
|
-
return
|
|
16
15
|
|
|
17
16
|
function handleVisibilityChange () {
|
|
18
17
|
if (toHiddenOnly) { // trigger cb on change to hidden state only
|
|
19
|
-
if (document.visibilityState
|
|
18
|
+
if (document.visibilityState === 'hidden') cb()
|
|
20
19
|
return
|
|
21
20
|
}
|
|
22
21
|
cb(document.visibilityState)
|
|
@@ -10,7 +10,6 @@ import { getConfiguration, getInfo, getRuntime } from '../../../common/config/co
|
|
|
10
10
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler'
|
|
11
11
|
import { setDenyList, shouldCollectEvent } from '../../../common/deny-list/deny-list'
|
|
12
12
|
import { FEATURE_NAME } from '../constants'
|
|
13
|
-
import { drain } from '../../../common/drain/drain'
|
|
14
13
|
import { FEATURE_NAMES } from '../../../loaders/features/features'
|
|
15
14
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants'
|
|
16
15
|
import { AggregateBase } from '../../utils/aggregate-base'
|
|
@@ -24,7 +23,7 @@ export class Aggregate extends AggregateBase {
|
|
|
24
23
|
|
|
25
24
|
register('xhr', storeXhr, this.featureName, this.ee)
|
|
26
25
|
if (!allAjaxIsEnabled) {
|
|
27
|
-
drain(
|
|
26
|
+
this.drain()
|
|
28
27
|
return // feature will only collect timeslice metrics & ajax trace nodes if it's not fully enabled
|
|
29
28
|
}
|
|
30
29
|
|
|
@@ -66,8 +65,7 @@ export class Aggregate extends AggregateBase {
|
|
|
66
65
|
|
|
67
66
|
ee.on(`drain-${this.featureName}`, () => { scheduler.startTimer(harvestTimeSeconds) })
|
|
68
67
|
|
|
69
|
-
drain(
|
|
70
|
-
return
|
|
68
|
+
this.drain()
|
|
71
69
|
|
|
72
70
|
function storeXhr (params, metrics, startTime, endTime, type) {
|
|
73
71
|
metrics.time = startTime
|
|
@@ -105,9 +103,9 @@ export class Aggregate extends AggregateBase {
|
|
|
105
103
|
path: params.pathname,
|
|
106
104
|
requestSize: metrics.txSize,
|
|
107
105
|
responseSize: metrics.rxSize,
|
|
108
|
-
type
|
|
109
|
-
startTime
|
|
110
|
-
endTime
|
|
106
|
+
type,
|
|
107
|
+
startTime,
|
|
108
|
+
endTime,
|
|
111
109
|
callbackDuration: metrics.cbTime
|
|
112
110
|
}
|
|
113
111
|
|
|
@@ -18,14 +18,14 @@ export class DT {
|
|
|
18
18
|
return null
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
var
|
|
22
|
-
if (!
|
|
21
|
+
var loaderConfig = getLoaderConfig(this.agentIdentifier)
|
|
22
|
+
if (!loaderConfig) {
|
|
23
23
|
return null
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
var accountId = (
|
|
27
|
-
var agentId = (
|
|
28
|
-
var trustKey = (
|
|
26
|
+
var accountId = (loaderConfig.accountID || '').toString() || null
|
|
27
|
+
var agentId = (loaderConfig.agentID || '').toString() || null
|
|
28
|
+
var trustKey = (loaderConfig.trustKey || '').toString() || null
|
|
29
29
|
|
|
30
30
|
if (!accountId || !agentId) {
|
|
31
31
|
return null
|
|
@@ -36,9 +36,9 @@ export class DT {
|
|
|
36
36
|
var timestamp = Date.now()
|
|
37
37
|
|
|
38
38
|
var payload = {
|
|
39
|
-
spanId
|
|
40
|
-
traceId
|
|
41
|
-
timestamp
|
|
39
|
+
spanId,
|
|
40
|
+
traceId,
|
|
41
|
+
timestamp
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
if (parsedOrigin.sameOrigin ||
|
|
@@ -34,6 +34,29 @@ export class Instrument extends InstrumentBase {
|
|
|
34
34
|
this.dt = new DT(agentIdentifier)
|
|
35
35
|
|
|
36
36
|
this.handler = (type, args, ctx, group) => handle(type, args, ctx, group, this.ee)
|
|
37
|
+
|
|
38
|
+
// this is a best (but imperfect) effort at capturing AJAX calls that may have fired before the agent was instantiated
|
|
39
|
+
// this could happen because the agent was "improperly" set up (ie, not at the top of the head) or
|
|
40
|
+
// because it was deferred from loading in some way -- e.g. 'deferred' script loading tags or other lazy-loading techniques
|
|
41
|
+
//
|
|
42
|
+
// it is "imperfect" because we cannot capture the following with the API vs wrapping the events directly:
|
|
43
|
+
// * requestBodySize - (txSize -- request body size)
|
|
44
|
+
// * method - request type (GET, POST, etc)
|
|
45
|
+
// * callbackDuration - (cbTime -- sum of resulting callback time)
|
|
46
|
+
try {
|
|
47
|
+
const initiators = { xmlhttprequest: 'xhr', fetch: 'fetch', beacon: 'beacon' }
|
|
48
|
+
globalScope?.performance?.getEntriesByType('resource').forEach(resource => {
|
|
49
|
+
if (resource.initiatorType in initiators && resource.responseStatus !== 0) {
|
|
50
|
+
const params = { status: resource.responseStatus }
|
|
51
|
+
const metrics = { rxSize: resource.transferSize, duration: Math.floor(resource.duration), cbTime: 0 }
|
|
52
|
+
addUrl(params, resource.name)
|
|
53
|
+
this.handler('xhr', [params, metrics, resource.startTime, resource.responseEnd, initiators[resource.initiatorType]], undefined, FEATURE_NAMES.ajax)
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
} catch (err) {
|
|
57
|
+
// do nothing
|
|
58
|
+
}
|
|
59
|
+
|
|
37
60
|
wrapFetch(this.ee)
|
|
38
61
|
wrapXhr(this.ee)
|
|
39
62
|
subscribeToEvents(agentIdentifier, this.ee, this.handler, this.dt)
|
|
@@ -97,9 +120,9 @@ function subscribeToEvents (agentIdentifier, ee, handler, dt) {
|
|
|
97
120
|
}
|
|
98
121
|
|
|
99
122
|
function onOpenXhrEnd (args, xhr) {
|
|
100
|
-
var
|
|
101
|
-
if (
|
|
102
|
-
xhr.setRequestHeader('X-NewRelic-ID',
|
|
123
|
+
var loaderConfig = getLoaderConfig(agentIdentifier)
|
|
124
|
+
if (loaderConfig.xpid && this.sameOrigin) {
|
|
125
|
+
xhr.setRequestHeader('X-NewRelic-ID', loaderConfig.xpid)
|
|
103
126
|
}
|
|
104
127
|
|
|
105
128
|
var payload = dt.generateTracePayload(this.parsedOrigin)
|
|
@@ -312,7 +335,7 @@ function subscribeToEvents (agentIdentifier, ee, handler, dt) {
|
|
|
312
335
|
|
|
313
336
|
// we capture failed call as status 0, the actual error is ignored
|
|
314
337
|
// eslint-disable-next-line handle-callback-err
|
|
315
|
-
function onFetchDone (
|
|
338
|
+
function onFetchDone (_, res) {
|
|
316
339
|
this.endTime = now()
|
|
317
340
|
if (!this.params) {
|
|
318
341
|
this.params = {}
|
|
@@ -360,19 +383,6 @@ function subscribeToEvents (agentIdentifier, ee, handler, dt) {
|
|
|
360
383
|
handler('xhr', [params, metrics, this.startTime, this.endTime, 'xhr'], this, FEATURE_NAMES.ajax)
|
|
361
384
|
}
|
|
362
385
|
|
|
363
|
-
function addUrl (ctx, url) {
|
|
364
|
-
var parsed = parseUrl(url)
|
|
365
|
-
var params = ctx.params
|
|
366
|
-
|
|
367
|
-
params.hostname = parsed.hostname
|
|
368
|
-
params.port = parsed.port
|
|
369
|
-
params.protocol = parsed.protocol
|
|
370
|
-
params.host = parsed.hostname + ':' + parsed.port
|
|
371
|
-
params.pathname = parsed.pathname
|
|
372
|
-
ctx.parsedOrigin = parsed
|
|
373
|
-
ctx.sameOrigin = parsed.sameOrigin
|
|
374
|
-
}
|
|
375
|
-
|
|
376
386
|
function captureXhrData (ctx, xhr) {
|
|
377
387
|
ctx.params.status = xhr.status
|
|
378
388
|
|
|
@@ -389,3 +399,16 @@ function subscribeToEvents (agentIdentifier, ee, handler, dt) {
|
|
|
389
399
|
ctx.loadCaptureCalled = true
|
|
390
400
|
}
|
|
391
401
|
}
|
|
402
|
+
|
|
403
|
+
function addUrl (ctx, url) {
|
|
404
|
+
var parsed = parseUrl(url)
|
|
405
|
+
var params = ctx.params || ctx
|
|
406
|
+
|
|
407
|
+
params.hostname = parsed.hostname
|
|
408
|
+
params.port = parsed.port
|
|
409
|
+
params.protocol = parsed.protocol
|
|
410
|
+
params.host = parsed.hostname + ':' + parsed.port
|
|
411
|
+
params.pathname = parsed.pathname
|
|
412
|
+
ctx.parsedOrigin = parsed
|
|
413
|
+
ctx.sameOrigin = parsed.sameOrigin
|
|
414
|
+
}
|
|
@@ -64,8 +64,8 @@ var debug = false
|
|
|
64
64
|
var classNameRegex = /function (.+?)\s*\(/
|
|
65
65
|
var chrome = /^\s*at (?:((?:\[object object\])?(?:[^(]*\([^)]*\))*[^()]*(?: \[as \S+\])?) )?\(?((?:file|http|https|chrome-extension):.*?)?:(\d+)(?::(\d+))?\)?\s*$/i
|
|
66
66
|
var gecko = /^\s*(?:(\S*|global code)(?:\(.*?\))?@)?((?:file|http|https|chrome|safari-extension).*?):(\d+)(?::(\d+))?\s*$/i
|
|
67
|
-
var
|
|
68
|
-
var
|
|
67
|
+
var chromeEval = /^\s*at .+ \(eval at \S+ \((?:(?:file|http|https):[^)]+)?\)(?:, [^:]*:\d+:\d+)?\)$/i
|
|
68
|
+
var ieEval = /^\s*at Function code \(Function code:\d+:\d+\)\s*/i
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* Represents an error with a stack trace.
|
|
@@ -209,7 +209,7 @@ function getStackElement (line) {
|
|
|
209
209
|
})
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
if (line.match(
|
|
212
|
+
if (line.match(chromeEval) || line.match(ieEval) || line === 'anonymous') {
|
|
213
213
|
return { func: 'evaluated code' }
|
|
214
214
|
}
|
|
215
215
|
}
|
|
@@ -255,7 +255,7 @@ function computeStackTraceBySourceAndLine (ex) {
|
|
|
255
255
|
mode: 'sourceline',
|
|
256
256
|
name: className,
|
|
257
257
|
message: ex.message,
|
|
258
|
-
stackString
|
|
258
|
+
stackString,
|
|
259
259
|
frames: [{
|
|
260
260
|
url: canonicalUrl,
|
|
261
261
|
line: ex.line,
|