@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.
Files changed (273) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/common/constants/env.cdn.js +1 -1
  3. package/dist/cjs/common/constants/env.npm.js +1 -1
  4. package/dist/cjs/common/constants/shared-channel.js +19 -0
  5. package/dist/cjs/common/event-emitter/contextual-ee.test.js +10 -10
  6. package/dist/cjs/common/harvest/{harvest-scheduler.test.js → harvest-scheduler.component-test.js} +2 -2
  7. package/dist/cjs/common/harvest/harvest-scheduler.js +21 -5
  8. package/dist/cjs/common/harvest/harvest.component-test.js +224 -0
  9. package/dist/cjs/common/harvest/harvest.js +4 -11
  10. package/dist/cjs/common/session/{session-entity.test.js → session-entity.component-test.js} +79 -42
  11. package/dist/cjs/common/session/session-entity.js +19 -11
  12. package/dist/cjs/common/timer/interaction-timer.js +1 -1
  13. package/dist/cjs/common/url/canonicalize-url.test.js +26 -30
  14. package/dist/cjs/common/url/encode.js +2 -2
  15. package/dist/cjs/common/util/console.test.js +30 -0
  16. package/dist/cjs/common/util/data-size.test.js +37 -20
  17. package/dist/cjs/common/util/feature-flags.js +23 -12
  18. package/dist/cjs/common/util/feature-flags.test.js +84 -0
  19. package/dist/cjs/common/util/get-or-set.js +8 -1
  20. package/dist/cjs/common/util/get-or-set.test.js +47 -0
  21. package/dist/cjs/common/util/global-scope.js +1 -32
  22. package/dist/cjs/common/util/global-scope.test.js +72 -0
  23. package/dist/cjs/common/util/obfuscate.component-test.js +129 -0
  24. package/dist/cjs/common/util/obfuscate.js +2 -2
  25. package/dist/cjs/common/util/stringify.test.js +48 -0
  26. package/dist/cjs/common/util/submit-data.js +18 -18
  27. package/dist/cjs/common/util/submit-data.test.js +245 -0
  28. package/dist/cjs/common/util/traverse.js +19 -27
  29. package/dist/cjs/common/util/traverse.test.js +44 -0
  30. package/dist/cjs/common/wrap/wrap-raf.js +1 -1
  31. package/dist/cjs/common/wrap/wrap-timer.js +1 -1
  32. package/dist/cjs/features/jserrors/aggregate/index.js +4 -0
  33. package/dist/cjs/features/jserrors/instrument/index.js +2 -15
  34. package/dist/cjs/features/metrics/aggregate/endpoint-map.js +14 -0
  35. package/dist/cjs/features/metrics/aggregate/index.js +3 -2
  36. package/dist/cjs/features/metrics/instrument/index.js +0 -2
  37. package/dist/cjs/features/page_view_event/aggregate/index.js +58 -44
  38. package/dist/cjs/features/session_replay/aggregate/index.component-test.js +457 -0
  39. package/dist/cjs/features/session_replay/aggregate/index.js +99 -82
  40. package/dist/cjs/features/session_replay/replay-mode.js +28 -0
  41. package/dist/cjs/features/session_trace/aggregate/index.js +222 -99
  42. package/dist/cjs/features/session_trace/constants.js +1 -3
  43. package/dist/cjs/features/session_trace/instrument/index.js +0 -16
  44. package/dist/cjs/features/spa/constants.js +0 -1
  45. package/dist/cjs/features/utils/agent-session.js +20 -36
  46. package/dist/cjs/features/utils/agent-session.test.js +211 -0
  47. package/dist/cjs/features/utils/aggregate-base.js +7 -12
  48. package/dist/cjs/features/utils/aggregate-base.test.js +110 -0
  49. package/dist/cjs/features/utils/feature-base.test.js +42 -0
  50. package/dist/cjs/features/utils/handler-cache.js +28 -23
  51. package/dist/cjs/features/utils/handler-cache.test.js +53 -0
  52. package/dist/cjs/features/utils/instrument-base.js +58 -39
  53. package/dist/cjs/features/utils/instrument-base.test.js +179 -0
  54. package/dist/cjs/features/utils/lazy-feature-loader.test.js +30 -0
  55. package/dist/cjs/loaders/agent.js +0 -1
  56. package/dist/cjs/loaders/api/api.js +1 -1
  57. package/dist/cjs/loaders/configure/configure.js +0 -1
  58. package/dist/cjs/loaders/features/featureDependencies.js +2 -0
  59. package/dist/esm/common/constants/env.cdn.js +1 -1
  60. package/dist/esm/common/constants/env.npm.js +1 -1
  61. package/dist/esm/common/constants/shared-channel.js +12 -0
  62. package/dist/esm/common/event-emitter/contextual-ee.test.js +10 -10
  63. package/dist/esm/common/harvest/{harvest-scheduler.test.js → harvest-scheduler.component-test.js} +2 -2
  64. package/dist/esm/common/harvest/harvest-scheduler.js +21 -5
  65. package/dist/esm/common/harvest/harvest.component-test.js +222 -0
  66. package/dist/esm/common/harvest/harvest.js +4 -11
  67. package/dist/esm/common/session/{session-entity.test.js → session-entity.component-test.js} +77 -40
  68. package/dist/esm/common/session/session-entity.js +17 -11
  69. package/dist/esm/common/timer/interaction-timer.js +1 -1
  70. package/dist/esm/common/url/canonicalize-url.test.js +25 -29
  71. package/dist/esm/common/url/encode.js +2 -2
  72. package/dist/esm/common/util/console.test.js +28 -0
  73. package/dist/esm/common/util/data-size.test.js +35 -20
  74. package/dist/esm/common/util/feature-flags.js +23 -12
  75. package/dist/esm/common/util/feature-flags.test.js +80 -0
  76. package/dist/esm/common/util/get-or-set.js +8 -1
  77. package/dist/esm/common/util/get-or-set.test.js +45 -0
  78. package/dist/esm/common/util/global-scope.js +1 -29
  79. package/dist/esm/common/util/global-scope.test.js +70 -0
  80. package/dist/esm/common/util/obfuscate.component-test.js +125 -0
  81. package/dist/esm/common/util/obfuscate.js +2 -2
  82. package/dist/esm/common/util/stringify.test.js +46 -0
  83. package/dist/esm/common/util/submit-data.js +18 -18
  84. package/dist/esm/common/util/submit-data.test.js +241 -0
  85. package/dist/esm/common/util/traverse.js +19 -27
  86. package/dist/esm/common/util/traverse.test.js +42 -0
  87. package/dist/esm/common/wrap/wrap-raf.js +1 -1
  88. package/dist/esm/common/wrap/wrap-timer.js +1 -1
  89. package/dist/esm/features/jserrors/aggregate/index.js +4 -0
  90. package/dist/esm/features/jserrors/instrument/index.js +2 -15
  91. package/dist/esm/features/metrics/aggregate/endpoint-map.js +7 -0
  92. package/dist/esm/features/metrics/aggregate/index.js +3 -2
  93. package/dist/esm/features/metrics/instrument/index.js +0 -2
  94. package/dist/esm/features/page_view_event/aggregate/index.js +58 -44
  95. package/dist/esm/features/session_replay/aggregate/index.component-test.js +453 -0
  96. package/dist/esm/features/session_replay/aggregate/index.js +92 -78
  97. package/dist/esm/features/session_replay/replay-mode.js +23 -0
  98. package/dist/esm/features/session_trace/aggregate/index.js +223 -100
  99. package/dist/esm/features/session_trace/constants.js +0 -1
  100. package/dist/esm/features/session_trace/instrument/index.js +1 -17
  101. package/dist/esm/features/spa/constants.js +0 -1
  102. package/dist/esm/features/utils/agent-session.js +21 -37
  103. package/dist/esm/features/utils/agent-session.test.js +207 -0
  104. package/dist/esm/features/utils/aggregate-base.js +7 -12
  105. package/dist/esm/features/utils/aggregate-base.test.js +108 -0
  106. package/dist/esm/features/utils/feature-base.test.js +40 -0
  107. package/dist/esm/features/utils/handler-cache.js +28 -23
  108. package/dist/esm/features/utils/handler-cache.test.js +51 -0
  109. package/dist/esm/features/utils/instrument-base.js +58 -39
  110. package/dist/esm/features/utils/instrument-base.test.js +175 -0
  111. package/dist/esm/features/utils/lazy-feature-loader.test.js +29 -0
  112. package/dist/esm/loaders/agent.js +0 -1
  113. package/dist/esm/loaders/api/api.js +2 -2
  114. package/dist/esm/loaders/configure/configure.js +0 -1
  115. package/dist/esm/loaders/features/featureDependencies.js +2 -0
  116. package/dist/types/common/config/state/init.d.ts.map +1 -1
  117. package/dist/types/common/constants/shared-channel.d.ts +5 -0
  118. package/dist/types/common/constants/shared-channel.d.ts.map +1 -0
  119. package/dist/types/common/context/shared-context.d.ts.map +1 -1
  120. package/dist/types/common/harvest/harvest-scheduler.component-test.d.ts +2 -0
  121. package/dist/types/common/harvest/harvest-scheduler.component-test.d.ts.map +1 -0
  122. package/dist/types/common/harvest/harvest-scheduler.d.ts +4 -0
  123. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
  124. package/dist/types/common/harvest/harvest.component-test.d.ts +2 -0
  125. package/dist/types/common/harvest/harvest.component-test.d.ts.map +1 -0
  126. package/dist/types/common/harvest/harvest.d.ts.map +1 -1
  127. package/dist/types/common/session/session-entity.component-test.d.ts +2 -0
  128. package/dist/types/common/session/session-entity.component-test.d.ts.map +1 -0
  129. package/dist/types/common/session/session-entity.d.ts +9 -5
  130. package/dist/types/common/session/session-entity.d.ts.map +1 -1
  131. package/dist/types/common/timer/interaction-timer.component-test.d.ts +2 -0
  132. package/dist/types/common/timer/interaction-timer.component-test.d.ts.map +1 -0
  133. package/dist/types/common/timer/timer.d.ts.map +1 -1
  134. package/dist/types/common/url/encode.component-test.d.ts +2 -0
  135. package/dist/types/common/url/encode.component-test.d.ts.map +1 -0
  136. package/dist/types/common/url/protocol.component-test.d.ts +2 -0
  137. package/dist/types/common/url/protocol.component-test.d.ts.map +1 -0
  138. package/dist/types/common/util/feature-flags.d.ts +1 -0
  139. package/dist/types/common/util/feature-flags.d.ts.map +1 -1
  140. package/dist/types/common/util/get-or-set.d.ts +9 -1
  141. package/dist/types/common/util/get-or-set.d.ts.map +1 -1
  142. package/dist/types/common/util/global-scope.d.ts +0 -9
  143. package/dist/types/common/util/global-scope.d.ts.map +1 -1
  144. package/dist/types/common/util/obfuscate.component-test.d.ts +2 -0
  145. package/dist/types/common/util/obfuscate.component-test.d.ts.map +1 -0
  146. package/dist/types/common/util/submit-data.d.ts +14 -10
  147. package/dist/types/common/util/submit-data.d.ts.map +1 -1
  148. package/dist/types/common/util/traverse.d.ts +10 -1
  149. package/dist/types/common/util/traverse.d.ts.map +1 -1
  150. package/dist/types/common/window/nreum.d.ts.map +1 -1
  151. package/dist/types/features/jserrors/aggregate/index.d.ts +1 -0
  152. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  153. package/dist/types/features/metrics/aggregate/endpoint-map.d.ts +8 -0
  154. package/dist/types/features/metrics/aggregate/endpoint-map.d.ts.map +1 -0
  155. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  156. package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts.map +1 -1
  157. package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
  158. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  159. package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
  160. package/dist/types/features/session_replay/aggregate/index.component-test.d.ts +2 -0
  161. package/dist/types/features/session_replay/aggregate/index.component-test.d.ts.map +1 -0
  162. package/dist/types/features/session_replay/aggregate/index.d.ts +14 -5
  163. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  164. package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
  165. package/dist/types/features/session_replay/replay-mode.d.ts +9 -0
  166. package/dist/types/features/session_replay/replay-mode.d.ts.map +1 -0
  167. package/dist/types/features/session_trace/aggregate/index.d.ts +21 -3
  168. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  169. package/dist/types/features/session_trace/constants.d.ts +0 -1
  170. package/dist/types/features/session_trace/constants.d.ts.map +1 -1
  171. package/dist/types/features/session_trace/instrument/index.d.ts +0 -2
  172. package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
  173. package/dist/types/features/spa/constants.d.ts.map +1 -1
  174. package/dist/types/features/utils/agent-session.d.ts.map +1 -1
  175. package/dist/types/features/utils/aggregate-base.d.ts +6 -1
  176. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  177. package/dist/types/features/utils/handler-cache.d.ts +12 -11
  178. package/dist/types/features/utils/handler-cache.d.ts.map +1 -1
  179. package/dist/types/features/utils/instrument-base.d.ts +17 -1
  180. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  181. package/dist/types/loaders/agent.d.ts.map +1 -1
  182. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  183. package/dist/types/loaders/features/featureDependencies.d.ts.map +1 -1
  184. package/package.json +14 -8
  185. package/src/common/config/state/init.js +0 -1
  186. package/src/common/constants/shared-channel.js +13 -0
  187. package/src/common/context/shared-context.js +0 -1
  188. package/src/common/event-emitter/contextual-ee.test.js +10 -10
  189. package/src/common/harvest/{harvest-scheduler.test.js → harvest-scheduler.component-test.js} +2 -2
  190. package/src/common/harvest/harvest-scheduler.js +17 -6
  191. package/src/common/harvest/harvest.component-test.js +169 -0
  192. package/src/common/harvest/harvest.js +5 -9
  193. package/src/common/session/{session-entity.test.js → session-entity.component-test.js} +70 -48
  194. package/src/common/session/session-entity.js +15 -12
  195. package/src/common/timer/interaction-timer.js +1 -1
  196. package/src/common/timer/timer.js +0 -1
  197. package/src/common/url/canonicalize-url.test.js +32 -21
  198. package/src/common/url/encode.js +2 -2
  199. package/src/common/util/console.test.js +34 -0
  200. package/src/common/util/data-size.test.js +27 -20
  201. package/src/common/util/feature-flags.js +24 -12
  202. package/src/common/util/feature-flags.test.js +98 -0
  203. package/src/common/util/get-or-set.js +8 -1
  204. package/src/common/util/get-or-set.test.js +58 -0
  205. package/src/common/util/global-scope.js +0 -26
  206. package/src/common/util/global-scope.test.js +87 -0
  207. package/src/common/util/obfuscate.component-test.js +173 -0
  208. package/src/common/util/obfuscate.js +2 -2
  209. package/src/common/util/stringify.test.js +49 -0
  210. package/src/common/util/submit-data.js +18 -19
  211. package/src/common/util/submit-data.test.js +226 -0
  212. package/src/common/util/traverse.js +18 -27
  213. package/src/common/util/traverse.test.js +50 -0
  214. package/src/common/window/nreum.js +0 -1
  215. package/src/common/wrap/wrap-raf.js +1 -1
  216. package/src/common/wrap/wrap-timer.js +1 -1
  217. package/src/features/jserrors/aggregate/index.js +5 -0
  218. package/src/features/jserrors/instrument/index.js +2 -15
  219. package/src/features/metrics/aggregate/endpoint-map.js +7 -0
  220. package/src/features/metrics/aggregate/index.js +3 -2
  221. package/src/features/metrics/aggregate/polyfill-detection.es5.js +0 -1
  222. package/src/features/metrics/instrument/index.js +0 -2
  223. package/src/features/page_view_event/aggregate/index.js +48 -51
  224. package/src/features/page_view_event/instrument/index.js +0 -1
  225. package/src/features/session_replay/aggregate/index.component-test.js +368 -0
  226. package/src/features/session_replay/aggregate/index.js +96 -71
  227. package/src/features/session_replay/instrument/index.js +0 -1
  228. package/src/features/session_replay/replay-mode.js +23 -0
  229. package/src/features/session_trace/aggregate/index.js +198 -79
  230. package/src/features/session_trace/constants.js +0 -1
  231. package/src/features/session_trace/instrument/index.js +2 -19
  232. package/src/features/spa/constants.js +0 -1
  233. package/src/features/utils/agent-session.js +22 -34
  234. package/src/features/utils/agent-session.test.js +194 -0
  235. package/src/features/utils/aggregate-base.js +12 -9
  236. package/src/features/utils/aggregate-base.test.js +122 -0
  237. package/src/features/utils/feature-base.test.js +45 -0
  238. package/src/features/utils/handler-cache.js +29 -24
  239. package/src/features/utils/handler-cache.test.js +72 -0
  240. package/src/features/utils/instrument-base.js +45 -29
  241. package/src/features/utils/instrument-base.test.js +190 -0
  242. package/src/features/utils/lazy-feature-loader.test.js +37 -0
  243. package/src/loaders/agent.js +0 -1
  244. package/src/loaders/api/api.js +2 -2
  245. package/src/loaders/configure/configure.js +0 -1
  246. package/src/loaders/features/featureDependencies.js +2 -0
  247. package/dist/cjs/common/storage/local-memory.js +0 -35
  248. package/dist/cjs/common/storage/local-memory.test.js +0 -20
  249. package/dist/cjs/common/util/s-hash.js +0 -19
  250. package/dist/cjs/features/metrics/instrument/workers-helper.js +0 -124
  251. package/dist/esm/common/storage/local-memory.js +0 -28
  252. package/dist/esm/common/storage/local-memory.test.js +0 -18
  253. package/dist/esm/common/util/s-hash.js +0 -13
  254. package/dist/esm/features/metrics/instrument/workers-helper.js +0 -119
  255. package/dist/types/common/storage/local-memory.d.ts +0 -8
  256. package/dist/types/common/storage/local-memory.d.ts.map +0 -1
  257. package/dist/types/common/util/s-hash.d.ts +0 -2
  258. package/dist/types/common/util/s-hash.d.ts.map +0 -1
  259. package/dist/types/features/metrics/instrument/workers-helper.d.ts +0 -7
  260. package/dist/types/features/metrics/instrument/workers-helper.d.ts.map +0 -1
  261. package/src/common/storage/local-memory.js +0 -30
  262. package/src/common/storage/local-memory.test.js +0 -19
  263. package/src/common/util/s-hash.js +0 -14
  264. package/src/features/metrics/instrument/workers-helper.js +0 -113
  265. /package/dist/cjs/common/timer/{interaction-timer.test.js → interaction-timer.component-test.js} +0 -0
  266. /package/dist/cjs/common/url/{encode.test.js → encode.component-test.js} +0 -0
  267. /package/dist/cjs/common/url/{protocol.test.js → protocol.component-test.js} +0 -0
  268. /package/dist/esm/common/timer/{interaction-timer.test.js → interaction-timer.component-test.js} +0 -0
  269. /package/dist/esm/common/url/{encode.test.js → encode.component-test.js} +0 -0
  270. /package/dist/esm/common/url/{protocol.test.js → protocol.component-test.js} +0 -0
  271. /package/src/common/timer/{interaction-timer.test.js → interaction-timer.component-test.js} +0 -0
  272. /package/src/common/url/{encode.test.js → encode.component-test.js} +0 -0
  273. /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
- // 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.
78
- this.ee.on('session-reset', () => {
79
- this.abort();
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
- // The SessionEntity class can emit a message indicating the session was paused (visibility change). This feature must stop recording if that occurs.
83
- this.ee.on(_sessionEntity.SESSION_EVENTS.PAUSE, () => {
84
- this.stopRecording();
85
- });
86
- // 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.
87
- this.ee.on(_sessionEntity.SESSION_EVENTS.RESUME, () => {
88
- if (!this.initialized || this.mode === MODE.OFF) return;
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
- // Wait for an error to be reported. This currently is wrapped around the "Error" feature. This is a feature-feature dependency.
102
- // This was to ensure that all errors, including those on the page before load and those handled with "noticeError" are accounted for. Needs evalulation
103
- (0, _registerHandler.registerHandler)('errorAgg', e => {
104
- this.hasError = true;
105
- // run once
106
- if (this.mode === MODE.ERROR) {
107
- this.mode = MODE.FULL;
108
- // if the error was noticed AFTER the recorder was already imported....
109
- if (recorder && this.initialized) {
110
- this.stopRecording();
111
- this.startRecording();
112
- this.scheduler.startTimer(this.harvestTimeSeconds);
113
- const {
114
- session
115
- } = (0, _config.getRuntime)(this.agentIdentifier);
116
- session.state.sessionReplay = this.mode;
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
- }, this.featureName, this.ee);
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
- // new handler for waiting for multiple flags. will be useful if/when backend designs multiple flags, or for evaluating multiple feature flags simultaneously (stn vs sr)
122
- this.waitForFlags(['sr']).then(_ref => {
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
- // If an error was noticed before the mode could be set (like in the early lifecycle of the page), immediately set to FULL mode
170
- if (this.mode === MODE.ERROR && this.errorNoticed) {
171
- this.mode = MODE.FULL;
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(options) {
194
+ prepareHarvest() {
187
195
  if (this.events.length === 0) return;
188
196
  const payload = this.getHarvestContents();
189
- try {
197
+ if (this.shouldCompress) {
190
198
  payload.body = gzipper(u8((0, _stringify.stringify)(payload.body)));
191
199
  this.scheduler.opts.gzip = true;
192
- } catch (err) {
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
- this.stopRecording = recorder({
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 * 0.12;
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
+ }