@newrelic/browser-agent 1.234.0 → 1.236.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 +42 -2
- package/dist/cjs/common/config/state/init.js +3 -0
- package/dist/cjs/common/config/state/runtime.js +4 -4
- 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/constants/shared-channel.js +19 -0
- package/dist/cjs/common/event-listener/event-listener-opts.js +3 -3
- package/dist/cjs/common/harvest/harvest-scheduler.js +35 -16
- package/dist/cjs/common/harvest/harvest.js +163 -144
- 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 +21 -13
- package/dist/cjs/common/timer/interaction-timer.js +3 -3
- 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/feature-flags.js +23 -12
- package/dist/cjs/common/util/obfuscate.js +2 -2
- package/dist/cjs/common/util/submit-data.js +61 -79
- 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 +2 -2
- 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 +3 -3
- package/dist/cjs/common/wrap/wrap-timer.js +5 -5
- package/dist/cjs/common/wrap/wrap-xhr.js +3 -3
- package/dist/cjs/features/ajax/aggregate/index.js +1 -1
- 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/index.js +11 -4
- package/dist/cjs/features/jserrors/instrument/index.js +6 -19
- 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/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 +99 -82
- package/dist/cjs/features/session_replay/replay-mode.js +28 -0
- package/dist/cjs/features/session_trace/aggregate/index.js +222 -99
- package/dist/cjs/features/session_trace/constants.js +1 -3
- package/dist/cjs/features/session_trace/instrument/index.js +2 -18
- package/dist/cjs/features/spa/aggregate/index.js +1 -1
- package/dist/cjs/features/spa/constants.js +0 -1
- package/dist/cjs/features/spa/instrument/index.js +2 -2
- package/dist/cjs/features/utils/agent-session.js +20 -36
- package/dist/cjs/features/utils/aggregate-base.js +7 -12
- package/dist/cjs/features/utils/handler-cache.js +28 -23
- package/dist/cjs/features/utils/instrument-base.js +58 -40
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/loaders/agent.js +7 -1
- package/dist/cjs/loaders/api/api.js +2 -2
- package/dist/cjs/loaders/api/apiAsync.js +6 -4
- package/dist/cjs/loaders/configure/configure.js +2 -2
- package/dist/cjs/loaders/features/featureDependencies.js +2 -0
- package/dist/cjs/loaders/micro-agent.js +29 -38
- package/dist/esm/common/config/state/init.js +3 -0
- package/dist/esm/common/config/state/runtime.js +1 -1
- 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/constants/shared-channel.js +12 -0
- package/dist/esm/common/event-listener/event-listener-opts.js +1 -1
- package/dist/esm/common/harvest/harvest-scheduler.js +34 -17
- package/dist/esm/common/harvest/harvest.js +160 -142
- 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 +18 -12
- package/dist/esm/common/timer/interaction-timer.js +2 -2
- 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/feature-flags.js +23 -12
- package/dist/esm/common/util/obfuscate.js +2 -2
- package/dist/esm/common/util/submit-data.js +58 -76
- 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 +1 -1
- 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 +2 -2
- package/dist/esm/common/wrap/wrap-timer.js +2 -2
- package/dist/esm/common/wrap/wrap-xhr.js +1 -1
- package/dist/esm/features/ajax/aggregate/index.js +1 -1
- 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/index.js +10 -3
- package/dist/esm/features/jserrors/instrument/index.js +3 -16
- 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/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 +92 -78
- package/dist/esm/features/session_replay/replay-mode.js +23 -0
- package/dist/esm/features/session_trace/aggregate/index.js +223 -100
- package/dist/esm/features/session_trace/constants.js +0 -1
- package/dist/esm/features/session_trace/instrument/index.js +2 -18
- package/dist/esm/features/spa/aggregate/index.js +1 -1
- package/dist/esm/features/spa/constants.js +0 -1
- package/dist/esm/features/spa/instrument/index.js +1 -1
- package/dist/esm/features/utils/agent-session.js +21 -37
- package/dist/esm/features/utils/aggregate-base.js +7 -12
- package/dist/esm/features/utils/handler-cache.js +28 -23
- package/dist/esm/features/utils/instrument-base.js +57 -39
- package/dist/esm/index.js +1 -4
- package/dist/esm/loaders/agent.js +7 -1
- package/dist/esm/loaders/api/api.js +2 -2
- package/dist/esm/loaders/api/apiAsync.js +3 -3
- package/dist/esm/loaders/configure/configure.js +1 -1
- package/dist/esm/loaders/features/featureDependencies.js +2 -0
- package/dist/esm/loaders/micro-agent.js +29 -38
- package/dist/types/common/config/state/init.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/constants/shared-channel.d.ts +5 -0
- package/dist/types/common/constants/shared-channel.d.ts.map +1 -0
- package/dist/types/common/harvest/harvest-scheduler.d.ts +5 -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 +9 -5
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/unload/eol.d.ts.map +1 -1
- package/dist/types/common/util/feature-flags.d.ts +1 -0
- package/dist/types/common/util/feature-flags.d.ts.map +1 -1
- package/dist/types/common/util/submit-data.d.ts +62 -64
- package/dist/types/common/util/submit-data.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 +2 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/instrument/index.d.ts +1 -1
- package/dist/types/features/jserrors/instrument/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 +14 -5
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/replay-mode.d.ts +9 -0
- package/dist/types/features/session_replay/replay-mode.d.ts.map +1 -0
- package/dist/types/features/session_trace/aggregate/index.d.ts +21 -3
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/constants.d.ts +0 -1
- package/dist/types/features/session_trace/constants.d.ts.map +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts +0 -2
- package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
- package/dist/types/features/spa/constants.d.ts.map +1 -1
- package/dist/types/features/utils/agent-session.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +6 -1
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/handler-cache.d.ts +12 -11
- package/dist/types/features/utils/handler-cache.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts +17 -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.d.ts +4 -4
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/features/featureDependencies.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent.d.ts +3 -4
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +14 -7
- package/src/common/config/__mocks__/config.js +11 -0
- package/src/common/config/state/init.js +1 -0
- package/src/common/config/state/runtime.js +1 -1
- 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/constants/shared-channel.js +13 -0
- package/src/common/context/__mocks__/shared-context.js +8 -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 +31 -19
- package/src/common/harvest/harvest-scheduler.test.js +491 -20
- package/src/common/harvest/harvest.js +147 -130
- package/src/common/harvest/harvest.test.js +788 -139
- 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.test.js → session-entity.component-test.js} +71 -48
- package/src/common/session/session-entity.js +16 -13
- package/src/common/timer/interaction-timer.js +2 -2
- 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 +32 -21
- 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 +6 -0
- package/src/common/util/__mocks__/traverse.js +1 -0
- package/src/common/util/data-size.test.js +27 -20
- package/src/common/util/feature-flags.js +24 -12
- package/src/common/util/feature-flags.test.js +98 -0
- package/src/common/util/obfuscate.component-test.js +173 -0
- package/src/common/util/obfuscate.js +2 -2
- package/src/common/util/submit-data.js +42 -56
- package/src/common/util/submit-data.test.js +158 -137
- 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 +1 -1
- 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 +2 -2
- package/src/common/wrap/wrap-timer.js +2 -2
- package/src/common/wrap/wrap-xhr.js +1 -1
- package/src/features/ajax/aggregate/index.js +1 -1
- 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.test.js +1 -1
- package/src/features/jserrors/aggregate/index.js +12 -3
- package/src/features/jserrors/instrument/index.js +3 -16
- 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/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 +368 -0
- package/src/features/session_replay/aggregate/index.js +96 -71
- package/src/features/session_replay/instrument/index.js +0 -1
- package/src/features/session_replay/replay-mode.js +23 -0
- package/src/features/session_trace/aggregate/index.js +198 -79
- package/src/features/session_trace/constants.js +0 -1
- package/src/features/session_trace/instrument/index.js +3 -20
- package/src/features/spa/aggregate/index.js +1 -1
- package/src/features/spa/constants.js +0 -1
- package/src/features/spa/instrument/index.js +1 -1
- package/src/features/utils/agent-session.js +22 -34
- package/src/features/utils/agent-session.test.js +194 -0
- package/src/features/utils/aggregate-base.js +12 -9
- package/src/features/utils/aggregate-base.test.js +122 -0
- package/src/features/utils/feature-base.test.js +45 -0
- package/src/features/utils/handler-cache.js +29 -23
- package/src/features/utils/handler-cache.test.js +72 -0
- package/src/features/utils/instrument-base.js +45 -29
- package/src/features/utils/instrument-base.test.js +209 -0
- package/src/features/utils/lazy-feature-loader.test.js +37 -0
- package/src/index.js +1 -3
- package/src/loaders/agent.js +8 -1
- package/src/loaders/api/api.js +2 -2
- package/src/loaders/api/apiAsync.js +3 -3
- package/src/loaders/configure/configure.js +1 -1
- package/src/loaders/features/featureDependencies.js +2 -0
- package/src/loaders/micro-agent.js +26 -30
- 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.test.js +0 -39
- package/dist/cjs/common/harvest/harvest.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.test.js +0 -460
- package/dist/cjs/common/storage/local-memory.js +0 -35
- package/dist/cjs/common/storage/local-memory.test.js +0 -20
- package/dist/cjs/common/storage/local-storage.test.js +0 -14
- package/dist/cjs/common/timer/interaction-timer.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 -42
- package/dist/cjs/common/url/clean-url.test.js +0 -9
- package/dist/cjs/common/url/encode.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.test.js +0 -15
- package/dist/cjs/common/util/console.test.js +0 -30
- package/dist/cjs/common/util/data-size.test.js +0 -47
- package/dist/cjs/common/util/get-or-set.test.js +0 -47
- package/dist/cjs/common/util/global-scope.js +0 -58
- 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/stringify.test.js +0 -48
- package/dist/cjs/common/util/submit-data.test.js +0 -221
- 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/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/spa/aggregate/interaction-node.test.js +0 -16
- 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.test.js +0 -37
- package/dist/esm/common/harvest/harvest.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.test.js +0 -458
- package/dist/esm/common/storage/local-memory.js +0 -28
- package/dist/esm/common/storage/local-memory.test.js +0 -18
- package/dist/esm/common/storage/local-storage.test.js +0 -12
- package/dist/esm/common/timer/interaction-timer.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 -38
- package/dist/esm/common/url/clean-url.test.js +0 -7
- package/dist/esm/common/url/encode.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.test.js +0 -13
- package/dist/esm/common/util/console.test.js +0 -28
- package/dist/esm/common/util/data-size.test.js +0 -45
- package/dist/esm/common/util/get-or-set.test.js +0 -45
- package/dist/esm/common/util/global-scope.js +0 -45
- 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/stringify.test.js +0 -46
- package/dist/esm/common/util/submit-data.test.js +0 -219
- 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/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/spa/aggregate/interaction-node.test.js +0 -14
- 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/storage/local-memory.d.ts +0 -8
- package/dist/types/common/storage/local-memory.d.ts.map +0 -1
- package/dist/types/common/util/global-scope.d.ts +0 -14
- package/dist/types/common/util/global-scope.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/storage/local-memory.js +0 -30
- package/src/common/storage/local-memory.test.js +0 -19
- package/src/common/util/global-scope.js +0 -49
- /package/src/common/timer/{interaction-timer.test.js → interaction-timer.component-test.js} +0 -0
- /package/src/common/url/{encode.test.js → encode.component-test.js} +0 -0
- /package/src/common/url/{protocol.test.js → protocol.component-test.js} +0 -0
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
6
6
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
7
|
-
import { stringify } from '../../../common/util/stringify';
|
|
8
7
|
import { parseUrl } from '../../../common/url/parse-url';
|
|
9
|
-
import { getConfigurationValue,
|
|
8
|
+
import { getConfigurationValue, getRuntime } from '../../../common/config/config';
|
|
10
9
|
import { now } from '../../../common/timing/now';
|
|
11
10
|
import { FEATURE_NAME } from '../constants';
|
|
12
11
|
import { drain } from '../../../common/drain/drain';
|
|
13
12
|
import { HandlerCache } from '../../utils/handler-cache';
|
|
13
|
+
import { MODE, SESSION_EVENTS } from '../../../common/session/session-entity';
|
|
14
|
+
import { getSessionReplayMode } from '../../session_replay/replay-mode';
|
|
14
15
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
15
16
|
const ignoredEvents = {
|
|
16
17
|
// we find that certain events make the data too noisy to be useful
|
|
@@ -34,16 +35,21 @@ const toAggregate = {
|
|
|
34
35
|
mousing: [1000, 2000],
|
|
35
36
|
touching: [1000, 2000]
|
|
36
37
|
};
|
|
37
|
-
const MAX_TRACE_DURATION =
|
|
38
|
+
const MAX_TRACE_DURATION = 10 * 60 * 1000; // 10 minutes
|
|
39
|
+
const REQ_THRESHOLD_TO_SEND = 30;
|
|
40
|
+
const ERROR_MODE_SECONDS_WINDOW = 30 * 1000; // sliding window of nodes to track when simply monitoring (but not harvesting) in error mode
|
|
38
41
|
|
|
39
42
|
export class Aggregate extends AggregateBase {
|
|
40
43
|
static featureName = FEATURE_NAME;
|
|
44
|
+
#scheduler;
|
|
41
45
|
constructor(agentIdentifier, aggregator, argsObj) {
|
|
42
46
|
var _this;
|
|
43
|
-
// Very unlikely, but in case the existing XMLHttpRequest.prototype object on the page couldn't be wrapped.
|
|
44
47
|
super(agentIdentifier, aggregator, FEATURE_NAME);
|
|
45
48
|
_this = this;
|
|
46
|
-
|
|
49
|
+
this.agentRuntime = getRuntime(agentIdentifier);
|
|
50
|
+
|
|
51
|
+
// Very unlikely, but in case the existing XMLHttpRequest.prototype object on the page couldn't be wrapped.
|
|
52
|
+
if (!this.agentRuntime.xhrWrappable) return;
|
|
47
53
|
this.resourceObserver = argsObj?.resourceObserver; // undefined if observer couldn't be created
|
|
48
54
|
this.ptid = '';
|
|
49
55
|
this.trace = {};
|
|
@@ -51,105 +57,217 @@ export class Aggregate extends AggregateBase {
|
|
|
51
57
|
this.sentTrace = null;
|
|
52
58
|
this.harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'session_trace.harvestTimeSeconds') || 10;
|
|
53
59
|
this.maxNodesPerHarvest = getConfigurationValue(agentIdentifier, 'session_trace.maxNodesPerHarvest') || 1000;
|
|
54
|
-
this.
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
this.isStandalone = false;
|
|
61
|
+
const operationalGate = new HandlerCache(); // acts as a controller-intermediary that can enable or disable this feature's collection dynamically
|
|
62
|
+
const sessionEntity = this.agentRuntime.session;
|
|
63
|
+
|
|
64
|
+
/* --- The following section deals with user sessions concept & contains non-trivial control flow. --- */
|
|
65
|
+
const controlTraceOp = traceMode => {
|
|
66
|
+
switch (traceMode) {
|
|
67
|
+
case MODE.ERROR:
|
|
68
|
+
this.startTracing(operationalGate, true);
|
|
69
|
+
break;
|
|
70
|
+
case MODE.FULL:
|
|
71
|
+
case true:
|
|
72
|
+
this.startTracing(operationalGate);
|
|
73
|
+
break;
|
|
74
|
+
case MODE.OFF:
|
|
75
|
+
case false:
|
|
76
|
+
default:
|
|
77
|
+
// this feature becomes "off" (does nothing & nothing is sent)
|
|
78
|
+
operationalGate.decide(false);
|
|
79
|
+
break;
|
|
61
80
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
};
|
|
82
|
+
if (!sessionEntity) {
|
|
83
|
+
// Since session manager isn't around, do the old Trace behavior of waiting for RUM response to decide feature activation.
|
|
84
|
+
this.isStandalone = true;
|
|
85
|
+
registerHandler('rumresp-stn', on => controlTraceOp(on), this.featureName, this.ee);
|
|
86
|
+
} else {
|
|
87
|
+
let seenAnError = false;
|
|
88
|
+
let mostRecentModeKnown;
|
|
89
|
+
registerHandler('errorAgg', () => {
|
|
90
|
+
// Switch to full capture mode on next harvest on first exception thrown only. Only done once so that sessionTraceMode isn't constantly overwritten after decision block.
|
|
91
|
+
if (!seenAnError) {
|
|
92
|
+
seenAnError = true;
|
|
93
|
+
/* If this cb executes before Trace has started, then no further action needed. But if...
|
|
94
|
+
- startTracing already ran under ERROR mode, then it will NOT have kicked off the harvest-scheduler so that needs to be done & switch mode.
|
|
95
|
+
- startTracing never ran because mode is OFF or Replay aborted or Traced turned off elsewhere OR trace already in FULL, then this should do nothing. */
|
|
96
|
+
if (sessionEntity.state.sessionTraceMode === MODE.ERROR && this.#scheduler) {
|
|
97
|
+
sessionEntity.write({
|
|
98
|
+
sessionTraceMode: mostRecentModeKnown = MODE.FULL
|
|
99
|
+
});
|
|
100
|
+
this.trimSTNs(ERROR_MODE_SECONDS_WINDOW); // up until now, Trace would've been just buffering nodes up to max, which needs to be trimmed to last X seconds
|
|
101
|
+
this.#scheduler.runHarvest({
|
|
102
|
+
needResponse: true
|
|
103
|
+
});
|
|
104
|
+
}
|
|
76
105
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
106
|
+
}, this.featureName, this.ee);
|
|
107
|
+
const stopTracePerm = () => {
|
|
108
|
+
if (sessionEntity.state.sessionTraceMode !== MODE.OFF) sessionEntity.write({
|
|
109
|
+
sessionTraceMode: MODE.OFF
|
|
110
|
+
});
|
|
111
|
+
operationalGate.permanentlyDecide(false);
|
|
112
|
+
this.#scheduler?.stopTimer(true);
|
|
113
|
+
if (mostRecentModeKnown === MODE.FULL) this.#scheduler?.runHarvest(); // allow queued nodes (past opGate) to final harvest, unless they were buffered in other modes
|
|
114
|
+
this.#scheduler = null;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// CAUTION: everything inside this promise runs post-load; event subscribers must be pre-load aka synchronous with constructor
|
|
118
|
+
this.waitForFlags(['stn', 'sr']).then(async _ref => {
|
|
119
|
+
let [traceOn, replayOn] = _ref;
|
|
120
|
+
if (!replayOn) {
|
|
121
|
+
// When sr = 0 from BCS, also do the old Trace behavior:
|
|
122
|
+
this.isStandalone = true;
|
|
123
|
+
controlTraceOp(traceOn);
|
|
124
|
+
} else {
|
|
125
|
+
this.ee.on('REPLAY_ABORTED', () => stopTracePerm());
|
|
126
|
+
/* Assuming on page visible that the trace mode is updated from shared session,
|
|
127
|
+
- if trace is turned off from the other page, it should be likewise here.
|
|
128
|
+
- if trace switches to Full mode, harvest should start (prev: Error) if not already running (prev: Full). */
|
|
129
|
+
this.ee.on(SESSION_EVENTS.RESUME, () => {
|
|
130
|
+
const updatedTraceMode = sessionEntity.state.sessionTraceMode;
|
|
131
|
+
if (updatedTraceMode === MODE.OFF) stopTracePerm();else if (updatedTraceMode === MODE.FULL && this.#scheduler && !this.#scheduler.started) this.#scheduler.runHarvest({
|
|
132
|
+
needResponse: true
|
|
133
|
+
});
|
|
134
|
+
mostRecentModeKnown = updatedTraceMode;
|
|
84
135
|
});
|
|
85
|
-
this.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
136
|
+
this.ee.on(SESSION_EVENTS.PAUSE, () => mostRecentModeKnown = sessionEntity.state.sessionTraceMode);
|
|
137
|
+
if (!sessionEntity.isNew) {
|
|
138
|
+
// inherit the same mode as existing session's Trace
|
|
139
|
+
const existingTraceMode = mostRecentModeKnown = sessionEntity.state.sessionTraceMode;
|
|
140
|
+
if (existingTraceMode === MODE.OFF) this.isStandalone = true;
|
|
141
|
+
controlTraceOp(existingTraceMode);
|
|
142
|
+
} else {
|
|
143
|
+
// for new sessions, see the truth table associated with NEWRELIC-8662 wrt the new Trace behavior under session management
|
|
144
|
+
const replayMode = await getSessionReplayMode(agentIdentifier);
|
|
145
|
+
if (replayMode === MODE.OFF) this.isStandalone = true; // without SR, Traces are still subject to old harvest limits
|
|
146
|
+
|
|
147
|
+
let startingMode;
|
|
148
|
+
if (traceOn === true) {
|
|
149
|
+
// CASE: both trace (entitlement+sampling) & replay (entitlement) flags are true from RUM
|
|
150
|
+
startingMode = MODE.FULL; // always full capture regardless of replay sampling decisions
|
|
151
|
+
} else {
|
|
152
|
+
// CASE: trace flag is off, BUT it must still run if replay is on (possibly)
|
|
153
|
+
// At this point, it's possible that 1 or more exception was thrown, in which case just start in full if Replay originally started in ERROR mode.
|
|
154
|
+
if (replayMode === MODE.ERROR && seenAnError) startingMode = MODE.FULL;else startingMode = replayMode;
|
|
155
|
+
}
|
|
156
|
+
sessionEntity.write({
|
|
157
|
+
sessionTraceMode: mostRecentModeKnown = startingMode
|
|
158
|
+
});
|
|
159
|
+
controlTraceOp(startingMode);
|
|
160
|
+
}
|
|
94
161
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
}, this.featureName, this.ee);
|
|
100
|
-
registerHandler('block-stn', () => handlerCache.decide(false), this.featureName, this.ee);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/* --- EoS --- */
|
|
101
165
|
|
|
102
166
|
// register the handlers immediately... but let the handlerCache decide if the data should actually get stored...
|
|
103
167
|
registerHandler('bst', function () {
|
|
104
168
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
105
169
|
args[_key] = arguments[_key];
|
|
106
170
|
}
|
|
107
|
-
return
|
|
171
|
+
return operationalGate.settle(() => _this.storeEvent(...args));
|
|
108
172
|
}, this.featureName, this.ee);
|
|
109
|
-
registerHandler('
|
|
173
|
+
registerHandler('bstResource', function () {
|
|
110
174
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
111
175
|
args[_key2] = arguments[_key2];
|
|
112
176
|
}
|
|
113
|
-
return
|
|
177
|
+
return operationalGate.settle(() => _this.storeResources(...args));
|
|
114
178
|
}, this.featureName, this.ee);
|
|
115
|
-
registerHandler('
|
|
179
|
+
registerHandler('bstHist', function () {
|
|
116
180
|
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
117
181
|
args[_key3] = arguments[_key3];
|
|
118
182
|
}
|
|
119
|
-
return
|
|
183
|
+
return operationalGate.settle(() => _this.storeHist(...args));
|
|
120
184
|
}, this.featureName, this.ee);
|
|
121
|
-
registerHandler('
|
|
185
|
+
registerHandler('bstXhrAgg', function () {
|
|
122
186
|
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
123
187
|
args[_key4] = arguments[_key4];
|
|
124
188
|
}
|
|
125
|
-
return
|
|
189
|
+
return operationalGate.settle(() => _this.storeXhrAgg(...args));
|
|
126
190
|
}, this.featureName, this.ee);
|
|
127
|
-
registerHandler('
|
|
191
|
+
registerHandler('bstApi', function () {
|
|
128
192
|
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
|
|
129
193
|
args[_key5] = arguments[_key5];
|
|
130
194
|
}
|
|
131
|
-
return
|
|
195
|
+
return operationalGate.settle(() => _this.storeSTN(...args));
|
|
132
196
|
}, this.featureName, this.ee);
|
|
133
|
-
registerHandler('
|
|
197
|
+
registerHandler('errorAgg', function () {
|
|
134
198
|
for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
|
|
135
199
|
args[_key6] = arguments[_key6];
|
|
136
200
|
}
|
|
137
|
-
return
|
|
201
|
+
return operationalGate.settle(() => _this.storeErrorAgg(...args));
|
|
138
202
|
}, this.featureName, this.ee);
|
|
139
|
-
registerHandler('
|
|
203
|
+
registerHandler('pvtAdded', function () {
|
|
140
204
|
for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
|
|
141
205
|
args[_key7] = arguments[_key7];
|
|
142
206
|
}
|
|
143
|
-
return
|
|
144
|
-
}, this.featureName, this.ee);
|
|
145
|
-
registerHandler('pvtAdded', function () {
|
|
146
|
-
for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
|
|
147
|
-
args[_key8] = arguments[_key8];
|
|
148
|
-
}
|
|
149
|
-
return handlerCache.settle(() => _this.processPVT(...args));
|
|
207
|
+
return operationalGate.settle(() => _this.processPVT(...args));
|
|
150
208
|
}, this.featureName, this.ee);
|
|
151
209
|
drain(this.agentIdentifier, this.featureName);
|
|
152
210
|
}
|
|
211
|
+
startTracing(startupBuffer) {
|
|
212
|
+
let dontStartHarvestYet = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
213
|
+
if (typeof PerformanceNavigationTiming !== 'undefined') {
|
|
214
|
+
this.storeTiming(window.performance.getEntriesByType('navigation')[0]);
|
|
215
|
+
} else {
|
|
216
|
+
this.storeTiming(window.performance.timing);
|
|
217
|
+
}
|
|
218
|
+
this.#scheduler = new HarvestScheduler('resources', {
|
|
219
|
+
onFinished: this.#onHarvestFinished.bind(this),
|
|
220
|
+
retryDelay: this.harvestTimeSeconds
|
|
221
|
+
}, this);
|
|
222
|
+
this.#scheduler.harvest.on('resources', this.#prepareHarvest.bind(this));
|
|
223
|
+
if (dontStartHarvestYet === false) this.#scheduler.runHarvest({
|
|
224
|
+
needResponse: true
|
|
225
|
+
}); // sends first stn harvest immediately
|
|
226
|
+
startupBuffer.decide(true); // signal to ALLOW & process data in EE's buffer into internal nodes queued for next harvest
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
#onHarvestFinished(result) {
|
|
230
|
+
if (result.sent && result.responseText && !this.ptid) {
|
|
231
|
+
// continue interval harvest only if ptid was returned by server on the first
|
|
232
|
+
this.agentRuntime.ptid = this.ptid = result.responseText;
|
|
233
|
+
this.#scheduler.startTimer(this.harvestTimeSeconds);
|
|
234
|
+
}
|
|
235
|
+
if (result.sent && result.retry && this.sentTrace) {
|
|
236
|
+
// merge previous trace back into buffer to retry for next harvest
|
|
237
|
+
Object.entries(this.sentTrace).forEach(_ref2 => {
|
|
238
|
+
let [name, listOfSTNodes] = _ref2;
|
|
239
|
+
if (this.nodeCount >= this.maxNodesPerHarvest) return;
|
|
240
|
+
this.nodeCount += listOfSTNodes.length;
|
|
241
|
+
this.trace[name] = this.trace[name] ? listOfSTNodes.concat(this.trace[name]) : listOfSTNodes;
|
|
242
|
+
});
|
|
243
|
+
this.sentTrace = null;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
#prepareHarvest(options) {
|
|
247
|
+
/* Standalone refers to the legacy version of ST before the idea of 'session' or the Replay feature existed.
|
|
248
|
+
It has a different behavior on returning a payload for harvest than when used in tandem with either of those concepts. */
|
|
249
|
+
if (this.isStandalone) {
|
|
250
|
+
if (now() > MAX_TRACE_DURATION) {
|
|
251
|
+
// been collecting for over the longest duration we should run for, empty trace object so ST has nothing to send
|
|
252
|
+
this.#scheduler.stopTimer();
|
|
253
|
+
this.trace = {};
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
// Only harvest when more than some threshold of nodes are pending, after the very first harvest.
|
|
257
|
+
if (this.ptid && this.nodeCount <= REQ_THRESHOLD_TO_SEND) return;
|
|
258
|
+
} else {
|
|
259
|
+
// -- *cli May '26 - Update: Not rate limiting backgrounded pages either for now.
|
|
260
|
+
// if (this.ptid && document.visibilityState === 'hidden' && this.nodeCount <= REQ_THRESHOLD_TO_SEND) return
|
|
261
|
+
|
|
262
|
+
const currentMode = this.agentRuntime.session.state.sessionTraceMode;
|
|
263
|
+
/* There could still be nodes previously collected even after Trace (w/ session mgmt) is turned off. Hence, continue to send the last batch.
|
|
264
|
+
* The intermediary controller SHOULD be already switched off so that no nodes are further queued. */
|
|
265
|
+
if (currentMode === MODE.OFF && Object.keys(this.trace).length === 0) return;
|
|
266
|
+
if (currentMode === MODE.ERROR) return; // Trace in this mode should never be harvesting, even on unload
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return this.takeSTNs(options.retry);
|
|
270
|
+
}
|
|
153
271
|
|
|
154
272
|
// PageViewTiming (FEATURE) events and metrics, such as 'load', 'lcp', etc. pipes into ST here.
|
|
155
273
|
processPVT(name, value, attrs) {
|
|
@@ -191,18 +309,6 @@ export class Aggregate extends AggregateBase {
|
|
|
191
309
|
}
|
|
192
310
|
}
|
|
193
311
|
|
|
194
|
-
// Tracks duration of native APIs wrapped by wrap-timer & wrap-raf.
|
|
195
|
-
storeTimer(target, start, end, type) {
|
|
196
|
-
const evt = {
|
|
197
|
-
n: type,
|
|
198
|
-
s: start,
|
|
199
|
-
e: end,
|
|
200
|
-
o: 'window',
|
|
201
|
-
t: type === 'requestAnimationFrame' ? type : 'timer'
|
|
202
|
-
};
|
|
203
|
-
this.storeSTN(evt);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
312
|
// Tracks the events and their listener's duration on objects wrapped by wrap-events.
|
|
207
313
|
storeEvent(currentEvent, target, start, end) {
|
|
208
314
|
if (this.shouldIgnoreEvent(currentEvent, target)) return;
|
|
@@ -283,12 +389,12 @@ export class Aggregate extends AggregateBase {
|
|
|
283
389
|
};
|
|
284
390
|
this.storeSTN(node);
|
|
285
391
|
}
|
|
286
|
-
|
|
392
|
+
#laststart = 0;
|
|
287
393
|
// Processes all the PerformanceResourceTiming entries captured (by observer).
|
|
288
394
|
storeResources(resources) {
|
|
289
395
|
if (!resources || resources.length === 0) return;
|
|
290
396
|
resources.forEach(currentResource => {
|
|
291
|
-
if ((currentResource.fetchStart | 0) <= this
|
|
397
|
+
if ((currentResource.fetchStart | 0) <= this.#laststart) return; // don't recollect already-seen resources
|
|
292
398
|
|
|
293
399
|
const parsed = parseUrl(currentResource.name);
|
|
294
400
|
const res = {
|
|
@@ -301,7 +407,7 @@ export class Aggregate extends AggregateBase {
|
|
|
301
407
|
};
|
|
302
408
|
this.storeSTN(res);
|
|
303
409
|
});
|
|
304
|
-
this
|
|
410
|
+
this.#laststart = resources[resources.length - 1].fetchStart | 0;
|
|
305
411
|
}
|
|
306
412
|
|
|
307
413
|
// JavascriptError (FEATURE) events pipes into ST here.
|
|
@@ -332,20 +438,50 @@ export class Aggregate extends AggregateBase {
|
|
|
332
438
|
|
|
333
439
|
// Central function called by all the other store__ & addToTrace API to append a trace node.
|
|
334
440
|
storeSTN(stn) {
|
|
335
|
-
if (this.nodeCount >= this.maxNodesPerHarvest)
|
|
336
|
-
|
|
441
|
+
if (this.nodeCount >= this.maxNodesPerHarvest) {
|
|
442
|
+
// limit the amount of pending data awaiting next harvest
|
|
443
|
+
if (this.isStandalone || this.agentRuntime.session.state.sessionTraceMode !== MODE.ERROR) return;
|
|
444
|
+
const openedSpace = this.trimSTNs(ERROR_MODE_SECONDS_WINDOW); // but maybe we could make some space by discarding irrelevant nodes if we're in sessioned Error mode
|
|
445
|
+
if (openedSpace == 0) return;
|
|
446
|
+
}
|
|
337
447
|
if (this.trace[stn.n]) this.trace[stn.n].push(stn);else this.trace[stn.n] = [stn];
|
|
338
448
|
this.nodeCount++;
|
|
339
449
|
}
|
|
340
450
|
|
|
451
|
+
/**
|
|
452
|
+
* Trim the collection of nodes awaiting harvest such that those seen outside a certain span of time are discarded.
|
|
453
|
+
* @param {number} lookbackDuration Past length of time until now for which we care about nodes, in milliseconds
|
|
454
|
+
* @returns {number} However many nodes were discarded after trimming.
|
|
455
|
+
*/
|
|
456
|
+
trimSTNs(lookbackDuration) {
|
|
457
|
+
let prunedNodes = 0;
|
|
458
|
+
const cutoffHighResTime = Math.max(now() - lookbackDuration, 0);
|
|
459
|
+
Object.keys(this.trace).forEach(nameCategory => {
|
|
460
|
+
const nodeList = this.trace[nameCategory];
|
|
461
|
+
/* Notice nodes are appending under their name's list as they end and are stored. This means each list is already (roughly) sorted in chronological order by end time.
|
|
462
|
+
* This isn't exact since nodes go through some processing & EE handlers chain, but it's close enough as we still capture nodes whose duration overlaps the lookback window.
|
|
463
|
+
* ASSUMPTION: all 'end' timings stored are relative to timeOrigin (DOMHighResTimeStamp) and not Unix epoch based. */
|
|
464
|
+
let cutoffIdx = nodeList.findIndex(node => cutoffHighResTime <= node.e);
|
|
465
|
+
if (cutoffIdx == 0) return;else if (cutoffIdx < 0) {
|
|
466
|
+
// whole list falls outside lookback window and is irrelevant
|
|
467
|
+
cutoffIdx = nodeList.length;
|
|
468
|
+
delete this.trace[nameCategory];
|
|
469
|
+
} else nodeList.splice(0, cutoffIdx); // chop off everything outside our window i.e. before the last <lookbackDuration> timeframe
|
|
470
|
+
|
|
471
|
+
this.nodeCount -= cutoffIdx;
|
|
472
|
+
prunedNodes += cutoffIdx;
|
|
473
|
+
});
|
|
474
|
+
return prunedNodes;
|
|
475
|
+
}
|
|
476
|
+
|
|
341
477
|
// Used by session trace's harvester to create the payload body.
|
|
342
478
|
takeSTNs(retry) {
|
|
343
479
|
if (!this.resourceObserver) {
|
|
344
480
|
// if PO isn't supported, this checks resourcetiming buffer every harvest.
|
|
345
481
|
this.storeResources(window.performance.getEntriesByType('resource'));
|
|
346
482
|
}
|
|
347
|
-
const stns = Object.entries(this.trace).flatMap(
|
|
348
|
-
let [name, listOfSTNodes] =
|
|
483
|
+
const stns = Object.entries(this.trace).flatMap(_ref3 => {
|
|
484
|
+
let [name, listOfSTNodes] = _ref3;
|
|
349
485
|
// basically take the "this.trace" map-obj and concat all the list-type values
|
|
350
486
|
if (!(name in toAggregate)) return listOfSTNodes;
|
|
351
487
|
// Special processing for event nodes dealing with user inputs:
|
|
@@ -359,7 +495,7 @@ export class Aggregate extends AggregateBase {
|
|
|
359
495
|
}
|
|
360
496
|
this.trace = {};
|
|
361
497
|
this.nodeCount = 0;
|
|
362
|
-
|
|
498
|
+
return {
|
|
363
499
|
qs: {
|
|
364
500
|
st: String(getRuntime(this.agentIdentifier).offset)
|
|
365
501
|
},
|
|
@@ -367,19 +503,6 @@ export class Aggregate extends AggregateBase {
|
|
|
367
503
|
res: stns
|
|
368
504
|
}
|
|
369
505
|
};
|
|
370
|
-
if (!this.ptid) {
|
|
371
|
-
// send custom and user attributes on the very first ST harvest only
|
|
372
|
-
const {
|
|
373
|
-
userAttributes,
|
|
374
|
-
atts,
|
|
375
|
-
jsAttributes
|
|
376
|
-
} = getInfo(this.agentIdentifier);
|
|
377
|
-
stnInfo.qs.ua = userAttributes;
|
|
378
|
-
stnInfo.qs.at = atts;
|
|
379
|
-
const ja = stringify(jsAttributes);
|
|
380
|
-
stnInfo.qs.ja = ja === '{}' ? null : ja;
|
|
381
|
-
}
|
|
382
|
-
return stnInfo;
|
|
383
506
|
}
|
|
384
507
|
smearEvtsByOrigin(name) {
|
|
385
508
|
const maxGap = toAggregate[name][0];
|
|
@@ -3,16 +3,15 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { handle } from '../../../common/event-emitter/handle';
|
|
6
|
-
import { wrapHistory, wrapEvents
|
|
6
|
+
import { wrapHistory, wrapEvents } from '../../../common/wrap';
|
|
7
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,
|
|
15
|
-
BST_TIMER,
|
|
16
15
|
START,
|
|
17
16
|
END,
|
|
18
17
|
FEATURE_NAME,
|
|
@@ -28,8 +27,6 @@ export class Instrument extends InstrumentBase {
|
|
|
28
27
|
if (!isBrowserScope) return; // session traces not supported outside web env
|
|
29
28
|
|
|
30
29
|
const thisInstrumentEE = this.ee;
|
|
31
|
-
this.timerEE = wrapTimer(thisInstrumentEE);
|
|
32
|
-
this.rafEE = wrapRaf(thisInstrumentEE);
|
|
33
30
|
wrapHistory(thisInstrumentEE);
|
|
34
31
|
this.eventsEE = wrapEvents(thisInstrumentEE);
|
|
35
32
|
this.eventsEE.on(FN_START, function (args, target) {
|
|
@@ -40,19 +37,6 @@ export class Instrument extends InstrumentBase {
|
|
|
40
37
|
// When ajax is disabled, this may fail without making ajax a dependency of session_trace
|
|
41
38
|
handle('bst', [args[0], target, this.bstStart, now()], undefined, FEATURE_NAMES.sessionTrace, thisInstrumentEE);
|
|
42
39
|
});
|
|
43
|
-
this.timerEE.on(FN_START, function (args, obj, type) {
|
|
44
|
-
this.bstStart = now();
|
|
45
|
-
this.bstType = type;
|
|
46
|
-
});
|
|
47
|
-
this.timerEE.on(FN_END, function (args, target) {
|
|
48
|
-
handle(BST_TIMER, [target, this.bstStart, now(), this.bstType], undefined, FEATURE_NAMES.sessionTrace, thisInstrumentEE);
|
|
49
|
-
});
|
|
50
|
-
this.rafEE.on(FN_START, function () {
|
|
51
|
-
this.bstStart = now();
|
|
52
|
-
});
|
|
53
|
-
this.rafEE.on(FN_END, function (args, target) {
|
|
54
|
-
handle(BST_TIMER, [target, this.bstStart, now(), 'requestAnimationFrame'], undefined, FEATURE_NAMES.sessionTrace, thisInstrumentEE);
|
|
55
|
-
});
|
|
56
40
|
thisInstrumentEE.on(PUSH_STATE + START, function (args) {
|
|
57
41
|
this.time = now();
|
|
58
42
|
this.startPath = location.pathname + location.hash;
|
|
@@ -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
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { originals } from '../../common/config/config';
|
|
2
|
-
import { globalScope } from '../../common/util/global-scope';
|
|
3
2
|
import { FEATURE_NAMES } from '../../loaders/features/features';
|
|
4
3
|
export const FEATURE_NAME = FEATURE_NAMES.spa;
|
|
5
4
|
export const INTERACTION_EVENTS = ['click', 'submit', 'keypress', 'keydown', 'keyup', 'change'];
|
|
@@ -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,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getConfiguration, getInfo, getRuntime } from '../../common/config/config';
|
|
2
2
|
import { drain } from '../../common/drain/drain';
|
|
3
3
|
import { ee } from '../../common/event-emitter/contextual-ee';
|
|
4
4
|
import { registerHandler } from '../../common/event-emitter/register-handler';
|
|
5
|
-
import { isBrowserScope } from '../../common/util/global-scope';
|
|
6
5
|
import { SessionEntity } from '../../common/session/session-entity';
|
|
7
6
|
import { LocalStorage } from '../../common/storage/local-storage.js';
|
|
8
7
|
import { FirstPartyCookies } from '../../common/storage/first-party-cookies';
|
|
@@ -10,43 +9,28 @@ let ranOnce = 0;
|
|
|
10
9
|
export function setupAgentSession(agentIdentifier) {
|
|
11
10
|
const agentRuntime = getRuntime(agentIdentifier);
|
|
12
11
|
if (ranOnce++) return agentRuntime.session;
|
|
13
|
-
const
|
|
12
|
+
const sessionInit = getConfiguration(agentIdentifier).session;
|
|
13
|
+
/* Domain is a string that can be specified by customer. The only way to keep the session object across subdomains is using first party cookies.
|
|
14
|
+
This determines which storage wrapper the session manager will use to keep state. */
|
|
15
|
+
const storageTypeInst = sessionInit?.domain ? new FirstPartyCookies(sessionInit.domain) : new LocalStorage();
|
|
16
|
+
agentRuntime.session = new SessionEntity({
|
|
17
|
+
agentIdentifier,
|
|
18
|
+
key: 'SESSION',
|
|
19
|
+
storage: storageTypeInst,
|
|
20
|
+
expiresMs: sessionInit?.expiresMs,
|
|
21
|
+
inactiveMs: sessionInit?.inactiveMs
|
|
22
|
+
});
|
|
14
23
|
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (cookiesEnabled) {
|
|
24
|
-
// defaults to "LocalMemory" if storageAPI is undefined, such as in Worker build
|
|
25
|
-
agentRuntime.session = new SessionEntity({
|
|
26
|
-
agentIdentifier,
|
|
27
|
-
key: 'SESSION',
|
|
28
|
-
storageAPI,
|
|
29
|
-
expiresMs: getConfigurationValue(agentIdentifier, 'session.expiresMs'),
|
|
30
|
-
inactiveMs: getConfigurationValue(agentIdentifier, 'session.inactiveMs')
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// The first time the agent runs on a page, it should put everything
|
|
35
|
-
// that's currently stored in the storage API into the local info.jsAttributes object
|
|
36
|
-
if (isBrowserScope) {
|
|
37
|
-
// retrieve & re-add all of the persisted setCustomAttribute|setUserId k-v from previous page load(s)
|
|
38
|
-
const customSessionData = agentRuntime.session.state.custom;
|
|
39
|
-
const agentInfo = getInfo(agentIdentifier);
|
|
40
|
-
if (customSessionData) {
|
|
41
|
-
setInfo(agentIdentifier, {
|
|
42
|
-
...agentInfo,
|
|
43
|
-
jsAttributes: {
|
|
44
|
-
...agentInfo.jsAttributes,
|
|
45
|
-
...customSessionData
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
}
|
|
24
|
+
// Retrieve & re-add all of the persisted setCustomAttribute|setUserId k-v from previous page load(s), if any was stored.
|
|
25
|
+
const customSessionData = agentRuntime.session.state.custom;
|
|
26
|
+
const agentInfo = getInfo(agentIdentifier);
|
|
27
|
+
if (customSessionData) {
|
|
28
|
+
agentInfo.jsAttributes = {
|
|
29
|
+
...agentInfo.jsAttributes,
|
|
30
|
+
...customSessionData
|
|
31
|
+
};
|
|
49
32
|
}
|
|
33
|
+
const sharedEE = ee.get(agentIdentifier);
|
|
50
34
|
|
|
51
35
|
// any calls to newrelic.setCustomAttribute(<persisted>) will need to be added to:
|
|
52
36
|
// local info.jsAttributes {}
|
|
@@ -8,21 +8,16 @@ export class AggregateBase extends FeatureBase {
|
|
|
8
8
|
super(...arguments);
|
|
9
9
|
this.checkConfiguration();
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* New handler for waiting for multiple flags. Useful when expecting multiple flags simultaneously (ex. stn vs sr)
|
|
14
|
+
* @param {string[]} flagNames
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
11
17
|
waitForFlags() {
|
|
12
18
|
let flagNames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
13
19
|
return Promise.all(flagNames.map(fName => new Promise(resolve => {
|
|
14
|
-
registerHandler("
|
|
15
|
-
resolve({
|
|
16
|
-
name: fName,
|
|
17
|
-
value: true
|
|
18
|
-
});
|
|
19
|
-
}, this.featureName, this.ee);
|
|
20
|
-
registerHandler("block-".concat(fName), () => {
|
|
21
|
-
resolve({
|
|
22
|
-
name: fName,
|
|
23
|
-
value: false
|
|
24
|
-
});
|
|
25
|
-
}, this.feature, this.ee);
|
|
20
|
+
registerHandler("rumresp-".concat(fName), isOn => resolve(isOn), this.featureName, this.ee);
|
|
26
21
|
})));
|
|
27
22
|
}
|
|
28
23
|
|