@newrelic/browser-agent 1.235.0 → 1.237.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/README.md +41 -1
- package/dist/cjs/common/config/state/init.js +4 -0
- package/dist/cjs/common/config/state/runtime.js +6 -5
- package/dist/cjs/common/constants/env.cdn.js +2 -2
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/constants/runtime.js +52 -0
- package/dist/cjs/common/deny-list/deny-list.js +14 -10
- package/dist/cjs/common/event-listener/event-listener-opts.js +3 -3
- package/dist/cjs/common/harvest/harvest-scheduler.js +22 -19
- package/dist/cjs/common/harvest/harvest.js +154 -148
- package/dist/cjs/common/harvest/types.js +54 -0
- package/dist/cjs/common/ids/id.js +2 -2
- package/dist/cjs/common/ids/unique-id.js +3 -3
- package/dist/cjs/common/session/session-entity.js +2 -2
- package/dist/cjs/common/timer/interaction-timer.js +2 -2
- package/dist/cjs/common/unload/eol.js +10 -11
- package/dist/cjs/common/url/canonicalize-url.js +2 -2
- package/dist/cjs/common/url/parse-url.js +3 -3
- package/dist/cjs/common/url/protocol.js +2 -2
- package/dist/cjs/common/util/submit-data.js +31 -81
- package/dist/cjs/common/window/nreum.js +14 -14
- package/dist/cjs/common/wrap/wrap-events.js +3 -3
- package/dist/cjs/common/wrap/wrap-fetch.js +5 -5
- package/dist/cjs/common/wrap/wrap-history.js +2 -2
- package/dist/cjs/common/wrap/wrap-jsonp.js +14 -8
- package/dist/cjs/common/wrap/wrap-mutation.js +2 -2
- package/dist/cjs/common/wrap/wrap-promise.js +2 -2
- package/dist/cjs/common/wrap/wrap-raf.js +2 -2
- package/dist/cjs/common/wrap/wrap-timer.js +4 -4
- package/dist/cjs/common/wrap/wrap-xhr.js +3 -3
- package/dist/cjs/features/ajax/aggregate/index.js +25 -28
- package/dist/cjs/features/ajax/instrument/distributed-tracing.js +2 -2
- package/dist/cjs/features/ajax/instrument/index.js +6 -7
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +1 -1
- package/dist/cjs/features/jserrors/aggregate/index.js +7 -4
- package/dist/cjs/features/jserrors/constants.js +2 -4
- package/dist/cjs/features/jserrors/instrument/index.js +80 -89
- package/dist/cjs/features/jserrors/instrument/uncaught-error.js +22 -0
- package/dist/cjs/features/metrics/aggregate/framework-detection.js +2 -2
- package/dist/cjs/features/metrics/aggregate/index.js +3 -3
- package/dist/cjs/features/page_action/aggregate/index.js +3 -3
- package/dist/cjs/features/page_view_event/aggregate/index.js +10 -11
- package/dist/cjs/features/page_view_event/aggregate/initialized-features.js +23 -19
- package/dist/cjs/features/page_view_event/instrument/index.js +2 -2
- package/dist/cjs/features/page_view_timing/aggregate/index.js +3 -5
- package/dist/cjs/features/page_view_timing/instrument/index.js +2 -2
- package/dist/cjs/features/session_replay/aggregate/index.js +65 -34
- package/dist/cjs/features/session_replay/replay-mode.js +2 -2
- package/dist/cjs/features/session_trace/aggregate/index.js +3 -4
- package/dist/cjs/features/session_trace/instrument/index.js +2 -2
- package/dist/cjs/features/spa/aggregate/index.js +1 -1
- package/dist/cjs/features/spa/instrument/index.js +2 -2
- package/dist/cjs/features/utils/instrument-base.js +12 -15
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/loaders/agent-base.js +87 -0
- package/dist/cjs/loaders/agent.js +48 -1
- package/dist/cjs/loaders/api/api.js +3 -3
- package/dist/cjs/loaders/api/apiAsync.js +6 -4
- package/dist/cjs/loaders/api/interaction-types.js +87 -0
- package/dist/cjs/loaders/configure/configure.js +4 -3
- package/dist/cjs/loaders/micro-agent.js +32 -39
- package/dist/esm/common/config/state/init.js +4 -0
- package/dist/esm/common/config/state/runtime.js +3 -2
- package/dist/esm/common/constants/env.cdn.js +2 -2
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/constants/runtime.js +38 -0
- package/dist/esm/common/deny-list/deny-list.js +14 -10
- package/dist/esm/common/event-listener/event-listener-opts.js +1 -1
- package/dist/esm/common/harvest/harvest-scheduler.js +21 -20
- package/dist/esm/common/harvest/harvest.js +150 -146
- package/dist/esm/common/harvest/types.js +47 -0
- package/dist/esm/common/ids/id.js +1 -1
- package/dist/esm/common/ids/unique-id.js +1 -1
- package/dist/esm/common/session/session-entity.js +1 -1
- package/dist/esm/common/timer/interaction-timer.js +1 -1
- package/dist/esm/common/unload/eol.js +1 -2
- package/dist/esm/common/url/canonicalize-url.js +1 -1
- package/dist/esm/common/url/parse-url.js +1 -1
- package/dist/esm/common/url/protocol.js +1 -1
- package/dist/esm/common/util/submit-data.js +29 -78
- package/dist/esm/common/window/nreum.js +1 -1
- package/dist/esm/common/wrap/wrap-events.js +1 -1
- package/dist/esm/common/wrap/wrap-fetch.js +1 -1
- package/dist/esm/common/wrap/wrap-history.js +1 -1
- package/dist/esm/common/wrap/wrap-jsonp.js +13 -7
- package/dist/esm/common/wrap/wrap-mutation.js +1 -1
- package/dist/esm/common/wrap/wrap-promise.js +1 -1
- package/dist/esm/common/wrap/wrap-raf.js +1 -1
- package/dist/esm/common/wrap/wrap-timer.js +1 -1
- package/dist/esm/common/wrap/wrap-xhr.js +1 -1
- package/dist/esm/features/ajax/aggregate/index.js +26 -29
- package/dist/esm/features/ajax/instrument/distributed-tracing.js +1 -1
- package/dist/esm/features/ajax/instrument/index.js +1 -2
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +1 -1
- package/dist/esm/features/jserrors/aggregate/index.js +6 -3
- package/dist/esm/features/jserrors/constants.js +1 -2
- package/dist/esm/features/jserrors/instrument/index.js +79 -88
- package/dist/esm/features/jserrors/instrument/uncaught-error.js +15 -0
- package/dist/esm/features/metrics/aggregate/framework-detection.js +1 -1
- package/dist/esm/features/metrics/aggregate/index.js +1 -1
- package/dist/esm/features/page_action/aggregate/index.js +1 -1
- package/dist/esm/features/page_view_event/aggregate/index.js +1 -2
- package/dist/esm/features/page_view_event/aggregate/initialized-features.js +23 -19
- package/dist/esm/features/page_view_event/instrument/index.js +1 -1
- package/dist/esm/features/page_view_timing/aggregate/index.js +2 -4
- package/dist/esm/features/page_view_timing/instrument/index.js +1 -1
- package/dist/esm/features/session_replay/aggregate/index.js +65 -34
- package/dist/esm/features/session_replay/replay-mode.js +2 -2
- package/dist/esm/features/session_trace/aggregate/index.js +3 -4
- package/dist/esm/features/session_trace/instrument/index.js +1 -1
- package/dist/esm/features/spa/aggregate/index.js +1 -1
- package/dist/esm/features/spa/instrument/index.js +1 -1
- package/dist/esm/features/utils/instrument-base.js +11 -14
- package/dist/esm/index.js +1 -4
- package/dist/esm/loaders/agent-base.js +80 -0
- package/dist/esm/loaders/agent.js +48 -1
- package/dist/esm/loaders/api/api.js +2 -2
- package/dist/esm/loaders/api/apiAsync.js +3 -3
- package/dist/esm/loaders/api/interaction-types.js +80 -0
- package/dist/esm/loaders/configure/configure.js +4 -3
- package/dist/esm/loaders/micro-agent.js +32 -39
- 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 +29 -0
- package/dist/types/common/constants/runtime.d.ts.map +1 -0
- package/dist/types/common/event-emitter/register-handler.d.ts +1 -1
- package/dist/types/common/harvest/harvest-scheduler.d.ts +1 -1
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest.d.ts +49 -38
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/harvest/types.d.ts +100 -0
- package/dist/types/common/harvest/types.d.ts.map +1 -0
- package/dist/types/common/session/session-entity.d.ts +6 -6
- package/dist/types/common/unload/eol.d.ts.map +1 -1
- package/dist/types/common/util/submit-data.d.ts +44 -64
- package/dist/types/common/util/submit-data.d.ts.map +1 -1
- package/dist/types/common/window/nreum.d.ts +2 -2
- package/dist/types/common/wrap/wrap-jsonp.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts +5 -5
- 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/index.d.ts +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/constants.d.ts +0 -1
- package/dist/types/features/jserrors/constants.d.ts.map +1 -1
- package/dist/types/features/jserrors/instrument/index.d.ts +0 -13
- package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/instrument/uncaught-error.d.ts +15 -0
- package/dist/types/features/jserrors/instrument/uncaught-error.d.ts.map +1 -0
- package/dist/types/features/metrics/aggregate/endpoint-map.d.ts +5 -5
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/initialized-features.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 +16 -30
- 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/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/loaders/agent-base.d.ts +59 -0
- package/dist/types/loaders/agent-base.d.ts.map +1 -0
- package/dist/types/loaders/agent.d.ts +39 -5
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/interaction-types.d.ts +122 -0
- package/dist/types/loaders/api/interaction-types.d.ts.map +1 -0
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts +9 -9
- package/dist/types/loaders/micro-agent.d.ts +6 -6
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/common/config/__mocks__/config.js +11 -0
- package/src/common/config/state/init.js +2 -1
- package/src/common/config/state/runtime.js +3 -2
- package/src/common/constants/__mocks__/env.js +3 -0
- package/src/common/constants/__mocks__/runtime.js +8 -0
- package/src/common/constants/env.cdn.test.js +7 -0
- package/src/common/constants/env.npm.test.js +7 -0
- package/src/common/constants/env.test.js +7 -0
- package/src/common/constants/runtime.js +71 -0
- package/src/common/constants/runtime.test.js +168 -0
- package/src/common/context/__mocks__/shared-context.js +8 -0
- package/src/common/deny-list/deny-list.js +11 -11
- package/src/common/deny-list/deny-list.test.js +31 -0
- package/src/common/event-listener/__mocks__/event-listener-opts.js +7 -0
- package/src/common/event-listener/event-listener-opts.js +1 -1
- package/src/common/harvest/__mocks__/harvest.js +13 -0
- package/src/common/harvest/harvest-scheduler.js +21 -20
- package/src/common/harvest/harvest-scheduler.test.js +496 -0
- package/src/common/harvest/harvest.js +142 -134
- package/src/common/harvest/harvest.test.js +798 -0
- package/src/common/harvest/types.js +47 -0
- package/src/common/ids/id.js +1 -1
- package/src/common/ids/unique-id.js +1 -1
- package/src/common/session/__mocks__/session-entity.js +25 -0
- package/src/common/session/session-entity.component-test.js +1 -1
- package/src/common/session/session-entity.js +1 -1
- package/src/common/timer/interaction-timer.js +1 -1
- package/src/common/timing/__mocks__/now.js +1 -0
- package/src/common/unload/__mocks__/eol.js +1 -0
- package/src/common/unload/eol.js +1 -2
- package/src/common/url/__mocks__/clean-url.js +1 -0
- package/src/common/url/__mocks__/encode.js +7 -0
- package/src/common/url/__mocks__/location.js +1 -0
- package/src/common/url/canonicalize-url.js +1 -1
- package/src/common/url/canonicalize-url.test.js +2 -2
- package/src/common/url/parse-url.js +1 -1
- package/src/common/url/parse-url.test.js +3 -3
- package/src/common/url/protocol.js +1 -1
- package/src/common/util/__mocks__/obfuscate.js +10 -0
- package/src/common/util/__mocks__/stringify.js +1 -0
- package/src/common/util/__mocks__/submit-data.js +5 -0
- package/src/common/util/__mocks__/traverse.js +1 -0
- package/src/common/util/submit-data.js +22 -58
- package/src/common/util/submit-data.test.js +30 -73
- package/src/common/window/nreum.js +1 -1
- package/src/common/wrap/wrap-events.js +1 -1
- package/src/common/wrap/wrap-fetch.js +1 -1
- package/src/common/wrap/wrap-history.js +1 -1
- package/src/common/wrap/wrap-jsonp.js +12 -7
- package/src/common/wrap/wrap-mutation.js +1 -1
- package/src/common/wrap/wrap-promise.js +1 -1
- package/src/common/wrap/wrap-promise.test.js +2 -2
- package/src/common/wrap/wrap-raf.js +1 -1
- package/src/common/wrap/wrap-timer.js +1 -1
- package/src/common/wrap/wrap-xhr.js +1 -1
- package/src/features/ajax/aggregate/index.js +26 -32
- package/src/features/ajax/instrument/distributed-tracing.js +1 -1
- package/src/features/ajax/instrument/index.js +1 -2
- package/src/features/jserrors/aggregate/compute-stack-trace.js +1 -1
- package/src/features/jserrors/aggregate/compute-stack-trace.test.js +1 -1
- package/src/features/jserrors/aggregate/index.js +7 -3
- package/src/features/jserrors/constants.js +0 -1
- package/src/features/jserrors/instrument/index.js +92 -88
- package/src/features/jserrors/instrument/uncaught-error.js +15 -0
- package/src/features/metrics/aggregate/framework-detection.js +1 -1
- package/src/features/metrics/aggregate/framework-detection.test.js +2 -2
- package/src/features/metrics/aggregate/index.js +1 -1
- package/src/features/page_action/aggregate/index.js +1 -1
- package/src/features/page_view_event/aggregate/index.js +1 -2
- package/src/features/page_view_event/aggregate/initialized-features.js +18 -14
- package/src/features/page_view_event/instrument/index.js +1 -1
- package/src/features/page_view_timing/aggregate/index.js +2 -4
- package/src/features/page_view_timing/instrument/index.js +1 -1
- package/src/features/session_replay/aggregate/index.component-test.js +17 -56
- package/src/features/session_replay/aggregate/index.js +47 -28
- package/src/features/session_replay/replay-mode.js +2 -2
- package/src/features/session_trace/aggregate/index.js +3 -4
- package/src/features/session_trace/instrument/index.js +1 -1
- package/src/features/spa/aggregate/index.js +1 -1
- package/src/features/spa/instrument/index.js +1 -1
- package/src/features/utils/agent-session.test.js +2 -2
- package/src/features/utils/instrument-base.js +11 -14
- package/src/features/utils/instrument-base.test.js +29 -3
- package/src/index.js +1 -3
- package/src/loaders/agent-base.js +81 -0
- package/src/loaders/agent.js +50 -1
- package/src/loaders/api/api.js +2 -2
- package/src/loaders/api/apiAsync.js +3 -3
- package/src/loaders/api/interaction-types.js +80 -0
- package/src/loaders/configure/configure.js +5 -4
- package/src/loaders/micro-agent.js +30 -31
- package/dist/cjs/common/browser-version/firefox-version.js +0 -17
- package/dist/cjs/common/browser-version/ios-version.js +0 -19
- package/dist/cjs/common/event-emitter/contextual-ee.test.js +0 -282
- package/dist/cjs/common/event-emitter/handle.test.js +0 -58
- package/dist/cjs/common/event-emitter/register-handler.test.js +0 -55
- package/dist/cjs/common/harvest/harvest-scheduler.component-test.js +0 -39
- package/dist/cjs/common/harvest/harvest.component-test.js +0 -224
- package/dist/cjs/common/ids/id.test.js +0 -85
- package/dist/cjs/common/ids/unique-id.test.js +0 -49
- package/dist/cjs/common/session/session-entity.component-test.js +0 -497
- package/dist/cjs/common/storage/local-storage.test.js +0 -14
- package/dist/cjs/common/timer/interaction-timer.component-test.js +0 -216
- package/dist/cjs/common/timer/timer.test.js +0 -105
- package/dist/cjs/common/timing/nav-timing.test.js +0 -192
- package/dist/cjs/common/url/canonicalize-url.test.js +0 -38
- package/dist/cjs/common/url/clean-url.test.js +0 -9
- package/dist/cjs/common/url/encode.component-test.js +0 -74
- package/dist/cjs/common/url/location.test.js +0 -13
- package/dist/cjs/common/url/parse-url.test.js +0 -111
- package/dist/cjs/common/url/protocol.component-test.js +0 -15
- package/dist/cjs/common/util/console.test.js +0 -30
- package/dist/cjs/common/util/data-size.test.js +0 -64
- package/dist/cjs/common/util/feature-flags.test.js +0 -84
- package/dist/cjs/common/util/get-or-set.test.js +0 -47
- package/dist/cjs/common/util/global-scope.js +0 -27
- package/dist/cjs/common/util/global-scope.test.js +0 -72
- package/dist/cjs/common/util/invoke.test.js +0 -49
- package/dist/cjs/common/util/map-own.test.js +0 -49
- package/dist/cjs/common/util/obfuscate.component-test.js +0 -129
- package/dist/cjs/common/util/stringify.test.js +0 -48
- package/dist/cjs/common/util/submit-data.test.js +0 -245
- package/dist/cjs/common/util/traverse.test.js +0 -44
- package/dist/cjs/common/wrap/wrap-promise.test.js +0 -119
- package/dist/cjs/features/jserrors/aggregate/canonical-function-name.test.js +0 -31
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +0 -383
- package/dist/cjs/features/jserrors/aggregate/format-stack-trace.test.js +0 -40
- package/dist/cjs/features/jserrors/aggregate/string-hash-code.test.js +0 -27
- package/dist/cjs/features/jserrors/instrument/debug.js +0 -40
- package/dist/cjs/features/metrics/aggregate/framework-detection.test.js +0 -137
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.test.js +0 -17
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.test.js +0 -165
- package/dist/cjs/features/session_replay/aggregate/index.component-test.js +0 -457
- package/dist/cjs/features/spa/aggregate/interaction-node.test.js +0 -16
- package/dist/cjs/features/utils/agent-session.test.js +0 -211
- package/dist/cjs/features/utils/aggregate-base.test.js +0 -110
- package/dist/cjs/features/utils/feature-base.test.js +0 -42
- package/dist/cjs/features/utils/handler-cache.test.js +0 -53
- package/dist/cjs/features/utils/instrument-base.test.js +0 -179
- package/dist/cjs/features/utils/lazy-feature-loader.test.js +0 -30
- package/dist/esm/common/browser-version/firefox-version.js +0 -10
- package/dist/esm/common/browser-version/ios-version.js +0 -11
- package/dist/esm/common/event-emitter/contextual-ee.test.js +0 -278
- package/dist/esm/common/event-emitter/handle.test.js +0 -54
- package/dist/esm/common/event-emitter/register-handler.test.js +0 -51
- package/dist/esm/common/harvest/harvest-scheduler.component-test.js +0 -37
- package/dist/esm/common/harvest/harvest.component-test.js +0 -222
- package/dist/esm/common/ids/id.test.js +0 -81
- package/dist/esm/common/ids/unique-id.test.js +0 -44
- package/dist/esm/common/session/session-entity.component-test.js +0 -495
- package/dist/esm/common/storage/local-storage.test.js +0 -12
- package/dist/esm/common/timer/interaction-timer.component-test.js +0 -214
- package/dist/esm/common/timer/timer.test.js +0 -103
- package/dist/esm/common/timing/nav-timing.test.js +0 -190
- package/dist/esm/common/url/canonicalize-url.test.js +0 -34
- package/dist/esm/common/url/clean-url.test.js +0 -7
- package/dist/esm/common/url/encode.component-test.js +0 -70
- package/dist/esm/common/url/location.test.js +0 -11
- package/dist/esm/common/url/parse-url.test.js +0 -107
- package/dist/esm/common/url/protocol.component-test.js +0 -13
- package/dist/esm/common/util/console.test.js +0 -28
- package/dist/esm/common/util/data-size.test.js +0 -60
- package/dist/esm/common/util/feature-flags.test.js +0 -80
- package/dist/esm/common/util/get-or-set.test.js +0 -45
- package/dist/esm/common/util/global-scope.js +0 -17
- package/dist/esm/common/util/global-scope.test.js +0 -70
- package/dist/esm/common/util/invoke.test.js +0 -47
- package/dist/esm/common/util/map-own.test.js +0 -47
- package/dist/esm/common/util/obfuscate.component-test.js +0 -125
- package/dist/esm/common/util/stringify.test.js +0 -46
- package/dist/esm/common/util/submit-data.test.js +0 -241
- package/dist/esm/common/util/traverse.test.js +0 -42
- package/dist/esm/common/wrap/wrap-promise.test.js +0 -115
- package/dist/esm/features/jserrors/aggregate/canonical-function-name.test.js +0 -29
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +0 -379
- package/dist/esm/features/jserrors/aggregate/format-stack-trace.test.js +0 -38
- package/dist/esm/features/jserrors/aggregate/string-hash-code.test.js +0 -25
- package/dist/esm/features/jserrors/instrument/debug.js +0 -38
- package/dist/esm/features/metrics/aggregate/framework-detection.test.js +0 -133
- package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.test.js +0 -15
- package/dist/esm/features/metrics/aggregate/polyfill-detection.test.js +0 -163
- package/dist/esm/features/session_replay/aggregate/index.component-test.js +0 -453
- package/dist/esm/features/spa/aggregate/interaction-node.test.js +0 -14
- package/dist/esm/features/utils/agent-session.test.js +0 -207
- package/dist/esm/features/utils/aggregate-base.test.js +0 -108
- package/dist/esm/features/utils/feature-base.test.js +0 -40
- package/dist/esm/features/utils/handler-cache.test.js +0 -51
- package/dist/esm/features/utils/instrument-base.test.js +0 -175
- package/dist/esm/features/utils/lazy-feature-loader.test.js +0 -29
- package/dist/types/common/browser-version/firefox-version.d.ts +0 -2
- package/dist/types/common/browser-version/firefox-version.d.ts.map +0 -1
- package/dist/types/common/browser-version/ios-version.d.ts +0 -3
- package/dist/types/common/browser-version/ios-version.d.ts.map +0 -1
- package/dist/types/common/harvest/harvest-scheduler.component-test.d.ts +0 -2
- package/dist/types/common/harvest/harvest-scheduler.component-test.d.ts.map +0 -1
- package/dist/types/common/harvest/harvest.component-test.d.ts +0 -2
- package/dist/types/common/harvest/harvest.component-test.d.ts.map +0 -1
- package/dist/types/common/session/session-entity.component-test.d.ts +0 -2
- package/dist/types/common/session/session-entity.component-test.d.ts.map +0 -1
- package/dist/types/common/timer/interaction-timer.component-test.d.ts +0 -2
- package/dist/types/common/timer/interaction-timer.component-test.d.ts.map +0 -1
- package/dist/types/common/url/encode.component-test.d.ts +0 -2
- package/dist/types/common/url/encode.component-test.d.ts.map +0 -1
- package/dist/types/common/url/protocol.component-test.d.ts +0 -2
- package/dist/types/common/url/protocol.component-test.d.ts.map +0 -1
- package/dist/types/common/util/global-scope.d.ts +0 -5
- package/dist/types/common/util/global-scope.d.ts.map +0 -1
- package/dist/types/common/util/obfuscate.component-test.d.ts +0 -2
- package/dist/types/common/util/obfuscate.component-test.d.ts.map +0 -1
- package/dist/types/features/jserrors/instrument/debug.d.ts +0 -2
- package/dist/types/features/jserrors/instrument/debug.d.ts.map +0 -1
- package/dist/types/features/session_replay/aggregate/index.component-test.d.ts +0 -2
- package/dist/types/features/session_replay/aggregate/index.component-test.d.ts.map +0 -1
- package/src/common/browser-version/firefox-version.js +0 -10
- package/src/common/browser-version/ios-version.js +0 -11
- package/src/common/harvest/harvest-scheduler.component-test.js +0 -25
- package/src/common/harvest/harvest.component-test.js +0 -169
- package/src/common/util/global-scope.js +0 -23
- package/src/common/util/global-scope.test.js +0 -87
- package/src/features/jserrors/instrument/debug.js +0 -36
|
@@ -5,63 +5,53 @@
|
|
|
5
5
|
|
|
6
6
|
import { handle } from '../../../common/event-emitter/handle';
|
|
7
7
|
import { now } from '../../../common/timing/now';
|
|
8
|
-
import { getOrSet } from '../../../common/util/get-or-set';
|
|
9
|
-
import { wrapRaf, wrapTimer, wrapEvents, wrapXhr } from '../../../common/wrap';
|
|
10
|
-
import './debug';
|
|
11
8
|
import { InstrumentBase } from '../../utils/instrument-base';
|
|
12
|
-
import { FEATURE_NAME
|
|
9
|
+
import { FEATURE_NAME } from '../constants';
|
|
13
10
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
14
|
-
import { globalScope } from '../../../common/
|
|
11
|
+
import { globalScope } from '../../../common/constants/runtime';
|
|
15
12
|
import { eventListenerOpts } from '../../../common/event-listener/event-listener-opts';
|
|
16
|
-
import { getRuntime } from '../../../common/config/config';
|
|
17
13
|
import { stringify } from '../../../common/util/stringify';
|
|
14
|
+
import { UncaughtError } from './uncaught-error';
|
|
18
15
|
export class Instrument extends InstrumentBase {
|
|
19
16
|
static featureName = FEATURE_NAME;
|
|
17
|
+
#seenErrors = new Set();
|
|
20
18
|
constructor(agentIdentifier, aggregator) {
|
|
21
19
|
let auto = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
22
20
|
super(agentIdentifier, aggregator, FEATURE_NAME, auto);
|
|
23
|
-
// skipNext counter to keep track of uncaught
|
|
24
|
-
// errors that will be the same as caught errors.
|
|
25
|
-
this.skipNext = 0;
|
|
26
21
|
try {
|
|
27
22
|
// this try-catch can be removed when IE11 is completely unsupported & gone
|
|
28
23
|
this.removeOnAbort = new AbortController();
|
|
29
24
|
} catch (e) {}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
getOrSet(err, NR_ERR_PROP, function getVal() {
|
|
37
|
-
return true;
|
|
38
|
-
});
|
|
39
|
-
this.thrown = true;
|
|
40
|
-
handle('err', [err, now()], undefined, FEATURE_NAMES.jserrors, thisInstrument.ee);
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
thisInstrument.ee.on('fn-end', function () {
|
|
44
|
-
if (!thisInstrument.abortHandler) return;
|
|
45
|
-
if (!this.thrown && thisInstrument.skipNext > 0) thisInstrument.skipNext -= 1;
|
|
25
|
+
|
|
26
|
+
// Capture function errors early in case the spa feature is loaded
|
|
27
|
+
this.ee.on('fn-err', (args, obj, error) => {
|
|
28
|
+
if (!this.abortHandler || this.#seenErrors.has(error)) return;
|
|
29
|
+
this.#seenErrors.add(error);
|
|
30
|
+
handle('err', [this.#castError(error), now()], undefined, FEATURE_NAMES.jserrors, this.ee);
|
|
46
31
|
});
|
|
47
|
-
|
|
48
|
-
|
|
32
|
+
this.ee.on('internal-error', error => {
|
|
33
|
+
if (!this.abortHandler) return;
|
|
34
|
+
handle('ierr', [this.#castError(error), now(), true], undefined, FEATURE_NAMES.jserrors, this.ee);
|
|
49
35
|
});
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
globalScope.onerror = this.onerrorHandler.bind(this);
|
|
54
|
-
globalScope.addEventListener('unhandledrejection', e => {
|
|
55
|
-
/** rejections can contain data of any type -- this is an effort to keep the message human readable */
|
|
56
|
-
const err = castReasonToError(e.reason);
|
|
57
|
-
handle('err', [err, now(), false, {
|
|
36
|
+
globalScope.addEventListener('unhandledrejection', promiseRejectionEvent => {
|
|
37
|
+
if (!this.abortHandler) return;
|
|
38
|
+
handle('err', [this.#castPromiseRejectionEvent(promiseRejectionEvent), now(), false, {
|
|
58
39
|
unhandledPromiseRejection: 1
|
|
59
40
|
}], undefined, FEATURE_NAMES.jserrors, this.ee);
|
|
60
41
|
}, eventListenerOpts(false, this.removeOnAbort?.signal));
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
42
|
+
globalScope.addEventListener('error', errorEvent => {
|
|
43
|
+
if (!this.abortHandler) return;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* If the spa feature is loaded, errors may already have been captured in the `fn-err` listener above.
|
|
47
|
+
* This ensures those errors are not captured twice.
|
|
48
|
+
*/
|
|
49
|
+
if (this.#seenErrors.has(errorEvent.error)) {
|
|
50
|
+
this.#seenErrors.delete(errorEvent.error);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
handle('err', [this.#castErrorEvent(errorEvent), now()], undefined, FEATURE_NAMES.jserrors, this.ee);
|
|
54
|
+
}, eventListenerOpts(false, this.removeOnAbort?.signal));
|
|
65
55
|
this.abortHandler = this.#abort; // we also use this as a flag to denote that the feature is active or on and handling errors
|
|
66
56
|
this.importAggregator();
|
|
67
57
|
}
|
|
@@ -69,65 +59,66 @@ export class Instrument extends InstrumentBase {
|
|
|
69
59
|
/** Restoration and resource release tasks to be done if JS error loader is being aborted. Unwind changes to globals. */
|
|
70
60
|
#abort() {
|
|
71
61
|
this.removeOnAbort?.abort();
|
|
62
|
+
this.#seenErrors.clear();
|
|
72
63
|
this.abortHandler = undefined; // weakly allow this abort op to run only once
|
|
73
64
|
}
|
|
74
65
|
|
|
75
66
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* @param {
|
|
79
|
-
* @
|
|
80
|
-
* @param {number} lineno
|
|
81
|
-
* @param {number} column
|
|
82
|
-
* @param {Error | *} errorObj
|
|
83
|
-
* @returns
|
|
67
|
+
* Any value can be used with the `throw` keyword. This function ensures that the value is
|
|
68
|
+
* either a proper Error instance or attempts to convert it to an UncaughtError instance.
|
|
69
|
+
* @param {any} error The value thrown
|
|
70
|
+
* @returns {Error|UncaughtError} The converted error instance
|
|
84
71
|
*/
|
|
85
|
-
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
72
|
+
#castError(error) {
|
|
73
|
+
if (error instanceof Error) {
|
|
74
|
+
return error;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The thrown value may contain a message property. If it does, try to treat the thrown
|
|
79
|
+
* value as an Error-like object.
|
|
80
|
+
*/
|
|
81
|
+
if (typeof error?.message !== 'undefined') {
|
|
82
|
+
return new UncaughtError(error.message, error.filename || error.sourceURL, error.lineno || error.line, error.colno || error.col);
|
|
83
|
+
}
|
|
84
|
+
return new UncaughtError(typeof error === 'string' ? error : stringify(error));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Attempts to convert a PromiseRejectionEvent object to an Error object
|
|
89
|
+
* @param {PromiseRejectionEvent} unhandledRejectionEvent The unhandled promise rejection event
|
|
90
|
+
* @returns {Error} An Error object with the message as the casted reason
|
|
91
|
+
*/
|
|
92
|
+
#castPromiseRejectionEvent(promiseRejectionEvent) {
|
|
93
|
+
let prefix = 'Unhandled Promise Rejection: ';
|
|
94
|
+
if (promiseRejectionEvent?.reason instanceof Error) {
|
|
90
95
|
try {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
promiseRejectionEvent.reason.message = prefix + promiseRejectionEvent.reason.message;
|
|
97
|
+
return promiseRejectionEvent.reason;
|
|
98
|
+
} catch (e) {
|
|
99
|
+
return promiseRejectionEvent.reason;
|
|
94
100
|
}
|
|
95
101
|
}
|
|
96
|
-
|
|
102
|
+
if (typeof promiseRejectionEvent.reason === 'undefined') return new UncaughtError(prefix);
|
|
103
|
+
const error = this.#castError(promiseRejectionEvent.reason);
|
|
104
|
+
error.message = prefix + error.message;
|
|
105
|
+
return error;
|
|
97
106
|
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
*
|
|
102
|
-
* @param {string} message
|
|
103
|
-
* @param {string} filename
|
|
104
|
-
* @param {number} lineno
|
|
105
|
-
*/
|
|
106
|
-
function UncaughtException(message, filename, lineno) {
|
|
107
|
-
this.message = message || 'Uncaught error with no additional information';
|
|
108
|
-
this.sourceURL = filename;
|
|
109
|
-
this.line = lineno;
|
|
110
|
-
}
|
|
111
107
|
|
|
112
|
-
/**
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
reason.message = prefix + reason.message;
|
|
122
|
-
return reason;
|
|
123
|
-
} catch (e) {
|
|
124
|
-
return reason;
|
|
108
|
+
/**
|
|
109
|
+
* Attempts to convert an ErrorEvent object to an Error object
|
|
110
|
+
* @param {ErrorEvent} errorEvent The error event
|
|
111
|
+
* @returns {Error|UncaughtError} The error event converted to an Error object
|
|
112
|
+
*/
|
|
113
|
+
#castErrorEvent(errorEvent) {
|
|
114
|
+
if (errorEvent.error instanceof Error) {
|
|
115
|
+
return errorEvent.error;
|
|
125
116
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return new
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Older browsers do not contain the `error` property on the ErrorEvent instance.
|
|
120
|
+
* https://caniuse.com/mdn-api_errorevent_error
|
|
121
|
+
*/
|
|
122
|
+
return new UncaughtError(errorEvent.message, errorEvent.filename, errorEvent.lineno, errorEvent.colno);
|
|
132
123
|
}
|
|
133
124
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents an uncaught non Error type error. This class does
|
|
3
|
+
* not extend the Error class to prevent an invalid stack trace
|
|
4
|
+
* from being created. Use this class to cast thrown errors that
|
|
5
|
+
* do not use the Error class (strings, etc) to an object.
|
|
6
|
+
*/
|
|
7
|
+
export class UncaughtError {
|
|
8
|
+
constructor(message, filename, lineno, colno) {
|
|
9
|
+
this.name = 'UncaughtError';
|
|
10
|
+
this.message = message;
|
|
11
|
+
this.sourceURL = filename;
|
|
12
|
+
this.line = lineno;
|
|
13
|
+
this.column = colno;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -10,7 +10,7 @@ import { getRules, validateRules } from '../../../common/util/obfuscate';
|
|
|
10
10
|
import { VERSION } from "../../../common/constants/env.npm";
|
|
11
11
|
import { onDOMContentLoaded } from '../../../common/window/load';
|
|
12
12
|
import { windowAddEventListener } from '../../../common/event-listener/event-listener-opts';
|
|
13
|
-
import { isBrowserScope } from '../../../common/
|
|
13
|
+
import { isBrowserScope } from '../../../common/constants/runtime';
|
|
14
14
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
15
15
|
import { stringify } from '../../../common/util/stringify';
|
|
16
16
|
import { endpointMap } from './endpoint-map';
|
|
@@ -11,7 +11,7 @@ import { cleanURL } from '../../../common/url/clean-url';
|
|
|
11
11
|
import { getConfigurationValue, getInfo, getRuntime } from '../../../common/config/config';
|
|
12
12
|
import { FEATURE_NAME } from '../constants';
|
|
13
13
|
import { drain } from '../../../common/drain/drain';
|
|
14
|
-
import { isBrowserScope } from '../../../common/
|
|
14
|
+
import { isBrowserScope } from '../../../common/constants/runtime';
|
|
15
15
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
16
16
|
export class Aggregate extends AggregateBase {
|
|
17
17
|
static featureName = FEATURE_NAME;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { handle } from '../../../common/event-emitter/handle';
|
|
2
2
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
3
|
-
import { isiOS } from '../../../common/
|
|
3
|
+
import { isiOS, globalScope, isBrowserScope } from '../../../common/constants/runtime';
|
|
4
4
|
import { onTTFB } from 'web-vitals';
|
|
5
5
|
import { addPT, addPN } from '../../../common/timing/nav-timing';
|
|
6
6
|
import { stringify } from '../../../common/util/stringify';
|
|
@@ -9,7 +9,6 @@ import { getConfigurationValue, getInfo, getRuntime } from '../../../common/conf
|
|
|
9
9
|
import { Harvest } from '../../../common/harvest/harvest';
|
|
10
10
|
import * as CONSTANTS from '../constants';
|
|
11
11
|
import { getActivatedFeaturesFlags } from './initialized-features';
|
|
12
|
-
import { globalScope, isBrowserScope } from '../../../common/util/global-scope';
|
|
13
12
|
import { drain } from '../../../common/drain/drain';
|
|
14
13
|
import { activateFeatures } from '../../../common/util/feature-flags';
|
|
15
14
|
import { warn } from '../../../common/util/console';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
2
|
+
import { gosNREUM } from '../../../common/window/nreum';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Get an array of flags required by downstream (NR UI) based on the features initialized in this agent
|
|
@@ -8,25 +9,28 @@ import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
|
8
9
|
*/
|
|
9
10
|
export function getActivatedFeaturesFlags(agentId) {
|
|
10
11
|
const flagArr = [];
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
12
|
+
const newrelic = gosNREUM();
|
|
13
|
+
try {
|
|
14
|
+
Object.keys(newrelic.initializedAgents[agentId].features).forEach(featName => {
|
|
15
|
+
switch (featName) {
|
|
16
|
+
case FEATURE_NAMES.ajax:
|
|
17
|
+
flagArr.push('xhr');
|
|
18
|
+
break;
|
|
19
|
+
case FEATURE_NAMES.jserrors:
|
|
20
|
+
flagArr.push('err');
|
|
21
|
+
break;
|
|
22
|
+
case FEATURE_NAMES.pageAction:
|
|
23
|
+
flagArr.push('ins');
|
|
24
|
+
break;
|
|
25
|
+
case FEATURE_NAMES.sessionTrace:
|
|
26
|
+
flagArr.push('stn');
|
|
27
|
+
break;
|
|
28
|
+
case FEATURE_NAMES.spa:
|
|
29
|
+
flagArr.push('spa');
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
} catch (e) {}
|
|
30
34
|
return flagArr;
|
|
31
35
|
}
|
|
32
36
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { handle } from '../../../common/event-emitter/handle';
|
|
2
|
-
import { isiOS } from '../../../common/
|
|
2
|
+
import { isiOS } from '../../../common/constants/runtime';
|
|
3
3
|
import { InstrumentBase } from '../../utils/instrument-base';
|
|
4
4
|
import * as CONSTANTS from '../constants';
|
|
5
5
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { onFCP, onFID, onLCP, onCLS, onINP } from 'web-vitals';
|
|
7
7
|
import { onFirstPaint } from '../first-paint';
|
|
8
8
|
import { onLongTask } from '../long-tasks';
|
|
9
|
-
import { iOS_below16 } from '../../../common/
|
|
9
|
+
import { iOS_below16 } from '../../../common/constants/runtime';
|
|
10
10
|
import { nullable, numeric, getAddStringContext, addCustomAttributes } from '../../../common/serialize/bel-serializer';
|
|
11
11
|
import { mapOwn } from '../../../common/util/map-own';
|
|
12
12
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
@@ -232,9 +232,7 @@ export class Aggregate extends AggregateBase {
|
|
|
232
232
|
}
|
|
233
233
|
onHarvestFinished(result) {
|
|
234
234
|
if (result.retry && this.timingsSent.length > 0) {
|
|
235
|
-
|
|
236
|
-
this.timings.push(this.timingsSent[i]);
|
|
237
|
-
}
|
|
235
|
+
this.timings.unshift(...this.timingsSent);
|
|
238
236
|
this.timingsSent = [];
|
|
239
237
|
}
|
|
240
238
|
}
|
|
@@ -9,7 +9,7 @@ import { windowAddEventListener } from '../../../common/event-listener/event-lis
|
|
|
9
9
|
import { now } from '../../../common/timing/now';
|
|
10
10
|
import { InstrumentBase } from '../../utils/instrument-base';
|
|
11
11
|
import { FEATURE_NAME } from '../constants';
|
|
12
|
-
import { isBrowserScope } from '../../../common/
|
|
12
|
+
import { isBrowserScope } from '../../../common/constants/runtime';
|
|
13
13
|
export class Instrument extends InstrumentBase {
|
|
14
14
|
static featureName = FEATURE_NAME;
|
|
15
15
|
constructor(agentIdentifier, aggregator) {
|
|
@@ -19,6 +19,7 @@ import { getConfigurationValue, getInfo, getRuntime } from '../../../common/conf
|
|
|
19
19
|
import { SESSION_EVENTS, MODE } from '../../../common/session/session-entity';
|
|
20
20
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
21
21
|
import { sharedChannel } from '../../../common/constants/shared-channel';
|
|
22
|
+
import { obj as encodeObj } from '../../../common/url/encode';
|
|
22
23
|
|
|
23
24
|
// would be better to get this dynamically in some way
|
|
24
25
|
export const RRWEB_VERSION = '2.0.0-alpha.8';
|
|
@@ -29,8 +30,12 @@ let recorder, gzipper, u8;
|
|
|
29
30
|
export const MAX_PAYLOAD_SIZE = 1000000;
|
|
30
31
|
/** Unloading caps around 64kb */
|
|
31
32
|
export const IDEAL_PAYLOAD_SIZE = 64000;
|
|
32
|
-
/** Interval between forcing new full snapshots in
|
|
33
|
-
const CHECKOUT_MS =
|
|
33
|
+
/** Interval between forcing new full snapshots -- 30 seconds in error mode, 5 minutes in full mode */
|
|
34
|
+
const CHECKOUT_MS = {
|
|
35
|
+
[MODE.ERROR]: 30000,
|
|
36
|
+
[MODE.FULL]: 300000,
|
|
37
|
+
[MODE.OFF]: 0
|
|
38
|
+
};
|
|
34
39
|
export class Aggregate extends AggregateBase {
|
|
35
40
|
static featureName = FEATURE_NAME;
|
|
36
41
|
constructor(agentIdentifier, aggregator) {
|
|
@@ -62,6 +67,12 @@ export class Aggregate extends AggregateBase {
|
|
|
62
67
|
/** Payload metadata -- Should indicate that the payload being sent contains an error. Used for query/filter purposes in UI */
|
|
63
68
|
this.hasError = false;
|
|
64
69
|
|
|
70
|
+
/** Payload metadata -- Should indicate when a replay blob started recording. Resets each time a harvest occurs. */
|
|
71
|
+
this.timestamp = {
|
|
72
|
+
first: undefined,
|
|
73
|
+
last: undefined
|
|
74
|
+
};
|
|
75
|
+
|
|
65
76
|
/** A value which increments with every new mutation node reported. Resets after a harvest is sent */
|
|
66
77
|
this.payloadBytesEstimation = 0;
|
|
67
78
|
const shouldSetup = getConfigurationValue(agentIdentifier, 'privacy.cookies_enabled') === true && getConfigurationValue(agentIdentifier, 'session_trace.enabled') === true;
|
|
@@ -85,7 +96,7 @@ export class Aggregate extends AggregateBase {
|
|
|
85
96
|
});
|
|
86
97
|
|
|
87
98
|
// Bespoke logic for new endpoint. This will change as downstream dependencies become solidified.
|
|
88
|
-
this.scheduler = new HarvestScheduler('
|
|
99
|
+
this.scheduler = new HarvestScheduler('browser/blobs', {
|
|
89
100
|
onFinished: this.onHarvestFinished.bind(this),
|
|
90
101
|
retryDelay: this.harvestTimeSeconds,
|
|
91
102
|
getPayload: this.prepareHarvest.bind(this),
|
|
@@ -105,10 +116,9 @@ export class Aggregate extends AggregateBase {
|
|
|
105
116
|
this.stopRecording();
|
|
106
117
|
this.startRecording();
|
|
107
118
|
this.scheduler.startTimer(this.harvestTimeSeconds);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
session.state.sessionReplay = this.mode;
|
|
119
|
+
this.syncWithSessionManager({
|
|
120
|
+
sessionReplay: this.mode
|
|
121
|
+
});
|
|
112
122
|
}
|
|
113
123
|
}
|
|
114
124
|
}, this.featureName, this.ee);
|
|
@@ -181,17 +191,18 @@ export class Aggregate extends AggregateBase {
|
|
|
181
191
|
}
|
|
182
192
|
this.startRecording();
|
|
183
193
|
this.isFirstChunk = !!session.isNew;
|
|
184
|
-
|
|
194
|
+
this.syncWithSessionManager({
|
|
195
|
+
sessionReplay: this.mode
|
|
196
|
+
});
|
|
185
197
|
}
|
|
186
198
|
prepareHarvest() {
|
|
187
|
-
if (this.events.length === 0) return;
|
|
199
|
+
if (this.events.length === 0 || this.mode !== MODE.FULL && !this.blocked) return;
|
|
188
200
|
const payload = this.getHarvestContents();
|
|
189
201
|
if (this.shouldCompress) {
|
|
190
202
|
payload.body = gzipper(u8(stringify(payload.body)));
|
|
191
203
|
this.scheduler.opts.gzip = true;
|
|
192
204
|
} else {
|
|
193
205
|
this.scheduler.opts.gzip = false;
|
|
194
|
-
delete payload.qs.content_encoding;
|
|
195
206
|
}
|
|
196
207
|
// TODO -- Gracefully handle the buffer for retries.
|
|
197
208
|
this.clearBuffer();
|
|
@@ -202,25 +213,28 @@ export class Aggregate extends AggregateBase {
|
|
|
202
213
|
const info = getInfo(this.agentIdentifier);
|
|
203
214
|
return {
|
|
204
215
|
qs: {
|
|
205
|
-
|
|
206
|
-
content_encoding: 'gzip',
|
|
207
|
-
browser_monitoring_key: info.licenseKey
|
|
208
|
-
},
|
|
209
|
-
body: {
|
|
216
|
+
browser_monitoring_key: info.licenseKey,
|
|
210
217
|
type: 'SessionReplay',
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
218
|
+
app_id: info.applicationID,
|
|
219
|
+
protocol_version: '0',
|
|
220
|
+
attributes: encodeObj({
|
|
221
|
+
...(this.shouldCompress && {
|
|
222
|
+
content_encoding: 'gzip'
|
|
223
|
+
}),
|
|
224
|
+
'replay.firstTimestamp': this.timestamp.first,
|
|
225
|
+
'replay.lastTimestamp': this.timestamp.last,
|
|
226
|
+
'replay.durationMs': this.timestamp.last - this.timestamp.first,
|
|
227
|
+
agentVersion: agentRuntime.version,
|
|
216
228
|
session: agentRuntime.session.state.value,
|
|
217
229
|
hasSnapshot: this.hasSnapshot,
|
|
218
230
|
hasError: this.hasError,
|
|
219
|
-
agentVersion: agentRuntime.version,
|
|
220
231
|
isFirstChunk: this.isFirstChunk,
|
|
232
|
+
decompressedBytes: this.payloadBytesEstimation,
|
|
221
233
|
'nr.rrweb.version': RRWEB_VERSION
|
|
222
|
-
}
|
|
223
|
-
}
|
|
234
|
+
}, MAX_PAYLOAD_SIZE - this.payloadBytesEstimation).substring(1) // remove the leading '&'
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
body: this.events
|
|
224
238
|
};
|
|
225
239
|
}
|
|
226
240
|
onHarvestFinished(result) {
|
|
@@ -238,6 +252,7 @@ export class Aggregate extends AggregateBase {
|
|
|
238
252
|
this.hasSnapshot = false;
|
|
239
253
|
this.hasError = false;
|
|
240
254
|
this.payloadBytesEstimation = 0;
|
|
255
|
+
this.clearTimestamps();
|
|
241
256
|
}
|
|
242
257
|
|
|
243
258
|
/** Begin recording using configured recording lib */
|
|
@@ -246,6 +261,7 @@ export class Aggregate extends AggregateBase {
|
|
|
246
261
|
warn('Recording library was never imported');
|
|
247
262
|
return this.abort();
|
|
248
263
|
}
|
|
264
|
+
this.recording = true;
|
|
249
265
|
const {
|
|
250
266
|
blockClass,
|
|
251
267
|
ignoreClass,
|
|
@@ -255,7 +271,6 @@ export class Aggregate extends AggregateBase {
|
|
|
255
271
|
maskTextSelector,
|
|
256
272
|
maskAllInputs
|
|
257
273
|
} = getConfigurationValue(this.agentIdentifier, 'session_replay');
|
|
258
|
-
this.hasSnapshot = true;
|
|
259
274
|
// set up rrweb configurations for maximum privacy --
|
|
260
275
|
// https://newrelic.atlassian.net/wiki/spaces/O11Y/pages/2792293280/2023+02+28+Browser+-+Session+Replay#Configuration-options
|
|
261
276
|
const stop = recorder({
|
|
@@ -267,11 +282,8 @@ export class Aggregate extends AggregateBase {
|
|
|
267
282
|
maskInputOptions,
|
|
268
283
|
maskTextSelector,
|
|
269
284
|
maskAllInputs,
|
|
270
|
-
|
|
271
|
-
checkoutEveryNms: CHECKOUT_MS
|
|
272
|
-
})
|
|
285
|
+
checkoutEveryNms: CHECKOUT_MS[this.mode]
|
|
273
286
|
});
|
|
274
|
-
this.recording = true;
|
|
275
287
|
this.stopRecording = () => {
|
|
276
288
|
this.recording = false;
|
|
277
289
|
stop();
|
|
@@ -296,12 +308,14 @@ export class Aggregate extends AggregateBase {
|
|
|
296
308
|
// we are still waiting for an error to throw, so keep wiping the buffer over time
|
|
297
309
|
this.clearBuffer();
|
|
298
310
|
}
|
|
311
|
+
this.setTimestamps(event);
|
|
312
|
+
if (event.type === 2) this.hasSnapshot = true;
|
|
299
313
|
this.events.push(event);
|
|
300
314
|
this.payloadBytesEstimation += eventBytes;
|
|
301
315
|
|
|
302
316
|
// We are making an effort to try to keep payloads manageable for unloading. If they reach the unload limit before their interval,
|
|
303
317
|
// it will send immediately. This often happens on the first snapshot, which can be significantly larger than the other payloads.
|
|
304
|
-
if (payloadSize > IDEAL_PAYLOAD_SIZE) {
|
|
318
|
+
if (payloadSize > IDEAL_PAYLOAD_SIZE && this.mode !== MODE.ERROR) {
|
|
305
319
|
// if we've made it to the ideal size of ~64kb before the interval timer, we should send early.
|
|
306
320
|
this.scheduler.runHarvest();
|
|
307
321
|
}
|
|
@@ -311,7 +325,17 @@ export class Aggregate extends AggregateBase {
|
|
|
311
325
|
takeFullSnapshot() {
|
|
312
326
|
if (!recorder) return;
|
|
313
327
|
recorder.takeFullSnapshot();
|
|
314
|
-
|
|
328
|
+
}
|
|
329
|
+
setTimestamps(rrwebEvent) {
|
|
330
|
+
if (!rrwebEvent) return;
|
|
331
|
+
if (!this.timestamp.first) this.timestamp.first = rrwebEvent.timestamp;
|
|
332
|
+
this.timestamp.last = rrwebEvent.timestamp;
|
|
333
|
+
}
|
|
334
|
+
clearTimestamps() {
|
|
335
|
+
this.timestamp = {
|
|
336
|
+
first: undefined,
|
|
337
|
+
last: undefined
|
|
338
|
+
};
|
|
315
339
|
}
|
|
316
340
|
|
|
317
341
|
/** Estimate the payload size */
|
|
@@ -326,11 +350,11 @@ export class Aggregate extends AggregateBase {
|
|
|
326
350
|
this.blocked = true;
|
|
327
351
|
this.mode = MODE.OFF;
|
|
328
352
|
this.stopRecording();
|
|
353
|
+
this.syncWithSessionManager({
|
|
354
|
+
sessionReplay: this.mode
|
|
355
|
+
});
|
|
356
|
+
this.clearTimestamps();
|
|
329
357
|
this.ee.emit('REPLAY_ABORTED');
|
|
330
|
-
const {
|
|
331
|
-
session
|
|
332
|
-
} = getRuntime(this.agentIdentifier);
|
|
333
|
-
session.state.sessionReplay = this.mode;
|
|
334
358
|
}
|
|
335
359
|
|
|
336
360
|
/** Extensive research has yielded about an 88% compression factor on these payloads.
|
|
@@ -341,4 +365,11 @@ export class Aggregate extends AggregateBase {
|
|
|
341
365
|
if (this.shouldCompress) return data * AVG_COMPRESSION;
|
|
342
366
|
return data;
|
|
343
367
|
}
|
|
368
|
+
syncWithSessionManager() {
|
|
369
|
+
let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
370
|
+
const {
|
|
371
|
+
session
|
|
372
|
+
} = getRuntime(this.agentIdentifier);
|
|
373
|
+
session.write(state);
|
|
374
|
+
}
|
|
344
375
|
}
|
|
@@ -15,8 +15,8 @@ export async function getSessionReplayMode(agentId) {
|
|
|
15
15
|
const newrelic = gosNREUM();
|
|
16
16
|
// Should be enabled by configuration and using an agent build that includes it (via checking that the instrument class was initialized).
|
|
17
17
|
if (getConfigurationValue(agentId, 'session_replay.enabled') && typeof newrelic.initializedAgents[agentId].features.session_replay === 'object') {
|
|
18
|
-
await newrelic.initializedAgents[agentId].features.session_replay.onAggregateImported;
|
|
19
|
-
return await sharedChannel.sessionReplayInitialized; // wait for replay to determine which mode it's after running its sampling logic
|
|
18
|
+
const srInitialized = await newrelic.initializedAgents[agentId].features.session_replay.onAggregateImported;
|
|
19
|
+
if (srInitialized) return await sharedChannel.sessionReplayInitialized; // wait for replay to determine which mode it's after running its sampling logic
|
|
20
20
|
}
|
|
21
21
|
} catch (e) {/* exception ==> off */}
|
|
22
22
|
return MODE.OFF; // at any step of the way s.t. SR cannot be on by implication or is explicitly off
|
|
@@ -109,8 +109,8 @@ export class Aggregate extends AggregateBase {
|
|
|
109
109
|
sessionTraceMode: MODE.OFF
|
|
110
110
|
});
|
|
111
111
|
operationalGate.permanentlyDecide(false);
|
|
112
|
-
this.#scheduler?.stopTimer(true);
|
|
113
112
|
if (mostRecentModeKnown === MODE.FULL) this.#scheduler?.runHarvest(); // allow queued nodes (past opGate) to final harvest, unless they were buffered in other modes
|
|
113
|
+
this.#scheduler?.stopTimer(true); // the 'true' arg here will forcibly block any future call to runHarvest, so the last runHarvest above must be prior
|
|
114
114
|
this.#scheduler = null;
|
|
115
115
|
};
|
|
116
116
|
|
|
@@ -136,9 +136,8 @@ export class Aggregate extends AggregateBase {
|
|
|
136
136
|
this.ee.on(SESSION_EVENTS.PAUSE, () => mostRecentModeKnown = sessionEntity.state.sessionTraceMode);
|
|
137
137
|
if (!sessionEntity.isNew) {
|
|
138
138
|
// inherit the same mode as existing session's Trace
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
controlTraceOp(existingTraceMode);
|
|
139
|
+
if (sessionEntity.state.sessionReplay === MODE.OFF) this.isStandalone = true;
|
|
140
|
+
controlTraceOp(mostRecentModeKnown = sessionEntity.state.sessionTraceMode);
|
|
142
141
|
} else {
|
|
143
142
|
// for new sessions, see the truth table associated with NEWRELIC-8662 wrt the new Trace behavior under session management
|
|
144
143
|
const replayMode = await getSessionReplayMode(agentIdentifier);
|
|
@@ -8,7 +8,7 @@ import { now } from '../../../common/timing/now';
|
|
|
8
8
|
import { InstrumentBase } from '../../utils/instrument-base';
|
|
9
9
|
import * as CONSTANTS from '../constants';
|
|
10
10
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
11
|
-
import { isBrowserScope } from '../../../common/
|
|
11
|
+
import { isBrowserScope } from '../../../common/constants/runtime';
|
|
12
12
|
const {
|
|
13
13
|
BST_RESOURCE,
|
|
14
14
|
RESOURCE,
|
|
@@ -619,7 +619,7 @@ export class Aggregate extends AggregateBase {
|
|
|
619
619
|
function onHarvestFinished(result) {
|
|
620
620
|
if (result.sent && result.retry && state.interactionsSent.length > 0) {
|
|
621
621
|
state.interactionsSent.forEach(function (interaction) {
|
|
622
|
-
state.interactionsToHarvest.
|
|
622
|
+
state.interactionsToHarvest.unshift(interaction);
|
|
623
623
|
});
|
|
624
624
|
state.interactionsSent = [];
|
|
625
625
|
}
|
|
@@ -8,7 +8,7 @@ import { InstrumentBase } from '../../utils/instrument-base';
|
|
|
8
8
|
import { getRuntime } from '../../../common/config/config';
|
|
9
9
|
import { now } from '../../../common/timing/now';
|
|
10
10
|
import * as CONSTANTS from '../constants';
|
|
11
|
-
import { isBrowserScope } from '../../../common/
|
|
11
|
+
import { isBrowserScope } from '../../../common/constants/runtime';
|
|
12
12
|
const {
|
|
13
13
|
FEATURE_NAME,
|
|
14
14
|
START,
|