@newrelic/browser-agent 1.233.1 → 1.235.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 +1 -1
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/constants/shared-channel.js +19 -0
- package/dist/cjs/common/event-emitter/contextual-ee.test.js +10 -10
- package/dist/cjs/common/harvest/{harvest-scheduler.test.js → harvest-scheduler.component-test.js} +2 -2
- package/dist/cjs/common/harvest/harvest-scheduler.js +21 -5
- package/dist/cjs/common/harvest/harvest.component-test.js +224 -0
- package/dist/cjs/common/harvest/harvest.js +4 -11
- package/dist/cjs/common/session/{session-entity.test.js → session-entity.component-test.js} +79 -42
- package/dist/cjs/common/session/session-entity.js +19 -11
- package/dist/cjs/common/timer/interaction-timer.js +1 -1
- package/dist/cjs/common/url/canonicalize-url.test.js +26 -30
- package/dist/cjs/common/url/encode.js +2 -2
- package/dist/cjs/common/util/console.test.js +30 -0
- package/dist/cjs/common/util/data-size.test.js +37 -20
- package/dist/cjs/common/util/feature-flags.js +23 -12
- package/dist/cjs/common/util/feature-flags.test.js +84 -0
- package/dist/cjs/common/util/get-or-set.js +8 -1
- package/dist/cjs/common/util/get-or-set.test.js +47 -0
- package/dist/cjs/common/util/global-scope.js +1 -32
- package/dist/cjs/common/util/global-scope.test.js +72 -0
- package/dist/cjs/common/util/obfuscate.component-test.js +129 -0
- package/dist/cjs/common/util/obfuscate.js +2 -2
- package/dist/cjs/common/util/stringify.test.js +48 -0
- package/dist/cjs/common/util/submit-data.js +18 -18
- package/dist/cjs/common/util/submit-data.test.js +245 -0
- package/dist/cjs/common/util/traverse.js +19 -27
- package/dist/cjs/common/util/traverse.test.js +44 -0
- package/dist/cjs/common/wrap/wrap-raf.js +1 -1
- package/dist/cjs/common/wrap/wrap-timer.js +1 -1
- package/dist/cjs/features/jserrors/aggregate/index.js +4 -0
- package/dist/cjs/features/jserrors/instrument/index.js +2 -15
- package/dist/cjs/features/metrics/aggregate/endpoint-map.js +14 -0
- package/dist/cjs/features/metrics/aggregate/index.js +3 -2
- package/dist/cjs/features/metrics/instrument/index.js +0 -2
- package/dist/cjs/features/page_view_event/aggregate/index.js +58 -44
- package/dist/cjs/features/session_replay/aggregate/index.component-test.js +457 -0
- 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 +0 -16
- package/dist/cjs/features/spa/constants.js +0 -1
- package/dist/cjs/features/utils/agent-session.js +20 -36
- package/dist/cjs/features/utils/agent-session.test.js +211 -0
- package/dist/cjs/features/utils/aggregate-base.js +7 -12
- package/dist/cjs/features/utils/aggregate-base.test.js +110 -0
- package/dist/cjs/features/utils/feature-base.test.js +42 -0
- package/dist/cjs/features/utils/handler-cache.js +28 -23
- package/dist/cjs/features/utils/handler-cache.test.js +53 -0
- package/dist/cjs/features/utils/instrument-base.js +58 -39
- package/dist/cjs/features/utils/instrument-base.test.js +179 -0
- package/dist/cjs/features/utils/lazy-feature-loader.test.js +30 -0
- package/dist/cjs/loaders/agent.js +0 -1
- package/dist/cjs/loaders/api/api.js +1 -1
- package/dist/cjs/loaders/configure/configure.js +0 -1
- package/dist/cjs/loaders/features/featureDependencies.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/constants/shared-channel.js +12 -0
- package/dist/esm/common/event-emitter/contextual-ee.test.js +10 -10
- package/dist/esm/common/harvest/{harvest-scheduler.test.js → harvest-scheduler.component-test.js} +2 -2
- package/dist/esm/common/harvest/harvest-scheduler.js +21 -5
- package/dist/esm/common/harvest/harvest.component-test.js +222 -0
- package/dist/esm/common/harvest/harvest.js +4 -11
- package/dist/esm/common/session/{session-entity.test.js → session-entity.component-test.js} +77 -40
- package/dist/esm/common/session/session-entity.js +17 -11
- package/dist/esm/common/timer/interaction-timer.js +1 -1
- package/dist/esm/common/url/canonicalize-url.test.js +25 -29
- package/dist/esm/common/url/encode.js +2 -2
- package/dist/esm/common/util/console.test.js +28 -0
- package/dist/esm/common/util/data-size.test.js +35 -20
- package/dist/esm/common/util/feature-flags.js +23 -12
- package/dist/esm/common/util/feature-flags.test.js +80 -0
- package/dist/esm/common/util/get-or-set.js +8 -1
- package/dist/esm/common/util/get-or-set.test.js +45 -0
- package/dist/esm/common/util/global-scope.js +1 -29
- package/dist/esm/common/util/global-scope.test.js +70 -0
- package/dist/esm/common/util/obfuscate.component-test.js +125 -0
- package/dist/esm/common/util/obfuscate.js +2 -2
- package/dist/esm/common/util/stringify.test.js +46 -0
- package/dist/esm/common/util/submit-data.js +18 -18
- package/dist/esm/common/util/submit-data.test.js +241 -0
- package/dist/esm/common/util/traverse.js +19 -27
- package/dist/esm/common/util/traverse.test.js +42 -0
- package/dist/esm/common/wrap/wrap-raf.js +1 -1
- package/dist/esm/common/wrap/wrap-timer.js +1 -1
- package/dist/esm/features/jserrors/aggregate/index.js +4 -0
- package/dist/esm/features/jserrors/instrument/index.js +2 -15
- package/dist/esm/features/metrics/aggregate/endpoint-map.js +7 -0
- package/dist/esm/features/metrics/aggregate/index.js +3 -2
- package/dist/esm/features/metrics/instrument/index.js +0 -2
- package/dist/esm/features/page_view_event/aggregate/index.js +58 -44
- package/dist/esm/features/session_replay/aggregate/index.component-test.js +453 -0
- 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 +1 -17
- package/dist/esm/features/spa/constants.js +0 -1
- package/dist/esm/features/utils/agent-session.js +21 -37
- package/dist/esm/features/utils/agent-session.test.js +207 -0
- package/dist/esm/features/utils/aggregate-base.js +7 -12
- package/dist/esm/features/utils/aggregate-base.test.js +108 -0
- package/dist/esm/features/utils/feature-base.test.js +40 -0
- package/dist/esm/features/utils/handler-cache.js +28 -23
- package/dist/esm/features/utils/handler-cache.test.js +51 -0
- package/dist/esm/features/utils/instrument-base.js +58 -39
- package/dist/esm/features/utils/instrument-base.test.js +175 -0
- package/dist/esm/features/utils/lazy-feature-loader.test.js +29 -0
- package/dist/esm/loaders/agent.js +0 -1
- package/dist/esm/loaders/api/api.js +2 -2
- package/dist/esm/loaders/configure/configure.js +0 -1
- package/dist/esm/loaders/features/featureDependencies.js +2 -0
- package/dist/types/common/config/state/init.d.ts.map +1 -1
- 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/context/shared-context.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest-scheduler.component-test.d.ts +2 -0
- package/dist/types/common/harvest/harvest-scheduler.component-test.d.ts.map +1 -0
- package/dist/types/common/harvest/harvest-scheduler.d.ts +4 -0
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest.component-test.d.ts +2 -0
- package/dist/types/common/harvest/harvest.component-test.d.ts.map +1 -0
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.component-test.d.ts +2 -0
- package/dist/types/common/session/session-entity.component-test.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/timer/interaction-timer.component-test.d.ts +2 -0
- package/dist/types/common/timer/interaction-timer.component-test.d.ts.map +1 -0
- package/dist/types/common/timer/timer.d.ts.map +1 -1
- package/dist/types/common/url/encode.component-test.d.ts +2 -0
- package/dist/types/common/url/encode.component-test.d.ts.map +1 -0
- package/dist/types/common/url/protocol.component-test.d.ts +2 -0
- package/dist/types/common/url/protocol.component-test.d.ts.map +1 -0
- 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/get-or-set.d.ts +9 -1
- package/dist/types/common/util/get-or-set.d.ts.map +1 -1
- package/dist/types/common/util/global-scope.d.ts +0 -9
- package/dist/types/common/util/global-scope.d.ts.map +1 -1
- package/dist/types/common/util/obfuscate.component-test.d.ts +2 -0
- package/dist/types/common/util/obfuscate.component-test.d.ts.map +1 -0
- package/dist/types/common/util/submit-data.d.ts +14 -10
- package/dist/types/common/util/submit-data.d.ts.map +1 -1
- package/dist/types/common/util/traverse.d.ts +10 -1
- package/dist/types/common/util/traverse.d.ts.map +1 -1
- package/dist/types/common/window/nreum.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +1 -0
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/endpoint-map.d.ts +8 -0
- package/dist/types/features/metrics/aggregate/endpoint-map.d.ts.map +1 -0
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts.map +1 -1
- package/dist/types/features/metrics/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.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.component-test.d.ts +2 -0
- package/dist/types/features/session_replay/aggregate/index.component-test.d.ts.map +1 -0
- 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/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/features/featureDependencies.d.ts.map +1 -1
- package/package.json +14 -8
- package/src/common/config/state/init.js +0 -1
- package/src/common/constants/shared-channel.js +13 -0
- package/src/common/context/shared-context.js +0 -1
- package/src/common/event-emitter/contextual-ee.test.js +10 -10
- package/src/common/harvest/{harvest-scheduler.test.js → harvest-scheduler.component-test.js} +2 -2
- package/src/common/harvest/harvest-scheduler.js +17 -6
- package/src/common/harvest/harvest.component-test.js +169 -0
- package/src/common/harvest/harvest.js +5 -9
- package/src/common/session/{session-entity.test.js → session-entity.component-test.js} +70 -48
- package/src/common/session/session-entity.js +15 -12
- package/src/common/timer/interaction-timer.js +1 -1
- package/src/common/timer/timer.js +0 -1
- package/src/common/url/canonicalize-url.test.js +32 -21
- package/src/common/url/encode.js +2 -2
- package/src/common/util/console.test.js +34 -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/get-or-set.js +8 -1
- package/src/common/util/get-or-set.test.js +58 -0
- package/src/common/util/global-scope.js +0 -26
- package/src/common/util/global-scope.test.js +87 -0
- package/src/common/util/obfuscate.component-test.js +173 -0
- package/src/common/util/obfuscate.js +2 -2
- package/src/common/util/stringify.test.js +49 -0
- package/src/common/util/submit-data.js +18 -19
- package/src/common/util/submit-data.test.js +226 -0
- package/src/common/util/traverse.js +18 -27
- package/src/common/util/traverse.test.js +50 -0
- package/src/common/window/nreum.js +0 -1
- package/src/common/wrap/wrap-raf.js +1 -1
- package/src/common/wrap/wrap-timer.js +1 -1
- package/src/features/jserrors/aggregate/index.js +5 -0
- package/src/features/jserrors/instrument/index.js +2 -15
- package/src/features/metrics/aggregate/endpoint-map.js +7 -0
- package/src/features/metrics/aggregate/index.js +3 -2
- package/src/features/metrics/aggregate/polyfill-detection.es5.js +0 -1
- package/src/features/metrics/instrument/index.js +0 -2
- package/src/features/page_view_event/aggregate/index.js +48 -51
- package/src/features/page_view_event/instrument/index.js +0 -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 +2 -19
- package/src/features/spa/constants.js +0 -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 -24
- 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 +190 -0
- package/src/features/utils/lazy-feature-loader.test.js +37 -0
- package/src/loaders/agent.js +0 -1
- package/src/loaders/api/api.js +2 -2
- package/src/loaders/configure/configure.js +0 -1
- package/src/loaders/features/featureDependencies.js +2 -0
- 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/util/s-hash.js +0 -19
- package/dist/cjs/features/metrics/instrument/workers-helper.js +0 -124
- 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/util/s-hash.js +0 -13
- package/dist/esm/features/metrics/instrument/workers-helper.js +0 -119
- 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/s-hash.d.ts +0 -2
- package/dist/types/common/util/s-hash.d.ts.map +0 -1
- package/dist/types/features/metrics/instrument/workers-helper.d.ts +0 -7
- package/dist/types/features/metrics/instrument/workers-helper.d.ts.map +0 -1
- package/src/common/storage/local-memory.js +0 -30
- package/src/common/storage/local-memory.test.js +0 -19
- package/src/common/util/s-hash.js +0 -14
- package/src/features/metrics/instrument/workers-helper.js +0 -113
- /package/dist/cjs/common/timer/{interaction-timer.test.js → interaction-timer.component-test.js} +0 -0
- /package/dist/cjs/common/url/{encode.test.js → encode.component-test.js} +0 -0
- /package/dist/cjs/common/url/{protocol.test.js → protocol.component-test.js} +0 -0
- /package/dist/esm/common/timer/{interaction-timer.test.js → interaction-timer.component-test.js} +0 -0
- /package/dist/esm/common/url/{encode.test.js → encode.component-test.js} +0 -0
- /package/dist/esm/common/url/{protocol.test.js → protocol.component-test.js} +0 -0
- /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
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.RRWEB_VERSION = exports.Aggregate = void 0;
|
|
6
|
+
exports.RRWEB_VERSION = exports.MAX_PAYLOAD_SIZE = exports.IDEAL_PAYLOAD_SIZE = exports.Aggregate = exports.AVG_COMPRESSION = void 0;
|
|
7
7
|
var _drain = require("../../../common/drain/drain");
|
|
8
8
|
var _registerHandler = require("../../../common/event-emitter/register-handler");
|
|
9
9
|
var _harvestScheduler = require("../../../common/harvest/harvest-scheduler");
|
|
@@ -12,6 +12,7 @@ var _stringify = require("../../../common/util/stringify");
|
|
|
12
12
|
var _config = require("../../../common/config/config");
|
|
13
13
|
var _sessionEntity = require("../../../common/session/session-entity");
|
|
14
14
|
var _aggregateBase = require("../../utils/aggregate-base");
|
|
15
|
+
var _sharedChannel = require("../../../common/constants/shared-channel");
|
|
15
16
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
16
17
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /*
|
|
17
18
|
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
@@ -26,37 +27,38 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
26
27
|
// would be better to get this dynamically in some way
|
|
27
28
|
const RRWEB_VERSION = '2.0.0-alpha.8';
|
|
28
29
|
exports.RRWEB_VERSION = RRWEB_VERSION;
|
|
30
|
+
const AVG_COMPRESSION = 0.12;
|
|
31
|
+
exports.AVG_COMPRESSION = AVG_COMPRESSION;
|
|
29
32
|
let recorder, gzipper, u8;
|
|
30
33
|
|
|
31
|
-
/** The "mode" with which the session replay is recording */
|
|
32
|
-
const MODE = {
|
|
33
|
-
OFF: 0,
|
|
34
|
-
FULL: 1,
|
|
35
|
-
ERROR: 2
|
|
36
|
-
};
|
|
37
34
|
/** Vortex caps payload sizes at 1MB */
|
|
38
35
|
const MAX_PAYLOAD_SIZE = 1000000;
|
|
39
36
|
/** Unloading caps around 64kb */
|
|
37
|
+
exports.MAX_PAYLOAD_SIZE = MAX_PAYLOAD_SIZE;
|
|
40
38
|
const IDEAL_PAYLOAD_SIZE = 64000;
|
|
41
39
|
/** Interval between forcing new full snapshots in "error" mode */
|
|
40
|
+
exports.IDEAL_PAYLOAD_SIZE = IDEAL_PAYLOAD_SIZE;
|
|
42
41
|
const CHECKOUT_MS = 30000;
|
|
43
42
|
class Aggregate extends _aggregateBase.AggregateBase {
|
|
44
43
|
static featureName = _constants.FEATURE_NAME;
|
|
45
44
|
constructor(agentIdentifier, aggregator) {
|
|
46
45
|
super(agentIdentifier, aggregator, _constants.FEATURE_NAME);
|
|
47
|
-
|
|
48
46
|
/** Each page mutation or event will be stored (raw) in this array. This array will be cleared on each harvest */
|
|
49
47
|
this.events = [];
|
|
50
48
|
/** The interval to harvest at. This gets overridden if the size of the payload exceeds certain thresholds */
|
|
51
49
|
this.harvestTimeSeconds = (0, _config.getConfigurationValue)(this.agentIdentifier, 'session_replay.harvestTimeSeconds') || 60;
|
|
52
50
|
/** Set once the recorder has fully initialized after flag checks and sampling */
|
|
53
51
|
this.initialized = false;
|
|
54
|
-
/** Set once an error has been detected on the page. */
|
|
52
|
+
/** Set once an error has been detected on the page. Never unset */
|
|
55
53
|
this.errorNoticed = false;
|
|
56
54
|
/** The "mode" to record in. Defaults to "OFF" until flags and sampling are checked. See "MODE" constant. */
|
|
57
|
-
this.mode = MODE.OFF;
|
|
55
|
+
this.mode = _sessionEntity.MODE.OFF;
|
|
58
56
|
/** Set once the feature has been "aborted" to prevent other side-effects from continuing */
|
|
59
57
|
this.blocked = false;
|
|
58
|
+
/** True when actively recording, false when paused or stopped */
|
|
59
|
+
this.recording = false;
|
|
60
|
+
/** can shut off efforts to compress the data */
|
|
61
|
+
this.shouldCompress = true;
|
|
60
62
|
|
|
61
63
|
/** Payload metadata -- Should indicate that the payload being sent is the first of a session */
|
|
62
64
|
this.isFirstChunk = false;
|
|
@@ -70,62 +72,61 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
70
72
|
|
|
71
73
|
/** A value which increments with every new mutation node reported. Resets after a harvest is sent */
|
|
72
74
|
this.payloadBytesEstimation = 0;
|
|
75
|
+
const shouldSetup = (0, _config.getConfigurationValue)(agentIdentifier, 'privacy.cookies_enabled') === true && (0, _config.getConfigurationValue)(agentIdentifier, 'session_trace.enabled') === true;
|
|
73
76
|
|
|
74
77
|
/** The method to stop recording. This defaults to a noop, but is overwritten once the recording library is imported and initialized */
|
|
75
78
|
this.stopRecording = () => {/* no-op until set by rrweb initializer */};
|
|
79
|
+
if (shouldSetup) {
|
|
80
|
+
// The SessionEntity class can emit a message indicating the session was cleared and reset (expiry, inactivity). This feature must abort and never resume if that occurs.
|
|
81
|
+
this.ee.on(_sessionEntity.SESSION_EVENTS.RESET, () => {
|
|
82
|
+
this.abort();
|
|
83
|
+
});
|
|
76
84
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
85
|
+
// The SessionEntity class can emit a message indicating the session was paused (visibility change). This feature must stop recording if that occurs.
|
|
86
|
+
this.ee.on(_sessionEntity.SESSION_EVENTS.PAUSE, () => {
|
|
87
|
+
this.stopRecording();
|
|
88
|
+
});
|
|
89
|
+
// The SessionEntity class can emit a message indicating the session was resumed (visibility change). This feature must start running again (if already running) if that occurs.
|
|
90
|
+
this.ee.on(_sessionEntity.SESSION_EVENTS.RESUME, () => {
|
|
91
|
+
if (!this.initialized || this.mode === _sessionEntity.MODE.OFF) return;
|
|
92
|
+
this.startRecording();
|
|
93
|
+
});
|
|
81
94
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
this.startRecording();
|
|
90
|
-
this.takeFullSnapshot();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
// Bespoke logic for new endpoint. This will change as downstream dependencies become solidified.
|
|
94
|
-
this.scheduler = new _harvestScheduler.HarvestScheduler('blob', {
|
|
95
|
-
onFinished: this.onHarvestFinished.bind(this),
|
|
96
|
-
retryDelay: this.harvestTimeSeconds,
|
|
97
|
-
getPayload: this.prepareHarvest.bind(this),
|
|
98
|
-
raw: true
|
|
99
|
-
}, this);
|
|
95
|
+
// Bespoke logic for new endpoint. This will change as downstream dependencies become solidified.
|
|
96
|
+
this.scheduler = new _harvestScheduler.HarvestScheduler('blob', {
|
|
97
|
+
onFinished: this.onHarvestFinished.bind(this),
|
|
98
|
+
retryDelay: this.harvestTimeSeconds,
|
|
99
|
+
getPayload: this.prepareHarvest.bind(this),
|
|
100
|
+
raw: true
|
|
101
|
+
}, this);
|
|
100
102
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
this.mode
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
this.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
103
|
+
// Wait for an error to be reported. This currently is wrapped around the "Error" feature. This is a feature-feature dependency.
|
|
104
|
+
// This was to ensure that all errors, including those on the page before load and those handled with "noticeError" are accounted for. Needs evalulation
|
|
105
|
+
(0, _registerHandler.registerHandler)('errorAgg', e => {
|
|
106
|
+
this.hasError = true;
|
|
107
|
+
this.errorNoticed = true;
|
|
108
|
+
// run once
|
|
109
|
+
if (this.mode === _sessionEntity.MODE.ERROR) {
|
|
110
|
+
this.mode = _sessionEntity.MODE.FULL;
|
|
111
|
+
// if the error was noticed AFTER the recorder was already imported....
|
|
112
|
+
if (recorder && this.initialized) {
|
|
113
|
+
this.stopRecording();
|
|
114
|
+
this.startRecording();
|
|
115
|
+
this.scheduler.startTimer(this.harvestTimeSeconds);
|
|
116
|
+
const {
|
|
117
|
+
session
|
|
118
|
+
} = (0, _config.getRuntime)(this.agentIdentifier);
|
|
119
|
+
session.state.sessionReplay = this.mode;
|
|
120
|
+
}
|
|
117
121
|
}
|
|
118
|
-
}
|
|
119
|
-
|
|
122
|
+
}, this.featureName, this.ee);
|
|
123
|
+
this.waitForFlags(['sr']).then(_ref => {
|
|
124
|
+
let [flagOn] = _ref;
|
|
125
|
+
return this.initializeRecording(flagOn, Math.random() < (0, _config.getConfigurationValue)(this.agentIdentifier, 'session_replay.errorSampleRate'), Math.random() < (0, _config.getConfigurationValue)(this.agentIdentifier, 'session_replay.sampleRate'));
|
|
126
|
+
}).then(() => _sharedChannel.sharedChannel.onReplayReady(this.mode)); // notify watchers that replay started with the mode
|
|
120
127
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
let [{
|
|
124
|
-
value
|
|
125
|
-
}] = _ref;
|
|
126
|
-
this.initializeRecording(value, Math.random() < (0, _config.getConfigurationValue)(this.agentIdentifier, 'session_replay.errorSampleRate'), Math.random() < (0, _config.getConfigurationValue)(this.agentIdentifier, 'session_replay.sampleRate'));
|
|
127
|
-
});
|
|
128
|
-
(0, _drain.drain)(this.agentIdentifier, this.featureName);
|
|
128
|
+
(0, _drain.drain)(this.agentIdentifier, this.featureName);
|
|
129
|
+
}
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
/**
|
|
@@ -152,46 +153,53 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
152
153
|
this.mode = session.state.sessionReplay;
|
|
153
154
|
} else {
|
|
154
155
|
// The session is new... determine the mode the new session should start in
|
|
155
|
-
if (fullSample) this.mode = MODE.FULL; // full mode has precedence over error mode
|
|
156
|
-
else if (errorSample) this.mode = MODE.ERROR;
|
|
156
|
+
if (fullSample) this.mode = _sessionEntity.MODE.FULL; // full mode has precedence over error mode
|
|
157
|
+
else if (errorSample) this.mode = _sessionEntity.MODE.ERROR;
|
|
157
158
|
// If neither are selected, then don't record (early return)
|
|
158
159
|
else return;
|
|
159
160
|
}
|
|
160
161
|
|
|
162
|
+
// If an error was noticed before the mode could be set (like in the early lifecycle of the page), immediately set to FULL mode
|
|
163
|
+
if (this.mode === _sessionEntity.MODE.ERROR && this.errorNoticed) {
|
|
164
|
+
this.mode = _sessionEntity.MODE.FULL;
|
|
165
|
+
}
|
|
166
|
+
|
|
161
167
|
// FULL mode records AND reports from the beginning, while ERROR mode only records (but does not report).
|
|
162
168
|
// ERROR mode will do this until an error is thrown, and then switch into FULL mode.
|
|
163
169
|
// If an error happened in ERROR mode before we've gotten to this stage, it will have already set the mode to FULL
|
|
164
|
-
if (this.mode === MODE.FULL) {
|
|
170
|
+
if (this.mode === _sessionEntity.MODE.FULL) {
|
|
165
171
|
// We only report (harvest) in FULL mode
|
|
166
172
|
this.scheduler.startTimer(this.harvestTimeSeconds);
|
|
167
173
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
this.
|
|
174
|
+
try {
|
|
175
|
+
recorder = (await Promise.resolve().then(() => _interopRequireWildcard(require( /* webpackChunkName: "recorder" */'rrweb')))).record;
|
|
176
|
+
} catch (err) {
|
|
177
|
+
return this.abort();
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
const {
|
|
181
|
+
gzipSync,
|
|
182
|
+
strToU8
|
|
183
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require( /* webpackChunkName: "compressor" */'fflate')));
|
|
184
|
+
gzipper = gzipSync;
|
|
185
|
+
u8 = strToU8;
|
|
186
|
+
} catch (err) {
|
|
187
|
+
// compressor failed to load, but we can still record without compression as a last ditch effort
|
|
188
|
+
this.shouldCompress = false;
|
|
172
189
|
}
|
|
173
|
-
// We record in FULL or ERROR mode
|
|
174
|
-
|
|
175
|
-
recorder = (await Promise.resolve().then(() => _interopRequireWildcard(require( /* webpackChunkName: "recorder" */'rrweb')))).record;
|
|
176
190
|
this.startRecording();
|
|
177
|
-
const {
|
|
178
|
-
gzipSync,
|
|
179
|
-
strToU8
|
|
180
|
-
} = await Promise.resolve().then(() => _interopRequireWildcard(require( /* webpackChunkName: "compressor" */'fflate')));
|
|
181
|
-
gzipper = gzipSync;
|
|
182
|
-
u8 = strToU8;
|
|
183
191
|
this.isFirstChunk = !!session.isNew;
|
|
184
192
|
session.state.sessionReplay = this.mode;
|
|
185
193
|
}
|
|
186
|
-
prepareHarvest(
|
|
194
|
+
prepareHarvest() {
|
|
187
195
|
if (this.events.length === 0) return;
|
|
188
196
|
const payload = this.getHarvestContents();
|
|
189
|
-
|
|
197
|
+
if (this.shouldCompress) {
|
|
190
198
|
payload.body = gzipper(u8((0, _stringify.stringify)(payload.body)));
|
|
191
199
|
this.scheduler.opts.gzip = true;
|
|
192
|
-
}
|
|
193
|
-
// failed to gzip
|
|
200
|
+
} else {
|
|
194
201
|
this.scheduler.opts.gzip = false;
|
|
202
|
+
delete payload.qs.content_encoding;
|
|
195
203
|
}
|
|
196
204
|
// TODO -- Gracefully handle the buffer for retries.
|
|
197
205
|
this.clearBuffer();
|
|
@@ -258,7 +266,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
258
266
|
this.hasSnapshot = true;
|
|
259
267
|
// set up rrweb configurations for maximum privacy --
|
|
260
268
|
// https://newrelic.atlassian.net/wiki/spaces/O11Y/pages/2792293280/2023+02+28+Browser+-+Session+Replay#Configuration-options
|
|
261
|
-
|
|
269
|
+
const stop = recorder({
|
|
262
270
|
emit: this.store.bind(this),
|
|
263
271
|
blockClass,
|
|
264
272
|
ignoreClass,
|
|
@@ -267,10 +275,15 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
267
275
|
maskInputOptions,
|
|
268
276
|
maskTextSelector,
|
|
269
277
|
maskAllInputs,
|
|
270
|
-
...(this.mode === MODE.ERROR && {
|
|
278
|
+
...(this.mode === _sessionEntity.MODE.ERROR && {
|
|
271
279
|
checkoutEveryNms: CHECKOUT_MS
|
|
272
280
|
})
|
|
273
281
|
});
|
|
282
|
+
this.recording = true;
|
|
283
|
+
this.stopRecording = () => {
|
|
284
|
+
this.recording = false;
|
|
285
|
+
stop();
|
|
286
|
+
};
|
|
274
287
|
}
|
|
275
288
|
|
|
276
289
|
/** Store a payload in the buffer (this.events). This should be the callback to the recording lib noticing a mutation */
|
|
@@ -281,12 +294,13 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
281
294
|
const payloadSize = this.getPayloadSize(eventBytes);
|
|
282
295
|
// Vortex will block payloads at a certain size, we might as well not send.
|
|
283
296
|
if (payloadSize > MAX_PAYLOAD_SIZE) {
|
|
297
|
+
this.clearBuffer();
|
|
284
298
|
return this.abort();
|
|
285
299
|
}
|
|
286
300
|
// Checkout events are flags by the recording lib that indicate a fullsnapshot was taken every n ms. These are important
|
|
287
301
|
// to help reconstruct the replay later and must be included. While waiting and buffering for errors to come through,
|
|
288
302
|
// each time we see a new checkout, we can drop the old data.
|
|
289
|
-
if (this.mode === MODE.ERROR && isCheckout) {
|
|
303
|
+
if (this.mode === _sessionEntity.MODE.ERROR && isCheckout) {
|
|
290
304
|
// we are still waiting for an error to throw, so keep wiping the buffer over time
|
|
291
305
|
this.clearBuffer();
|
|
292
306
|
}
|
|
@@ -318,7 +332,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
318
332
|
/** Abort the feature, once aborted it will not resume */
|
|
319
333
|
abort() {
|
|
320
334
|
this.blocked = true;
|
|
335
|
+
this.mode = _sessionEntity.MODE.OFF;
|
|
321
336
|
this.stopRecording();
|
|
337
|
+
this.ee.emit('REPLAY_ABORTED');
|
|
322
338
|
const {
|
|
323
339
|
session
|
|
324
340
|
} = (0, _config.getRuntime)(this.agentIdentifier);
|
|
@@ -330,7 +346,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
330
346
|
* https://staging.onenr.io/037jbJWxbjy
|
|
331
347
|
* */
|
|
332
348
|
estimateCompression(data) {
|
|
333
|
-
return data *
|
|
349
|
+
if (this.shouldCompress) return data * AVG_COMPRESSION;
|
|
350
|
+
return data;
|
|
334
351
|
}
|
|
335
352
|
}
|
|
336
353
|
exports.Aggregate = Aggregate;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getSessionReplayMode = getSessionReplayMode;
|
|
7
|
+
var _config = require("../../common/config/config");
|
|
8
|
+
var _sessionEntity = require("../../common/session/session-entity");
|
|
9
|
+
var _nreum = require("../../common/window/nreum");
|
|
10
|
+
var _sharedChannel = require("../../common/constants/shared-channel");
|
|
11
|
+
/**
|
|
12
|
+
* Figure out if the Replay feature is running (what mode it's in).
|
|
13
|
+
* IMPORTANT: Session tracking is assumed to be ON; if applicable, check init's privacy.cookies_enabled setting before using this fn!
|
|
14
|
+
* CRITICAL: This fn must be called prior to ALL features aggregate draining. If not, it will never resolve.
|
|
15
|
+
* @param {String} agentId
|
|
16
|
+
* @returns Promise that resolves to one of the values in MODE enum
|
|
17
|
+
*/
|
|
18
|
+
async function getSessionReplayMode(agentId) {
|
|
19
|
+
try {
|
|
20
|
+
const newrelic = (0, _nreum.gosNREUM)();
|
|
21
|
+
// Should be enabled by configuration and using an agent build that includes it (via checking that the instrument class was initialized).
|
|
22
|
+
if ((0, _config.getConfigurationValue)(agentId, 'session_replay.enabled') && typeof newrelic.initializedAgents[agentId].features.session_replay === 'object') {
|
|
23
|
+
await newrelic.initializedAgents[agentId].features.session_replay.onAggregateImported; // if Replay could not initialize, this throws a (uncaught) rejection
|
|
24
|
+
return await _sharedChannel.sharedChannel.sessionReplayInitialized; // wait for replay to determine which mode it's after running its sampling logic
|
|
25
|
+
}
|
|
26
|
+
} catch (e) {/* exception ==> off */}
|
|
27
|
+
return _sessionEntity.MODE.OFF; // at any step of the way s.t. SR cannot be on by implication or is explicitly off
|
|
28
|
+
}
|