@newrelic/browser-agent 1.264.0 → 1.265.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/CHANGELOG.md +24 -0
- package/dist/cjs/common/aggregate/aggregator.js +1 -2
- package/dist/cjs/common/config/{state/configurable.js → configurable.js} +1 -1
- package/dist/cjs/common/config/{state/info.js → info.js} +1 -1
- package/dist/cjs/common/config/{state/init.js → init.js} +5 -5
- package/dist/cjs/common/config/{state/loader-config.js → loader-config.js} +1 -1
- package/dist/cjs/common/config/{state/runtime.js → runtime.js} +16 -5
- package/dist/cjs/common/constants/agent-constants.js +8 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/context/shared-context.js +1 -2
- package/dist/cjs/common/dispatch/global-event.js +1 -2
- package/dist/cjs/common/drain/drain.js +10 -16
- package/dist/cjs/common/event-emitter/contextual-ee.js +3 -4
- package/dist/cjs/common/event-listener/event-listener-opts.js +2 -6
- package/dist/cjs/common/harvest/harvest-scheduler.js +1 -2
- package/dist/cjs/common/harvest/harvest.js +29 -56
- package/dist/cjs/common/serialize/bel-serializer.js +6 -11
- package/dist/cjs/common/session/session-entity.js +9 -12
- package/dist/cjs/common/timing/nav-timing.js +1 -3
- package/dist/cjs/common/timing/time-keeper.js +16 -6
- package/dist/cjs/common/url/encode.js +2 -4
- package/dist/cjs/common/util/console.js +2 -0
- package/dist/cjs/common/util/invoke.js +6 -16
- package/dist/cjs/common/util/obfuscate.js +97 -53
- package/dist/cjs/common/util/submit-data.js +17 -20
- package/dist/cjs/common/util/text.js +9 -0
- package/dist/cjs/common/util/traverse.js +1 -3
- package/dist/cjs/common/vitals/cumulative-layout-shift.js +5 -6
- package/dist/cjs/common/vitals/first-contentful-paint.js +4 -5
- package/dist/cjs/common/vitals/first-input-delay.js +4 -5
- package/dist/cjs/common/vitals/interaction-to-next-paint.js +5 -6
- package/dist/cjs/common/vitals/largest-contentful-paint.js +4 -5
- package/dist/cjs/common/vitals/time-to-first-byte.js +4 -5
- package/dist/cjs/common/vitals/vital-metric.js +6 -8
- package/dist/cjs/common/window/nreum.js +2 -1
- package/dist/cjs/common/window/page-visibility.js +1 -4
- package/dist/cjs/common/wrap/wrap-events.js +1 -4
- package/dist/cjs/common/wrap/wrap-promise.js +1 -4
- package/dist/cjs/common/wrap/wrap-websocket.js +74 -0
- package/dist/cjs/features/ajax/aggregate/chunk.js +4 -3
- package/dist/cjs/features/ajax/aggregate/gql.js +4 -5
- package/dist/cjs/features/ajax/aggregate/index.js +20 -23
- package/dist/cjs/features/ajax/constants.js +2 -3
- package/dist/cjs/features/ajax/instrument/distributed-tracing.js +9 -8
- package/dist/cjs/features/ajax/instrument/index.js +15 -13
- package/dist/cjs/features/generic_events/aggregate/index.js +49 -58
- package/dist/cjs/features/generic_events/constants.js +4 -2
- package/dist/cjs/features/generic_events/instrument/index.js +7 -7
- package/dist/cjs/features/jserrors/aggregate/index.js +24 -44
- package/dist/cjs/features/jserrors/instrument/index.js +5 -5
- package/dist/cjs/features/logging/aggregate/index.js +34 -37
- package/dist/cjs/features/logging/constants.js +2 -3
- package/dist/cjs/features/logging/instrument/index.js +6 -7
- package/dist/cjs/features/logging/shared/log.js +1 -3
- package/dist/cjs/features/logging/shared/utils.js +2 -4
- package/dist/cjs/features/metrics/aggregate/index.js +35 -18
- package/dist/cjs/features/metrics/aggregate/websocket-detection.js +34 -0
- package/dist/cjs/features/metrics/constants.js +4 -2
- package/dist/cjs/features/metrics/instrument/index.js +13 -5
- package/dist/cjs/features/page_action/instrument/index.js +8 -4
- package/dist/cjs/features/page_view_event/aggregate/index.js +20 -40
- package/dist/cjs/features/page_view_event/instrument/index.js +5 -5
- package/dist/cjs/features/page_view_timing/aggregate/index.js +24 -40
- package/dist/cjs/features/page_view_timing/instrument/index.js +5 -5
- package/dist/cjs/features/session_replay/aggregate/index.js +37 -44
- package/dist/cjs/features/session_replay/constants.js +1 -5
- package/dist/cjs/features/session_replay/instrument/index.js +6 -10
- package/dist/cjs/features/session_replay/shared/recorder-events.js +25 -20
- package/dist/cjs/features/session_replay/shared/recorder.js +17 -13
- package/dist/cjs/features/session_replay/shared/stylesheet-evaluator.js +3 -3
- package/dist/cjs/features/session_replay/shared/utils.js +5 -4
- package/dist/cjs/features/session_trace/aggregate/index.js +26 -43
- package/dist/cjs/features/session_trace/aggregate/trace/storage.js +7 -5
- package/dist/cjs/features/session_trace/instrument/index.js +9 -8
- package/dist/cjs/features/soft_navigations/aggregate/ajax-node.js +1 -1
- package/dist/cjs/features/soft_navigations/aggregate/bel-node.js +1 -1
- package/dist/cjs/features/soft_navigations/aggregate/index.js +23 -31
- package/dist/cjs/features/soft_navigations/aggregate/initial-page-load-interaction.js +2 -2
- package/dist/cjs/features/soft_navigations/aggregate/interaction.js +9 -10
- package/dist/cjs/features/soft_navigations/instrument/index.js +15 -14
- package/dist/cjs/features/spa/aggregate/index.js +17 -27
- package/dist/cjs/features/spa/aggregate/interaction.js +7 -6
- package/dist/cjs/features/spa/aggregate/serializer.js +3 -3
- package/dist/cjs/features/spa/constants.js +2 -2
- package/dist/cjs/features/spa/instrument/index.js +21 -20
- package/dist/cjs/features/utils/agent-session.js +6 -4
- package/dist/cjs/features/utils/aggregate-base.js +15 -10
- package/dist/cjs/features/utils/event-buffer.js +132 -0
- package/dist/cjs/features/utils/feature-gates.js +2 -2
- package/dist/cjs/features/utils/instrument-base.js +7 -8
- package/dist/cjs/features/utils/lazy-feature-loader.js +11 -11
- package/dist/cjs/features/utils/nr1-debugger.js +1 -3
- package/dist/cjs/loaders/agent-base.js +4 -8
- package/dist/cjs/loaders/agent.js +7 -2
- package/dist/cjs/loaders/api/api.js +22 -34
- package/dist/cjs/loaders/api/apiAsync.js +9 -12
- package/dist/cjs/loaders/configure/configure.js +12 -12
- package/dist/cjs/loaders/features/enabled-features.js +2 -2
- package/dist/cjs/loaders/micro-agent.js +15 -14
- package/dist/esm/common/aggregate/aggregator.js +1 -2
- package/dist/esm/common/config/{state/configurable.js → configurable.js} +1 -1
- package/dist/esm/common/config/{state/info.js → info.js} +1 -1
- package/dist/esm/common/config/{state/init.js → init.js} +5 -5
- package/dist/esm/common/config/{state/loader-config.js → loader-config.js} +1 -1
- package/dist/esm/common/config/{state/runtime.js → runtime.js} +17 -5
- package/dist/esm/common/constants/agent-constants.js +2 -0
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/context/shared-context.js +1 -2
- package/dist/esm/common/dispatch/global-event.js +1 -2
- package/dist/esm/common/drain/drain.js +10 -16
- package/dist/esm/common/event-emitter/contextual-ee.js +2 -3
- package/dist/esm/common/event-listener/event-listener-opts.js +2 -6
- package/dist/esm/common/harvest/harvest-scheduler.js +1 -2
- package/dist/esm/common/harvest/harvest.js +21 -48
- package/dist/esm/common/serialize/bel-serializer.js +6 -11
- package/dist/esm/common/session/session-entity.js +8 -11
- package/dist/esm/common/timing/nav-timing.js +1 -3
- package/dist/esm/common/timing/time-keeper.js +15 -5
- package/dist/esm/common/url/encode.js +2 -4
- package/dist/esm/common/util/console.js +2 -0
- package/dist/esm/common/util/invoke.js +6 -16
- package/dist/esm/common/util/obfuscate.js +96 -49
- package/dist/esm/common/util/submit-data.js +17 -20
- package/dist/esm/common/util/text.js +3 -0
- package/dist/esm/common/util/traverse.js +1 -3
- package/dist/esm/common/vitals/cumulative-layout-shift.js +5 -6
- package/dist/esm/common/vitals/first-contentful-paint.js +4 -5
- package/dist/esm/common/vitals/first-input-delay.js +4 -5
- package/dist/esm/common/vitals/interaction-to-next-paint.js +5 -6
- package/dist/esm/common/vitals/largest-contentful-paint.js +4 -5
- package/dist/esm/common/vitals/time-to-first-byte.js +4 -5
- package/dist/esm/common/vitals/vital-metric.js +6 -8
- package/dist/esm/common/window/nreum.js +2 -1
- package/dist/esm/common/window/page-visibility.js +1 -4
- package/dist/esm/common/wrap/wrap-events.js +1 -4
- package/dist/esm/common/wrap/wrap-promise.js +1 -4
- package/dist/esm/common/wrap/wrap-websocket.js +67 -0
- package/dist/esm/features/ajax/aggregate/chunk.js +3 -2
- package/dist/esm/features/ajax/aggregate/gql.js +4 -5
- package/dist/esm/features/ajax/aggregate/index.js +17 -20
- package/dist/esm/features/ajax/constants.js +1 -2
- package/dist/esm/features/ajax/instrument/distributed-tracing.js +2 -1
- package/dist/esm/features/ajax/instrument/index.js +11 -9
- package/dist/esm/features/generic_events/aggregate/index.js +41 -50
- package/dist/esm/features/generic_events/constants.js +3 -1
- package/dist/esm/features/generic_events/instrument/index.js +5 -5
- package/dist/esm/features/jserrors/aggregate/index.js +19 -39
- package/dist/esm/features/jserrors/instrument/index.js +4 -4
- package/dist/esm/features/logging/aggregate/index.js +32 -35
- package/dist/esm/features/logging/constants.js +1 -2
- package/dist/esm/features/logging/instrument/index.js +5 -6
- package/dist/esm/features/logging/shared/log.js +1 -3
- package/dist/esm/features/logging/shared/utils.js +2 -4
- package/dist/esm/features/metrics/aggregate/index.js +29 -12
- package/dist/esm/features/metrics/aggregate/websocket-detection.js +29 -0
- package/dist/esm/features/metrics/constants.js +3 -1
- package/dist/esm/features/metrics/instrument/index.js +13 -5
- package/dist/esm/features/page_action/instrument/index.js +7 -3
- package/dist/esm/features/page_view_event/aggregate/index.js +18 -38
- package/dist/esm/features/page_view_event/instrument/index.js +4 -4
- package/dist/esm/features/page_view_timing/aggregate/index.js +21 -37
- package/dist/esm/features/page_view_timing/instrument/index.js +4 -4
- package/dist/esm/features/session_replay/aggregate/index.js +27 -34
- package/dist/esm/features/session_replay/constants.js +0 -4
- package/dist/esm/features/session_replay/index.js +1 -7
- package/dist/esm/features/session_replay/instrument/index.js +6 -9
- package/dist/esm/features/session_replay/shared/recorder-events.js +25 -20
- package/dist/esm/features/session_replay/shared/recorder.js +14 -10
- package/dist/esm/features/session_replay/shared/stylesheet-evaluator.js +3 -3
- package/dist/esm/features/session_replay/shared/utils.js +3 -2
- package/dist/esm/features/session_trace/aggregate/index.js +21 -38
- package/dist/esm/features/session_trace/aggregate/trace/storage.js +7 -5
- package/dist/esm/features/session_trace/instrument/index.js +6 -5
- package/dist/esm/features/soft_navigations/aggregate/ajax-node.js +1 -1
- package/dist/esm/features/soft_navigations/aggregate/bel-node.js +1 -1
- package/dist/esm/features/soft_navigations/aggregate/index.js +22 -30
- package/dist/esm/features/soft_navigations/aggregate/initial-page-load-interaction.js +1 -1
- package/dist/esm/features/soft_navigations/aggregate/interaction.js +7 -8
- package/dist/esm/features/soft_navigations/instrument/index.js +12 -11
- package/dist/esm/features/spa/aggregate/index.js +11 -21
- package/dist/esm/features/spa/aggregate/interaction.js +6 -5
- package/dist/esm/features/spa/aggregate/serializer.js +1 -1
- package/dist/esm/features/spa/constants.js +2 -2
- package/dist/esm/features/spa/instrument/index.js +13 -12
- package/dist/esm/features/utils/agent-session.js +3 -1
- package/dist/esm/features/utils/aggregate-base.js +13 -8
- package/dist/esm/features/utils/event-buffer.js +126 -0
- package/dist/esm/features/utils/feature-gates.js +1 -1
- package/dist/esm/features/utils/instrument-base.js +6 -7
- package/dist/esm/features/utils/lazy-feature-loader.js +11 -11
- package/dist/esm/features/utils/nr1-debugger.js +1 -3
- package/dist/esm/loaders/agent-base.js +4 -8
- package/dist/esm/loaders/agent.js +7 -2
- package/dist/esm/loaders/api/api.js +17 -29
- package/dist/esm/loaders/api/apiAsync.js +2 -5
- package/dist/esm/loaders/configure/configure.js +5 -5
- package/dist/esm/loaders/features/enabled-features.js +1 -1
- package/dist/esm/loaders/micro-agent.js +10 -9
- package/dist/types/common/config/configurable.d.ts.map +1 -0
- package/dist/types/common/config/info.d.ts.map +1 -0
- package/dist/types/common/config/init.d.ts.map +1 -0
- package/dist/types/common/config/loader-config.d.ts.map +1 -0
- package/dist/types/common/config/runtime.d.ts.map +1 -0
- package/dist/types/common/constants/agent-constants.d.ts +3 -0
- package/dist/types/common/constants/agent-constants.d.ts.map +1 -0
- package/dist/types/common/drain/drain.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest.d.ts +1 -7
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/serialize/bel-serializer.d.ts.map +1 -1
- package/dist/types/common/timing/time-keeper.d.ts +9 -2
- package/dist/types/common/timing/time-keeper.d.ts.map +1 -1
- package/dist/types/common/util/console.d.ts.map +1 -1
- package/dist/types/common/util/obfuscate.d.ts +78 -6
- package/dist/types/common/util/obfuscate.d.ts.map +1 -1
- package/dist/types/common/util/text.d.ts +2 -0
- package/dist/types/common/util/text.d.ts.map +1 -0
- package/dist/types/common/window/nreum.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-websocket.d.ts +4 -0
- package/dist/types/common/wrap/wrap-websocket.d.ts.map +1 -0
- package/dist/types/features/ajax/aggregate/chunk.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts +2 -3
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/ajax/constants.d.ts +0 -1
- package/dist/types/features/ajax/constants.d.ts.map +1 -1
- package/dist/types/features/ajax/instrument/distributed-tracing.d.ts.map +1 -1
- package/dist/types/features/ajax/instrument/index.d.ts +1 -0
- package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/aggregate/index.d.ts +6 -8
- package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/constants.d.ts +2 -0
- package/dist/types/features/generic_events/constants.d.ts.map +1 -1
- package/dist/types/features/generic_events/instrument/index.d.ts +1 -0
- package/dist/types/features/generic_events/instrument/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +2 -2
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/instrument/index.d.ts +1 -0
- package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
- package/dist/types/features/logging/aggregate/index.d.ts +4 -7
- package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/logging/constants.d.ts +0 -1
- package/dist/types/features/logging/constants.d.ts.map +1 -1
- package/dist/types/features/logging/instrument/index.d.ts +1 -0
- package/dist/types/features/logging/instrument/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/websocket-detection.d.ts +12 -0
- package/dist/types/features/metrics/aggregate/websocket-detection.d.ts.map +1 -0
- package/dist/types/features/metrics/constants.d.ts +1 -0
- package/dist/types/features/metrics/constants.d.ts.map +1 -1
- package/dist/types/features/metrics/instrument/index.d.ts +1 -0
- package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_action/instrument/index.d.ts +4 -0
- package/dist/types/features/page_action/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_event/instrument/index.d.ts +1 -0
- package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/instrument/index.d.ts +1 -0
- package/dist/types/features/page_view_timing/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/constants.d.ts +0 -4
- package/dist/types/features/session_replay/constants.d.ts.map +1 -1
- package/dist/types/features/session_replay/instrument/index.d.ts +1 -0
- package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder-events.d.ts +6 -6
- package/dist/types/features/session_replay/shared/recorder-events.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts +2 -2
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/utils.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +2 -2
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/trace/storage.d.ts +1 -1
- package/dist/types/features/session_trace/aggregate/trace/storage.d.ts.map +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts +1 -0
- package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/index.d.ts +3 -3
- package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/instrument/index.d.ts +1 -0
- package/dist/types/features/soft_navigations/instrument/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/index.d.ts +2 -2
- package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/interaction.d.ts.map +1 -1
- package/dist/types/features/spa/constants.d.ts.map +1 -1
- package/dist/types/features/spa/instrument/index.d.ts +1 -0
- package/dist/types/features/spa/instrument/index.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 +1 -0
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/event-buffer.d.ts +72 -0
- package/dist/types/features/utils/event-buffer.d.ts.map +1 -0
- package/dist/types/features/utils/instrument-base.d.ts +1 -0
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/agent-base.d.ts +1 -1
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +55 -59
- package/src/common/config/__mocks__/info.js +3 -0
- package/src/common/config/__mocks__/init.js +3 -0
- package/src/common/config/__mocks__/loader-config.js +2 -0
- package/src/common/config/__mocks__/runtime.js +2 -0
- package/src/common/config/{state/configurable.js → configurable.js} +1 -1
- package/src/common/config/{state/info.js → info.js} +1 -1
- package/src/common/config/{state/init.js → init.js} +5 -5
- package/src/common/config/{state/loader-config.js → loader-config.js} +1 -1
- package/src/common/config/{state/runtime.js → runtime.js} +19 -5
- package/src/common/constants/agent-constants.js +2 -0
- package/src/common/drain/drain.js +5 -2
- package/src/common/event-emitter/contextual-ee.js +1 -1
- package/src/common/harvest/harvest.js +7 -21
- package/src/common/serialize/bel-serializer.js +5 -7
- package/src/common/session/session-entity.js +2 -2
- package/src/common/timing/__mocks__/time-keeper.js +6 -2
- package/src/common/timing/time-keeper.js +15 -5
- package/src/common/util/__mocks__/console.js +1 -0
- package/src/common/util/__mocks__/obfuscate.js +5 -8
- package/src/common/util/console.js +2 -0
- package/src/common/util/obfuscate.js +94 -50
- package/src/common/util/text.js +6 -0
- package/src/common/window/__mocks__/nreum.js +1 -1
- package/src/common/window/nreum.js +2 -1
- package/src/common/wrap/wrap-websocket.js +73 -0
- package/src/features/ajax/aggregate/chunk.js +3 -2
- package/src/features/ajax/aggregate/index.js +20 -19
- package/src/features/ajax/constants.js +0 -2
- package/src/features/ajax/instrument/distributed-tracing.js +2 -1
- package/src/features/ajax/instrument/index.js +9 -5
- package/src/features/generic_events/aggregate/index.js +43 -37
- package/src/features/generic_events/constants.js +2 -0
- package/src/features/generic_events/instrument/index.js +3 -1
- package/src/features/jserrors/aggregate/index.js +14 -4
- package/src/features/jserrors/instrument/index.js +2 -0
- package/src/features/logging/aggregate/index.js +39 -31
- package/src/features/logging/constants.js +0 -2
- package/src/features/logging/instrument/index.js +2 -0
- package/src/features/logging/shared/utils.js +1 -1
- package/src/features/metrics/aggregate/index.js +24 -9
- package/src/features/metrics/aggregate/websocket-detection.js +31 -0
- package/src/features/metrics/constants.js +3 -0
- package/src/features/metrics/instrument/index.js +13 -1
- package/src/features/page_action/instrument/index.js +5 -0
- package/src/features/page_view_event/aggregate/index.js +8 -23
- package/src/features/page_view_event/instrument/index.js +2 -0
- package/src/features/page_view_timing/aggregate/index.js +14 -16
- package/src/features/page_view_timing/instrument/index.js +2 -0
- package/src/features/session_replay/aggregate/index.js +13 -9
- package/src/features/session_replay/constants.js +0 -4
- package/src/features/session_replay/index.js +1 -7
- package/src/features/session_replay/instrument/index.js +3 -4
- package/src/features/session_replay/shared/recorder-events.js +27 -20
- package/src/features/session_replay/shared/recorder.js +13 -6
- package/src/features/session_replay/shared/stylesheet-evaluator.js +2 -2
- package/src/features/session_replay/shared/utils.js +3 -2
- package/src/features/session_trace/aggregate/index.js +16 -7
- package/src/features/session_trace/aggregate/trace/storage.js +6 -1
- package/src/features/session_trace/instrument/index.js +4 -1
- package/src/features/soft_navigations/aggregate/ajax-node.js +1 -1
- package/src/features/soft_navigations/aggregate/index.js +13 -15
- package/src/features/soft_navigations/aggregate/initial-page-load-interaction.js +1 -1
- package/src/features/soft_navigations/aggregate/interaction.js +1 -1
- package/src/features/soft_navigations/instrument/index.js +9 -5
- package/src/features/spa/aggregate/index.js +11 -18
- package/src/features/spa/aggregate/interaction.js +5 -3
- package/src/features/spa/aggregate/serializer.js +1 -1
- package/src/features/spa/constants.js +2 -2
- package/src/features/spa/instrument/index.js +9 -3
- package/src/features/utils/agent-session.js +3 -1
- package/src/features/utils/aggregate-base.js +10 -2
- package/src/features/utils/event-buffer.js +126 -0
- package/src/features/utils/feature-gates.js +1 -1
- package/src/features/utils/instrument-base.js +2 -1
- package/src/loaders/agent-base.js +2 -2
- package/src/loaders/agent.js +7 -2
- package/src/loaders/api/api.js +2 -1
- package/src/loaders/api/apiAsync.js +1 -1
- package/src/loaders/configure/configure.js +4 -1
- package/src/loaders/features/enabled-features.js +1 -1
- package/src/loaders/micro-agent.js +4 -1
- package/dist/cjs/common/config/config.js +0 -76
- package/dist/cjs/common/config/state/originals.js +0 -8
- package/dist/cjs/common/wrap/index.js +0 -61
- package/dist/esm/common/config/config.js +0 -11
- package/dist/esm/common/config/state/originals.js +0 -2
- package/dist/esm/common/wrap/index.js +0 -13
- package/dist/types/common/config/config.d.ts +0 -13
- package/dist/types/common/config/config.d.ts.map +0 -1
- package/dist/types/common/config/state/configurable.d.ts.map +0 -1
- package/dist/types/common/config/state/info.d.ts.map +0 -1
- package/dist/types/common/config/state/init.d.ts.map +0 -1
- package/dist/types/common/config/state/loader-config.d.ts.map +0 -1
- package/dist/types/common/config/state/originals.d.ts +0 -2
- package/dist/types/common/config/state/originals.d.ts.map +0 -1
- package/dist/types/common/config/state/runtime.d.ts.map +0 -1
- package/dist/types/common/wrap/index.d.ts +0 -10
- package/dist/types/common/wrap/index.d.ts.map +0 -1
- package/src/common/config/__mocks__/config.js +0 -11
- package/src/common/config/config.js +0 -12
- package/src/common/config/state/originals.js +0 -3
- package/src/common/wrap/index.js +0 -16
- /package/dist/types/common/config/{state/configurable.d.ts → configurable.d.ts} +0 -0
- /package/dist/types/common/config/{state/info.d.ts → info.d.ts} +0 -0
- /package/dist/types/common/config/{state/init.d.ts → init.d.ts} +0 -0
- /package/dist/types/common/config/{state/loader-config.d.ts → loader-config.d.ts} +0 -0
- /package/dist/types/common/config/{state/runtime.d.ts → runtime.d.ts} +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
2
2
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
3
|
-
import {
|
|
3
|
+
import { getInfo } from '../../../common/config/info';
|
|
4
|
+
import { getConfigurationValue } from '../../../common/config/init';
|
|
5
|
+
import { getRuntime } from '../../../common/config/runtime';
|
|
4
6
|
import { FEATURE_NAME } from '../constants';
|
|
5
7
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
6
8
|
import { TraceStorage } from './trace/storage';
|
|
@@ -8,11 +10,12 @@ import { obj as encodeObj } from '../../../common/url/encode';
|
|
|
8
10
|
import { deregisterDrain } from '../../../common/drain/drain';
|
|
9
11
|
import { globalScope } from '../../../common/constants/runtime';
|
|
10
12
|
import { MODE, SESSION_EVENTS } from '../../../common/session/constants';
|
|
13
|
+
import { applyFnToProps } from '../../../common/util/traverse';
|
|
11
14
|
const ERROR_MODE_SECONDS_WINDOW = 30 * 1000; // sliding window of nodes to track when simply monitoring (but not harvesting) in error mode
|
|
12
15
|
/** Reserved room for query param attrs */
|
|
13
16
|
const QUERY_PARAM_PADDING = 5000;
|
|
14
17
|
export class Aggregate extends AggregateBase {
|
|
15
|
-
static featureName =
|
|
18
|
+
static featureName = FEATURE_NAME;
|
|
16
19
|
constructor(agentIdentifier, aggregator) {
|
|
17
20
|
super(agentIdentifier, aggregator, FEATURE_NAME);
|
|
18
21
|
this.agentRuntime = getRuntime(agentIdentifier);
|
|
@@ -30,15 +33,11 @@ export class Aggregate extends AggregateBase {
|
|
|
30
33
|
/** TraceStorage is the mechanism that holds, normalizes and aggregates ST nodes. It will be accessed and purged when harvests occur */
|
|
31
34
|
this.traceStorage = new TraceStorage(this);
|
|
32
35
|
/** This agg needs information about sampling (sts) and entitlements (st) to make the appropriate decisions on running */
|
|
33
|
-
this.waitForFlags(['sts', 'st']).then(
|
|
34
|
-
let [stMode, stEntitled] = _ref;
|
|
35
|
-
return this.initialize(stMode, stEntitled);
|
|
36
|
-
});
|
|
36
|
+
this.waitForFlags(['sts', 'st']).then(([stMode, stEntitled]) => this.initialize(stMode, stEntitled));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/** Sets up event listeners, and initializes this module to run in the correct "mode". Can be triggered from a few places, but makes an effort to only set up listeners once */
|
|
40
40
|
initialize(stMode, stEntitled, ignoreSession) {
|
|
41
|
-
var _this = this;
|
|
42
41
|
this.entitled ??= stEntitled;
|
|
43
42
|
if (this.blocked || !this.entitled) return deregisterDrain(this.agentIdentifier, this.featureName);
|
|
44
43
|
if (!this.initialized) {
|
|
@@ -78,31 +77,17 @@ export class Aggregate extends AggregateBase {
|
|
|
78
77
|
}, this);
|
|
79
78
|
|
|
80
79
|
/** The handlers set up by the Inst file */
|
|
81
|
-
registerHandler('bst',
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
registerHandler('
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
registerHandler('
|
|
88
|
-
return _this.traceStorage.storeHist(...arguments);
|
|
89
|
-
}, this.featureName, this.ee);
|
|
90
|
-
registerHandler('bstXhrAgg', function () {
|
|
91
|
-
return _this.traceStorage.storeXhrAgg(...arguments);
|
|
92
|
-
}, this.featureName, this.ee);
|
|
93
|
-
registerHandler('bstApi', function () {
|
|
94
|
-
return _this.traceStorage.storeSTN(...arguments);
|
|
95
|
-
}, this.featureName, this.ee);
|
|
96
|
-
registerHandler('trace-jserror', function () {
|
|
97
|
-
return _this.traceStorage.storeErrorAgg(...arguments);
|
|
98
|
-
}, this.featureName, this.ee);
|
|
99
|
-
registerHandler('pvtAdded', function () {
|
|
100
|
-
return _this.traceStorage.processPVT(...arguments);
|
|
101
|
-
}, this.featureName, this.ee);
|
|
80
|
+
registerHandler('bst', (...args) => this.traceStorage.storeEvent(...args), this.featureName, this.ee);
|
|
81
|
+
registerHandler('bstResource', (...args) => this.traceStorage.storeResources(...args), this.featureName, this.ee);
|
|
82
|
+
registerHandler('bstHist', (...args) => this.traceStorage.storeHist(...args), this.featureName, this.ee);
|
|
83
|
+
registerHandler('bstXhrAgg', (...args) => this.traceStorage.storeXhrAgg(...args), this.featureName, this.ee);
|
|
84
|
+
registerHandler('bstApi', (...args) => this.traceStorage.storeSTN(...args), this.featureName, this.ee);
|
|
85
|
+
registerHandler('trace-jserror', (...args) => this.traceStorage.storeErrorAgg(...args), this.featureName, this.ee);
|
|
86
|
+
registerHandler('pvtAdded', (...args) => this.traceStorage.processPVT(...args), this.featureName, this.ee);
|
|
102
87
|
if (typeof PerformanceNavigationTiming !== 'undefined') {
|
|
103
88
|
this.traceStorage.storeTiming(globalScope.performance?.getEntriesByType?.('navigation')[0]);
|
|
104
89
|
} else {
|
|
105
|
-
this.traceStorage.storeTiming(globalScope.performance?.timing);
|
|
90
|
+
this.traceStorage.storeTiming(globalScope.performance?.timing, true);
|
|
106
91
|
}
|
|
107
92
|
|
|
108
93
|
/** Only start actually harvesting if running in full mode at init time */
|
|
@@ -126,8 +111,7 @@ export class Aggregate extends AggregateBase {
|
|
|
126
111
|
}
|
|
127
112
|
|
|
128
113
|
/** Called by the harvest scheduler at harvest time to retrieve the payload. This will only actually return a payload if running in full mode */
|
|
129
|
-
prepareHarvest() {
|
|
130
|
-
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
114
|
+
prepareHarvest(options = {}) {
|
|
131
115
|
this.traceStorage.prevStoredEvents.clear(); // release references to past events for GC
|
|
132
116
|
if (!this.timeKeeper?.ready) return; // this should likely never happen, but just to be safe, we should never harvest if we cant correct time
|
|
133
117
|
if (this.blocked || this.mode !== MODE.FULL || this.traceStorage.nodeCount === 0) return;
|
|
@@ -166,7 +150,7 @@ export class Aggregate extends AggregateBase {
|
|
|
166
150
|
type: 'BrowserSessionChunk',
|
|
167
151
|
app_id: this.agentInfo.applicationID,
|
|
168
152
|
protocol_version: '0',
|
|
169
|
-
timestamp: this.timeKeeper.convertRelativeTimestamp(earliestTimeStamp),
|
|
153
|
+
timestamp: Math.floor(this.timeKeeper.correctAbsoluteTimestamp(this.timeKeeper.convertRelativeTimestamp(earliestTimeStamp))),
|
|
170
154
|
attributes: encodeObj({
|
|
171
155
|
...(agentMetadata.entityGuid && {
|
|
172
156
|
entityGuid: agentMetadata.entityGuid
|
|
@@ -175,8 +159,8 @@ export class Aggregate extends AggregateBase {
|
|
|
175
159
|
// this section of attributes must be controllable and stay below the query param padding limit -- see QUERY_PARAM_PADDING
|
|
176
160
|
// if not, data could be lost to truncation at time of sending, potentially breaking parsing / API behavior in NR1
|
|
177
161
|
// trace payload metadata
|
|
178
|
-
'trace.firstTimestamp': this.timeKeeper.convertRelativeTimestamp(earliestTimeStamp),
|
|
179
|
-
'trace.lastTimestamp': this.timeKeeper.convertRelativeTimestamp(latestTimeStamp),
|
|
162
|
+
'trace.firstTimestamp': Math.floor(this.timeKeeper.correctAbsoluteTimestamp(this.timeKeeper.convertRelativeTimestamp(earliestTimeStamp))),
|
|
163
|
+
'trace.lastTimestamp': Math.floor(this.timeKeeper.correctAbsoluteTimestamp(this.timeKeeper.convertRelativeTimestamp(latestTimeStamp))),
|
|
180
164
|
'trace.nodes': stns.length,
|
|
181
165
|
'trace.originTimestamp': this.timeKeeper.correctedOriginTime,
|
|
182
166
|
// other payload metadata
|
|
@@ -191,12 +175,12 @@ export class Aggregate extends AggregateBase {
|
|
|
191
175
|
session: "".concat(this.sessionId),
|
|
192
176
|
// customer-defined data should go last so that if it exceeds the query param padding limit it will be truncated instead of important attrs
|
|
193
177
|
...(endUserId && {
|
|
194
|
-
'enduser.id': endUserId
|
|
178
|
+
'enduser.id': this.obfuscator.obfuscateString(endUserId)
|
|
195
179
|
})
|
|
196
180
|
// The Query Param is being arbitrarily limited in length here. It is also applied when estimating the size of the payload in getPayloadSize()
|
|
197
181
|
}, QUERY_PARAM_PADDING).substring(1) // remove the leading '&'
|
|
198
182
|
},
|
|
199
|
-
body: stns
|
|
183
|
+
body: applyFnToProps(stns, this.obfuscator.obfuscateString.bind(this.obfuscator), 'string')
|
|
200
184
|
};
|
|
201
185
|
}
|
|
202
186
|
|
|
@@ -206,8 +190,7 @@ export class Aggregate extends AggregateBase {
|
|
|
206
190
|
onHarvestFinished(result) {
|
|
207
191
|
if (result.sent && result.retry && this.sentTrace) {
|
|
208
192
|
// merge previous trace back into buffer to retry for next harvest
|
|
209
|
-
Object.entries(this.sentTrace).forEach(
|
|
210
|
-
let [name, listOfSTNodes] = _ref2;
|
|
193
|
+
Object.entries(this.sentTrace).forEach(([name, listOfSTNodes]) => {
|
|
211
194
|
this.traceStorage.restoreNode(name, listOfSTNodes);
|
|
212
195
|
});
|
|
213
196
|
this.sentTrace = null;
|
|
@@ -33,10 +33,10 @@ const toAggregate = {
|
|
|
33
33
|
export class TraceStorage {
|
|
34
34
|
nodeCount = 0;
|
|
35
35
|
trace = {};
|
|
36
|
-
earliestTimeStamp =
|
|
36
|
+
earliestTimeStamp = Infinity;
|
|
37
37
|
latestTimeStamp = 0;
|
|
38
38
|
tempStorage = [];
|
|
39
|
-
prevStoredEvents =
|
|
39
|
+
prevStoredEvents = new Set();
|
|
40
40
|
constructor(parent) {
|
|
41
41
|
this.parent = parent;
|
|
42
42
|
}
|
|
@@ -91,8 +91,7 @@ export class TraceStorage {
|
|
|
91
91
|
// if PO isn't supported, this checks resourcetiming buffer every harvest.
|
|
92
92
|
this.storeResources(globalScope.performance?.getEntriesByType?.('resource'));
|
|
93
93
|
}
|
|
94
|
-
const stns = Object.entries(this.trace).flatMap(
|
|
95
|
-
let [name, listOfSTNodes] = _ref;
|
|
94
|
+
const stns = Object.entries(this.trace).flatMap(([name, listOfSTNodes]) => {
|
|
96
95
|
// basically take the "this.trace" map-obj and concat all the list-type values
|
|
97
96
|
if (!(name in toAggregate)) return listOfSTNodes;
|
|
98
97
|
// Special processing for event nodes dealing with user inputs:
|
|
@@ -150,7 +149,7 @@ export class TraceStorage {
|
|
|
150
149
|
return name === 'fi' && !!attrs && typeof attrs.fid === 'number';
|
|
151
150
|
}
|
|
152
151
|
}
|
|
153
|
-
storeTiming(timingEntry) {
|
|
152
|
+
storeTiming(timingEntry, isAbsoluteTimestamp = false) {
|
|
154
153
|
if (!timingEntry) return;
|
|
155
154
|
|
|
156
155
|
// loop iterates through prototype also (for FF)
|
|
@@ -165,6 +164,9 @@ export class TraceStorage {
|
|
|
165
164
|
// that are in the future (Microsoft Edge seems to sometimes produce these)
|
|
166
165
|
if (!(typeof val === 'number' && val >= 0)) continue;
|
|
167
166
|
val = Math.round(val);
|
|
167
|
+
if (this.parent.timeKeeper && this.parent.timeKeeper.ready && isAbsoluteTimestamp) {
|
|
168
|
+
val = this.parent.timeKeeper.convertAbsoluteTimestamp(Math.floor(this.parent.timeKeeper.correctAbsoluteTimestamp(val)));
|
|
169
|
+
}
|
|
168
170
|
this.storeSTN(new TraceNode(key, val, val, 'document', 'timing'));
|
|
169
171
|
}
|
|
170
172
|
}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { handle } from '../../../common/event-emitter/handle';
|
|
6
|
-
import { wrapHistory
|
|
6
|
+
import { wrapHistory } from '../../../common/wrap/wrap-history';
|
|
7
|
+
import { wrapEvents } from '../../../common/wrap/wrap-events';
|
|
7
8
|
import { InstrumentBase } from '../../utils/instrument-base';
|
|
8
9
|
import * as CONSTANTS from '../constants';
|
|
9
10
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
@@ -21,9 +22,8 @@ const {
|
|
|
21
22
|
PUSH_STATE
|
|
22
23
|
} = CONSTANTS;
|
|
23
24
|
export class Instrument extends InstrumentBase {
|
|
24
|
-
static featureName =
|
|
25
|
-
constructor(agentIdentifier, aggregator) {
|
|
26
|
-
let auto = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
25
|
+
static featureName = FEATURE_NAME;
|
|
26
|
+
constructor(agentIdentifier, aggregator, auto = true) {
|
|
27
27
|
super(agentIdentifier, aggregator, FEATURE_NAME, auto);
|
|
28
28
|
const canTrackSession = canEnableSessionTracking(this.agentIdentifier);
|
|
29
29
|
if (!canTrackSession) {
|
|
@@ -67,4 +67,5 @@ export class Instrument extends InstrumentBase {
|
|
|
67
67
|
resourceObserver: observer
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
|
-
}
|
|
70
|
+
}
|
|
71
|
+
export const SessionTrace = Instrument;
|
|
@@ -16,7 +16,7 @@ export class AjaxNode extends BelNode {
|
|
|
16
16
|
this.traceId = ajaxEvent.traceId;
|
|
17
17
|
this.spanTimestamp = ajaxEvent.spanTimestamp;
|
|
18
18
|
this.gql = ajaxEvent.gql;
|
|
19
|
-
this.start = ajaxEvent.startTime;
|
|
19
|
+
this.start = ajaxEvent.startTime; // 5000 --- 5500 --> 10500
|
|
20
20
|
this.end = ajaxEvent.endTime;
|
|
21
21
|
}
|
|
22
22
|
serialize(parentStartTimestamp) {
|
|
@@ -7,7 +7,7 @@ export class BelNode {
|
|
|
7
7
|
end;
|
|
8
8
|
callbackEnd = 0;
|
|
9
9
|
callbackDuration = 0;
|
|
10
|
-
nodeId =
|
|
10
|
+
nodeId = ++nodesSeen;
|
|
11
11
|
constructor(agentIdentifier) {
|
|
12
12
|
if (!agentIdentifier) throw new Error('Interaction is missing core attributes');
|
|
13
13
|
this.agentIdentifier = agentIdentifier;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getConfigurationValue } from '../../../common/config/
|
|
1
|
+
import { getConfigurationValue } from '../../../common/config/init';
|
|
2
2
|
import { deregisterDrain } from '../../../common/drain/drain';
|
|
3
3
|
import { handle } from '../../../common/event-emitter/handle';
|
|
4
4
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
@@ -8,30 +8,28 @@ import { timeToFirstByte } from '../../../common/vitals/time-to-first-byte';
|
|
|
8
8
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
9
9
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants';
|
|
10
10
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
11
|
+
import { EventBuffer } from '../../utils/event-buffer';
|
|
11
12
|
import { API_TRIGGER_NAME, FEATURE_NAME, INTERACTION_STATUS } from '../constants';
|
|
12
13
|
import { AjaxNode } from './ajax-node';
|
|
13
14
|
import { InitialPageLoadInteraction } from './initial-page-load-interaction';
|
|
14
15
|
import { Interaction } from './interaction';
|
|
15
16
|
export class Aggregate extends AggregateBase {
|
|
16
|
-
static featureName =
|
|
17
|
-
constructor(agentIdentifier, aggregator,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} = _ref;
|
|
17
|
+
static featureName = FEATURE_NAME;
|
|
18
|
+
constructor(agentIdentifier, aggregator, {
|
|
19
|
+
domObserver
|
|
20
|
+
}) {
|
|
21
21
|
super(agentIdentifier, aggregator, FEATURE_NAME);
|
|
22
22
|
const harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'soft_navigations.harvestTimeSeconds') || 10;
|
|
23
|
-
this.interactionsToHarvest =
|
|
24
|
-
this.interactionsAwaitingRetry = [];
|
|
23
|
+
this.interactionsToHarvest = new EventBuffer();
|
|
25
24
|
this.domObserver = domObserver;
|
|
26
25
|
this.initialPageLoadInteraction = new InitialPageLoadInteraction(agentIdentifier);
|
|
27
|
-
timeToFirstByte.subscribe(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
} = _ref2;
|
|
26
|
+
timeToFirstByte.subscribe(({
|
|
27
|
+
attrs
|
|
28
|
+
}) => {
|
|
31
29
|
const loadEventTime = attrs.navigationEntry.loadEventEnd;
|
|
32
30
|
this.initialPageLoadInteraction.forceSave = true;
|
|
33
31
|
this.initialPageLoadInteraction.done(loadEventTime);
|
|
34
|
-
this.interactionsToHarvest.
|
|
32
|
+
this.interactionsToHarvest.add(this.initialPageLoadInteraction);
|
|
35
33
|
this.initialPageLoadInteraction = null;
|
|
36
34
|
// Report metric on the initial page load time
|
|
37
35
|
handle(SUPPORTABILITY_METRIC_CHANNEL, ['SoftNav/Interaction/InitialPageLoad/Duration/Ms', Math.round(loadEventTime)], undefined, FEATURE_NAMES.metrics, this.ee);
|
|
@@ -40,8 +38,7 @@ export class Aggregate extends AggregateBase {
|
|
|
40
38
|
this.interactionInProgress = null; // aside from the "page load" interaction, there can only ever be 1 ongoing at a time
|
|
41
39
|
|
|
42
40
|
this.blocked = false;
|
|
43
|
-
this.waitForFlags(['spa']).then(
|
|
44
|
-
let [spaOn] = _ref3;
|
|
41
|
+
this.waitForFlags(['spa']).then(([spaOn]) => {
|
|
45
42
|
if (spaOn) {
|
|
46
43
|
this.drain();
|
|
47
44
|
const scheduler = new HarvestScheduler('events', {
|
|
@@ -72,18 +69,17 @@ export class Aggregate extends AggregateBase {
|
|
|
72
69
|
registerHandler('jserror', this.#handleJserror.bind(this), this.featureName, this.ee);
|
|
73
70
|
}
|
|
74
71
|
onHarvestStarted(options) {
|
|
75
|
-
if (this.interactionsToHarvest.
|
|
72
|
+
if (!this.interactionsToHarvest.hasData || this.blocked) return;
|
|
76
73
|
// The payload depacker takes the first ixn of a payload (if there are multiple ixns) and positively offset the subsequent ixns timestamps by that amount.
|
|
77
74
|
// In order to accurately portray the real start & end times of the 2nd & onward ixns, we hence need to negatively offset their start timestamps with that of the 1st ixn.
|
|
78
75
|
let firstIxnStartTime = 0; // the very 1st ixn does not require any offsetting
|
|
79
76
|
const serializedIxnList = [];
|
|
80
|
-
for (const interaction of this.interactionsToHarvest) {
|
|
77
|
+
for (const interaction of this.interactionsToHarvest.buffer) {
|
|
81
78
|
serializedIxnList.push(interaction.serialize(firstIxnStartTime));
|
|
82
79
|
if (!firstIxnStartTime) firstIxnStartTime = Math.floor(interaction.start);
|
|
83
80
|
}
|
|
84
81
|
const payload = "bel.7;".concat(serializedIxnList.join(';'));
|
|
85
|
-
if (options.retry) this.
|
|
86
|
-
this.interactionsToHarvest = [];
|
|
82
|
+
if (options.retry) this.interactionsToHarvest.hold();else this.interactionsToHarvest.clear();
|
|
87
83
|
return {
|
|
88
84
|
body: {
|
|
89
85
|
e: payload
|
|
@@ -91,10 +87,7 @@ export class Aggregate extends AggregateBase {
|
|
|
91
87
|
};
|
|
92
88
|
}
|
|
93
89
|
onHarvestFinished(result) {
|
|
94
|
-
if (result.sent && result.retry && this.
|
|
95
|
-
this.interactionsToHarvest = [...this.interactionsAwaitingRetry, ...this.interactionsToHarvest];
|
|
96
|
-
}
|
|
97
|
-
this.interactionsAwaitingRetry = [];
|
|
90
|
+
if (result.sent && result.retry && this.interactionsToHarvest.held.hasData) this.interactionsToHarvest.unhold();else this.interactionsToHarvest.held.clear();
|
|
98
91
|
}
|
|
99
92
|
startUIInteraction(eventName, startedAt, sourceElem) {
|
|
100
93
|
// this is throttled by instrumentation so that it isn't excessively called
|
|
@@ -115,7 +108,7 @@ export class Aggregate extends AggregateBase {
|
|
|
115
108
|
setClosureHandlers() {
|
|
116
109
|
this.interactionInProgress.on('finished', () => {
|
|
117
110
|
const ref = this.interactionInProgress;
|
|
118
|
-
this.interactionsToHarvest.
|
|
111
|
+
this.interactionsToHarvest.add(this.interactionInProgress);
|
|
119
112
|
this.interactionInProgress = null;
|
|
120
113
|
this.domObserver.disconnect(); // can stop observing whenever our interaction logic completes a cycle
|
|
121
114
|
|
|
@@ -142,9 +135,9 @@ export class Aggregate extends AggregateBase {
|
|
|
142
135
|
*/
|
|
143
136
|
if (this.interactionInProgress?.isActiveDuring(timestamp)) return this.interactionInProgress;
|
|
144
137
|
let saveIxn;
|
|
145
|
-
for (let idx = this.interactionsToHarvest.length - 1; idx >= 0; idx--) {
|
|
138
|
+
for (let idx = this.interactionsToHarvest.buffer.length - 1; idx >= 0; idx--) {
|
|
146
139
|
// reverse search for the latest completed interaction for efficiency
|
|
147
|
-
const finishedInteraction = this.interactionsToHarvest[idx];
|
|
140
|
+
const finishedInteraction = this.interactionsToHarvest.buffer[idx];
|
|
148
141
|
if (finishedInteraction.isActiveDuring(timestamp)) {
|
|
149
142
|
if (finishedInteraction.trigger !== 'initialPageLoad') return finishedInteraction;
|
|
150
143
|
// It's possible that a complete interaction occurs before page is fully loaded, so we need to consider if a route-change ixn may have overlapped this iPL
|
|
@@ -204,10 +197,9 @@ export class Aggregate extends AggregateBase {
|
|
|
204
197
|
#registerApiHandlers() {
|
|
205
198
|
const INTERACTION_API = 'api-ixn-';
|
|
206
199
|
const thisClass = this;
|
|
207
|
-
registerHandler(INTERACTION_API + 'get', function (time
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
200
|
+
registerHandler(INTERACTION_API + 'get', function (time, {
|
|
201
|
+
waitForEnd
|
|
202
|
+
} = {}) {
|
|
211
203
|
// In here, 'this' refers to the EventContext specific to per InteractionHandle instance spawned by each .interaction() api call.
|
|
212
204
|
// Each api call aka IH instance would therefore retain a reference to either the in-progress interaction *at the time of the call* OR a new api-started interaction.
|
|
213
205
|
this.associatedInteraction = thisClass.getInteractionFor(time);
|
|
@@ -3,7 +3,7 @@ import { Interaction } from './interaction';
|
|
|
3
3
|
import { numeric } from '../../../common/serialize/bel-serializer';
|
|
4
4
|
import { firstPaint } from '../../../common/vitals/first-paint';
|
|
5
5
|
import { firstContentfulPaint } from '../../../common/vitals/first-contentful-paint';
|
|
6
|
-
import { getInfo } from '../../../common/config/
|
|
6
|
+
import { getInfo } from '../../../common/config/info';
|
|
7
7
|
export class InitialPageLoadInteraction extends Interaction {
|
|
8
8
|
constructor(agentIdentifier) {
|
|
9
9
|
super(agentIdentifier, 'initialPageLoad', 0, null);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getInfo } from '../../../common/config/
|
|
1
|
+
import { getInfo } from '../../../common/config/info';
|
|
2
2
|
import { globalScope, initialLocation } from '../../../common/constants/runtime';
|
|
3
3
|
import { generateUuid } from '../../../common/ids/unique-id';
|
|
4
4
|
import { addCustomAttributes, getAddStringContext, nullable, numeric } from '../../../common/serialize/bel-serializer';
|
|
@@ -11,10 +11,10 @@ import { BelNode } from './bel-node';
|
|
|
11
11
|
* link https://github.com/newrelic/nr-querypack/blob/main/schemas/bel/7.qpschema
|
|
12
12
|
**/
|
|
13
13
|
export class Interaction extends BelNode {
|
|
14
|
-
id =
|
|
15
|
-
initialPageURL =
|
|
16
|
-
oldURL =
|
|
17
|
-
newURL =
|
|
14
|
+
id = generateUuid(); // unique id that is serialized and used to link interactions with errors
|
|
15
|
+
initialPageURL = initialLocation;
|
|
16
|
+
oldURL = '' + globalScope?.location;
|
|
17
|
+
newURL = '' + globalScope?.location;
|
|
18
18
|
customName;
|
|
19
19
|
customAttributes = {};
|
|
20
20
|
customDataByApi = {};
|
|
@@ -22,7 +22,7 @@ export class Interaction extends BelNode {
|
|
|
22
22
|
appTime; // only used by initialPageLoad interactions
|
|
23
23
|
newRoute;
|
|
24
24
|
/** Internal state of this interaction: in-progress, finished, or cancelled. */
|
|
25
|
-
status =
|
|
25
|
+
status = INTERACTION_STATUS.IP;
|
|
26
26
|
domTimestamp = 0;
|
|
27
27
|
historyTimestamp = 0;
|
|
28
28
|
createdByApi = false;
|
|
@@ -65,8 +65,7 @@ export class Interaction extends BelNode {
|
|
|
65
65
|
else this.#cancel();
|
|
66
66
|
return true;
|
|
67
67
|
}
|
|
68
|
-
#finish() {
|
|
69
|
-
let customEndTime = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
68
|
+
#finish(customEndTime = 0) {
|
|
70
69
|
if (this.status !== INTERACTION_STATUS.IP) return; // disallow this call if the ixn is already done aka not in-progress
|
|
71
70
|
clearTimeout(this.cancellationTimer);
|
|
72
71
|
this.end = Math.max(this.domTimestamp, this.historyTimestamp, customEndTime);
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { gosNREUMOriginals } from '../../../common/window/nreum';
|
|
2
2
|
import { isBrowserScope } from '../../../common/constants/runtime';
|
|
3
3
|
import { handle } from '../../../common/event-emitter/handle';
|
|
4
4
|
import { windowAddEventListener } from '../../../common/event-listener/event-listener-opts';
|
|
5
5
|
import { debounce } from '../../../common/util/invoke';
|
|
6
|
-
import { wrapEvents
|
|
6
|
+
import { wrapEvents } from '../../../common/wrap/wrap-events';
|
|
7
|
+
import { wrapHistory } from '../../../common/wrap/wrap-history';
|
|
7
8
|
import { InstrumentBase } from '../../utils/instrument-base';
|
|
8
9
|
import { FEATURE_NAME, INTERACTION_TRIGGERS } from '../constants';
|
|
9
10
|
import { now } from '../../../common/timing/now';
|
|
10
11
|
|
|
11
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* The minimal time after a UI event for which no further events will be processed - i.e. a throttling rate to reduce spam.
|
|
12
14
|
* This also give some time for the new interaction to complete without being discarded by a subsequent UI event and wrongly attributed.
|
|
13
15
|
* This value is still subject to change and critique, as it is derived from beyond worst case time to next frame of a page.
|
|
14
16
|
*/
|
|
15
17
|
const UI_WAIT_INTERVAL = 1 / 10 * 1000; // assume 10 fps
|
|
16
18
|
|
|
17
19
|
export class Instrument extends InstrumentBase {
|
|
18
|
-
static featureName =
|
|
19
|
-
constructor(agentIdentifier, aggregator) {
|
|
20
|
-
let auto = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
20
|
+
static featureName = FEATURE_NAME;
|
|
21
|
+
constructor(agentIdentifier, aggregator, auto = true) {
|
|
21
22
|
super(agentIdentifier, aggregator, FEATURE_NAME, auto);
|
|
22
|
-
if (!isBrowserScope || !
|
|
23
|
+
if (!isBrowserScope || !gosNREUMOriginals().o.MO) return; // soft navigations is not supported outside web env or browsers without the mutation observer API
|
|
23
24
|
|
|
24
25
|
const historyEE = wrapHistory(this.ee);
|
|
25
26
|
const eventsEE = wrapEvents(this.ee);
|
|
@@ -32,7 +33,7 @@ export class Instrument extends InstrumentBase {
|
|
|
32
33
|
const trackURLChangeEvent = evt => handle('newURL', [evt.timeStamp, '' + window.location], undefined, this.featureName, this.ee);
|
|
33
34
|
windowAddEventListener('popstate', trackURLChangeEvent, true, this.removeOnAbort?.signal);
|
|
34
35
|
let oncePerFrame = false; // attempt to reduce dom noice since the observer runs very frequently with below options
|
|
35
|
-
const domObserver = new
|
|
36
|
+
const domObserver = new (gosNREUMOriginals().o.MO)((domChanges, observer) => {
|
|
36
37
|
if (oncePerFrame) return;
|
|
37
38
|
oncePerFrame = true;
|
|
38
39
|
requestAnimationFrame(() => {
|
|
@@ -52,8 +53,7 @@ export class Instrument extends InstrumentBase {
|
|
|
52
53
|
}, UI_WAIT_INTERVAL, {
|
|
53
54
|
leading: true
|
|
54
55
|
});
|
|
55
|
-
eventsEE.on('fn-start',
|
|
56
|
-
let [evt] = _ref;
|
|
56
|
+
eventsEE.on('fn-start', ([evt]) => {
|
|
57
57
|
// set up a new user ixn before the callback for the triggering event executes
|
|
58
58
|
if (INTERACTION_TRIGGERS.includes(evt?.type)) {
|
|
59
59
|
processUserInteraction(evt);
|
|
@@ -70,4 +70,5 @@ export class Instrument extends InstrumentBase {
|
|
|
70
70
|
this.abortHandler = undefined; // weakly allow this abort op to run only once
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
}
|
|
73
|
+
}
|
|
74
|
+
export const SoftNav = Instrument;
|
|
@@ -9,7 +9,8 @@ import { shouldCollectEvent } from '../../../common/deny-list/deny-list';
|
|
|
9
9
|
import { navTimingValues as navTiming } from '../../../common/timing/nav-timing';
|
|
10
10
|
import { generateUuid } from '../../../common/ids/unique-id';
|
|
11
11
|
import { Interaction } from './interaction';
|
|
12
|
-
import { getConfigurationValue
|
|
12
|
+
import { getConfigurationValue } from '../../../common/config/init';
|
|
13
|
+
import { getRuntime } from '../../../common/config/runtime';
|
|
13
14
|
import { eventListenerOpts } from '../../../common/event-listener/event-listener-opts';
|
|
14
15
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
15
16
|
import { Serializer } from './serializer';
|
|
@@ -25,6 +26,7 @@ import { handle } from '../../../common/event-emitter/handle';
|
|
|
25
26
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants';
|
|
26
27
|
import { deregisterDrain } from '../../../common/drain/drain';
|
|
27
28
|
import { warn } from '../../../common/util/console';
|
|
29
|
+
import { EventBuffer } from '../../utils/event-buffer';
|
|
28
30
|
const {
|
|
29
31
|
FEATURE_NAME,
|
|
30
32
|
INTERACTION_EVENTS,
|
|
@@ -44,7 +46,7 @@ const {
|
|
|
44
46
|
originalSetTimeout
|
|
45
47
|
} = CONSTANTS;
|
|
46
48
|
export class Aggregate extends AggregateBase {
|
|
47
|
-
static featureName =
|
|
49
|
+
static featureName = FEATURE_NAME;
|
|
48
50
|
constructor(agentIdentifier, aggregator) {
|
|
49
51
|
super(agentIdentifier, aggregator, FEATURE_NAME);
|
|
50
52
|
const agentRuntime = getRuntime(agentIdentifier);
|
|
@@ -62,8 +64,7 @@ export class Aggregate extends AggregateBase {
|
|
|
62
64
|
childTime: 0,
|
|
63
65
|
depth: 0,
|
|
64
66
|
harvestTimeSeconds: getConfigurationValue(agentIdentifier, 'spa.harvestTimeSeconds') || 10,
|
|
65
|
-
interactionsToHarvest:
|
|
66
|
-
interactionsSent: [],
|
|
67
|
+
interactionsToHarvest: new EventBuffer(),
|
|
67
68
|
// The below feature flag is used to disable the SPA ajax fix for specific customers, see https://new-relic.atlassian.net/browse/NR-172169
|
|
68
69
|
disableSpaFix: (getConfigurationValue(agentIdentifier, 'feature_flags') || []).indexOf('disable-spa-fix') > -1
|
|
69
70
|
};
|
|
@@ -116,8 +117,7 @@ export class Aggregate extends AggregateBase {
|
|
|
116
117
|
// | click ending: | 65 | 50 | | | |
|
|
117
118
|
// click fn-end | 70 | 0 | 0 | 70 | 20 |
|
|
118
119
|
|
|
119
|
-
this.waitForFlags(['spa']).then(
|
|
120
|
-
let [spaFlag] = _ref;
|
|
120
|
+
this.waitForFlags(['spa']).then(([spaFlag]) => {
|
|
121
121
|
if (spaFlag) {
|
|
122
122
|
scheduler = new HarvestScheduler('events', {
|
|
123
123
|
onFinished: onHarvestFinished,
|
|
@@ -619,14 +619,9 @@ export class Aggregate extends AggregateBase {
|
|
|
619
619
|
}
|
|
620
620
|
const classThis = this;
|
|
621
621
|
function onHarvestStarted(options) {
|
|
622
|
-
if (state.interactionsToHarvest.
|
|
623
|
-
var payload = serializer.serializeMultiple(state.interactionsToHarvest, 0, navTiming);
|
|
624
|
-
if (options.retry)
|
|
625
|
-
state.interactionsToHarvest.forEach(function (interaction) {
|
|
626
|
-
state.interactionsSent.push(interaction);
|
|
627
|
-
});
|
|
628
|
-
}
|
|
629
|
-
state.interactionsToHarvest = [];
|
|
622
|
+
if (!state.interactionsToHarvest.hasData || classThis.blocked) return {};
|
|
623
|
+
var payload = serializer.serializeMultiple(state.interactionsToHarvest.buffer, 0, navTiming);
|
|
624
|
+
if (options.retry) state.interactionsToHarvest.hold();else state.interactionsToHarvest.clear();
|
|
630
625
|
return {
|
|
631
626
|
body: {
|
|
632
627
|
e: payload
|
|
@@ -634,12 +629,7 @@ export class Aggregate extends AggregateBase {
|
|
|
634
629
|
};
|
|
635
630
|
}
|
|
636
631
|
function onHarvestFinished(result) {
|
|
637
|
-
if (result.sent && result.retry && state.
|
|
638
|
-
state.interactionsSent.forEach(function (interaction) {
|
|
639
|
-
state.interactionsToHarvest.unshift(interaction);
|
|
640
|
-
});
|
|
641
|
-
state.interactionsSent = [];
|
|
642
|
-
}
|
|
632
|
+
if (result.sent && result.retry && state.interactionsToHarvest.held.hasData) state.interactionsToHarvest.unhold();else state.interactionsToHarvest.held.clear();
|
|
643
633
|
}
|
|
644
634
|
baseEE.on('spa-jserror', function (type, name, params, metrics) {
|
|
645
635
|
if (!state.currentNode) return;
|
|
@@ -687,7 +677,7 @@ export class Aggregate extends AggregateBase {
|
|
|
687
677
|
interaction.root.attrs.firstContentfulPaint = firstContentfulPaint.current.value;
|
|
688
678
|
}
|
|
689
679
|
baseEE.emit('interactionDone', [interaction, true]);
|
|
690
|
-
state.interactionsToHarvest.
|
|
680
|
+
state.interactionsToHarvest.add(interaction);
|
|
691
681
|
let smCategory;
|
|
692
682
|
if (interaction.root?.attrs?.trigger === 'initialPageLoad') smCategory = 'InitialPageLoad';else if (interaction.routeChange) smCategory = 'RouteChange';else smCategory = 'Custom';
|
|
693
683
|
handle(SUPPORTABILITY_METRIC_CHANNEL, ["Spa/Interaction/".concat(smCategory, "/Duration/Ms"), Math.max((interaction.root?.end || 0) - (interaction.root?.start || 0), 0)], undefined, FEATURE_NAMES.metrics, baseEE);
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { getInfo
|
|
6
|
+
import { getInfo } from '../../../common/config/info';
|
|
7
|
+
import { getRuntime } from '../../../common/config/runtime';
|
|
8
|
+
import { gosNREUMOriginals } from '../../../common/window/nreum';
|
|
7
9
|
import { ee } from '../../../common/event-emitter/contextual-ee';
|
|
8
10
|
import { InteractionNode } from './interaction-node';
|
|
9
|
-
var originalSetTimeout =
|
|
10
|
-
var originalClearTimeout =
|
|
11
|
+
var originalSetTimeout = gosNREUMOriginals().o.ST;
|
|
12
|
+
var originalClearTimeout = gosNREUMOriginals().o.CT;
|
|
11
13
|
var lastId = {};
|
|
12
14
|
export function Interaction(eventName, timestamp, url, routeName, onFinished, agentIdentifier) {
|
|
13
15
|
this.agentIdentifier = agentIdentifier;
|
|
@@ -81,8 +83,7 @@ InteractionPrototype.finish = function finishInteraction() {
|
|
|
81
83
|
if (this.onFinished) {
|
|
82
84
|
this.onFinished(this);
|
|
83
85
|
}
|
|
84
|
-
Object.entries(getInfo(interaction.agentIdentifier).jsAttributes || {}).forEach(
|
|
85
|
-
let [attr, value] = _ref;
|
|
86
|
+
Object.entries(getInfo(interaction.agentIdentifier).jsAttributes || {}).forEach(([attr, value]) => {
|
|
86
87
|
if (!(attr in customAttrs)) customAttrs[attr] = value;
|
|
87
88
|
});
|
|
88
89
|
root.end = endTimestamp;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { cleanURL } from '../../../common/url/clean-url';
|
|
6
6
|
import { nullable, numeric, getAddStringContext, addCustomAttributes } from '../../../common/serialize/bel-serializer';
|
|
7
7
|
import { SharedContext } from '../../../common/context/shared-context';
|
|
8
|
-
import { getInfo } from '../../../common/config/
|
|
8
|
+
import { getInfo } from '../../../common/config/info';
|
|
9
9
|
export class Serializer extends SharedContext {
|
|
10
10
|
constructor(parent) {
|
|
11
11
|
super(parent);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { gosNREUMOriginals } from '../../common/window/nreum';
|
|
2
2
|
import { FEATURE_NAMES } from '../../loaders/features/features';
|
|
3
3
|
export const FEATURE_NAME = FEATURE_NAMES.spa;
|
|
4
4
|
export const INTERACTION_EVENTS = ['click', 'submit', 'keypress', 'keydown', 'keyup', 'change'];
|
|
@@ -15,7 +15,7 @@ export const FETCH_START = 'fetch-start';
|
|
|
15
15
|
export const FETCH_DONE = 'fetch-done';
|
|
16
16
|
export const FETCH_BODY = 'fetch-body-';
|
|
17
17
|
export const JSONP_END = 'jsonp-end';
|
|
18
|
-
export const originalSetTimeout =
|
|
18
|
+
export const originalSetTimeout = gosNREUMOriginals().o.ST;
|
|
19
19
|
export const START = '-start';
|
|
20
20
|
export const END = '-end';
|
|
21
21
|
export const BODY = '-body';
|