@newrelic/browser-agent 0.1.231 → 1.232.1

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 (256) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/common/config/state/configurable.js +27 -21
  3. package/dist/cjs/common/config/state/init.js +8 -0
  4. package/dist/cjs/common/config/state/runtime.js +24 -26
  5. package/dist/cjs/common/constants/env.cdn.js +1 -1
  6. package/dist/cjs/common/constants/env.npm.js +1 -1
  7. package/dist/cjs/common/context/shared-context.js +2 -1
  8. package/dist/cjs/common/event-emitter/contextual-ee.test.js +2 -2
  9. package/dist/cjs/common/event-emitter/register-handler.test.js +1 -1
  10. package/dist/cjs/common/event-listener/event-listener-opts.js +4 -2
  11. package/dist/cjs/common/harvest/harvest-scheduler.js +14 -11
  12. package/dist/cjs/common/harvest/harvest.js +3 -1
  13. package/dist/cjs/common/session/constants.js +12 -0
  14. package/dist/cjs/common/session/session-entity.js +278 -0
  15. package/dist/cjs/common/session/session-entity.test.js +436 -0
  16. package/dist/cjs/common/storage/first-party-cookies.js +35 -0
  17. package/dist/cjs/common/storage/local-memory.js +35 -0
  18. package/dist/cjs/common/storage/local-memory.test.js +20 -0
  19. package/dist/cjs/common/storage/local-storage.js +33 -0
  20. package/dist/cjs/common/storage/local-storage.test.js +14 -0
  21. package/dist/cjs/common/timer/interaction-timer.js +78 -0
  22. package/dist/cjs/common/timer/interaction-timer.test.js +216 -0
  23. package/dist/cjs/common/timer/timer.js +32 -0
  24. package/dist/cjs/common/timer/timer.test.js +105 -0
  25. package/dist/cjs/common/unload/eol.js +2 -2
  26. package/dist/cjs/common/url/canonicalize-url.js +32 -0
  27. package/dist/cjs/common/url/canonicalize-url.test.js +42 -0
  28. package/dist/cjs/common/url/clean-url.js +10 -3
  29. package/dist/cjs/common/util/data-size.js +6 -0
  30. package/dist/cjs/common/util/data-size.test.js +47 -0
  31. package/dist/cjs/common/util/global-scope.js +4 -2
  32. package/dist/cjs/common/util/invoke.js +73 -0
  33. package/dist/cjs/common/util/invoke.test.js +49 -0
  34. package/dist/cjs/common/util/obfuscate.js +0 -4
  35. package/dist/cjs/common/window/page-visibility.js +3 -1
  36. package/dist/cjs/common/wrap/wrap-fetch.js +1 -3
  37. package/dist/cjs/common/wrap/wrap-function.js +1 -3
  38. package/dist/cjs/common/wrap/wrap-timer.js +1 -1
  39. package/dist/cjs/features/ajax/aggregate/index.js +2 -2
  40. package/dist/cjs/features/ajax/instrument/index.js +1 -1
  41. package/dist/cjs/features/jserrors/aggregate/canonical-function-name.js +12 -4
  42. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +93 -10
  43. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +164 -38
  44. package/dist/cjs/features/jserrors/aggregate/index.js +25 -46
  45. package/dist/cjs/features/jserrors/instrument/index.js +0 -2
  46. package/dist/cjs/features/metrics/aggregate/index.js +13 -2
  47. package/dist/cjs/features/page_action/aggregate/index.js +2 -2
  48. package/dist/cjs/features/page_view_event/aggregate/index.js +6 -3
  49. package/dist/cjs/features/page_view_timing/aggregate/index.js +6 -6
  50. package/dist/cjs/features/session_trace/aggregate/index.js +3 -5
  51. package/dist/cjs/features/spa/aggregate/index.js +6 -5
  52. package/dist/cjs/features/utils/agent-session.js +73 -0
  53. package/dist/cjs/features/utils/feature-base.js +1 -1
  54. package/dist/cjs/features/utils/instrument-base.js +7 -2
  55. package/dist/cjs/features/utils/lazy-loader.js +1 -1
  56. package/dist/cjs/loaders/agent.js +1 -1
  57. package/dist/cjs/loaders/api/api.js +1 -4
  58. package/dist/cjs/loaders/api/apiAsync.js +3 -2
  59. package/dist/cjs/loaders/configure/configure.js +0 -6
  60. package/dist/esm/common/config/state/configurable.js +26 -20
  61. package/dist/esm/common/config/state/init.js +8 -0
  62. package/dist/esm/common/config/state/runtime.js +24 -26
  63. package/dist/esm/common/constants/env.cdn.js +1 -1
  64. package/dist/esm/common/constants/env.npm.js +1 -1
  65. package/dist/esm/common/context/shared-context.js +2 -1
  66. package/dist/esm/common/event-emitter/contextual-ee.test.js +2 -2
  67. package/dist/esm/common/event-emitter/register-handler.test.js +1 -1
  68. package/dist/esm/common/event-listener/event-listener-opts.js +4 -2
  69. package/dist/esm/common/harvest/harvest-scheduler.js +14 -11
  70. package/dist/esm/common/harvest/harvest.js +3 -1
  71. package/dist/esm/common/session/constants.js +3 -0
  72. package/dist/esm/common/session/session-entity.js +271 -0
  73. package/dist/esm/common/session/session-entity.test.js +434 -0
  74. package/dist/esm/common/storage/first-party-cookies.js +28 -0
  75. package/dist/esm/common/storage/local-memory.js +28 -0
  76. package/dist/esm/common/storage/local-memory.test.js +18 -0
  77. package/dist/esm/common/storage/local-storage.js +26 -0
  78. package/dist/esm/common/storage/local-storage.test.js +12 -0
  79. package/dist/esm/common/timer/interaction-timer.js +71 -0
  80. package/dist/esm/common/timer/interaction-timer.test.js +214 -0
  81. package/dist/esm/common/timer/timer.js +25 -0
  82. package/dist/esm/common/timer/timer.test.js +103 -0
  83. package/dist/esm/common/unload/eol.js +1 -1
  84. package/dist/esm/common/url/canonicalize-url.js +27 -0
  85. package/dist/esm/common/url/canonicalize-url.test.js +38 -0
  86. package/dist/esm/common/url/clean-url.js +10 -3
  87. package/dist/esm/common/util/data-size.js +7 -0
  88. package/dist/esm/common/util/data-size.test.js +45 -0
  89. package/dist/esm/common/util/global-scope.js +1 -0
  90. package/dist/esm/common/util/invoke.js +66 -0
  91. package/dist/esm/common/util/invoke.test.js +47 -0
  92. package/dist/esm/common/util/obfuscate.js +0 -4
  93. package/dist/esm/common/window/page-visibility.js +3 -1
  94. package/dist/esm/common/wrap/wrap-fetch.js +1 -2
  95. package/dist/esm/common/wrap/wrap-function.js +1 -2
  96. package/dist/esm/common/wrap/wrap-timer.js +1 -1
  97. package/dist/esm/features/ajax/aggregate/index.js +2 -2
  98. package/dist/esm/features/ajax/instrument/index.js +1 -1
  99. package/dist/esm/features/jserrors/aggregate/canonical-function-name.js +12 -4
  100. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +93 -10
  101. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +149 -25
  102. package/dist/esm/features/jserrors/aggregate/index.js +26 -46
  103. package/dist/esm/features/jserrors/instrument/index.js +0 -1
  104. package/dist/esm/features/metrics/aggregate/index.js +14 -3
  105. package/dist/esm/features/page_action/aggregate/index.js +2 -2
  106. package/dist/esm/features/page_view_event/aggregate/index.js +6 -3
  107. package/dist/esm/features/page_view_timing/aggregate/index.js +6 -6
  108. package/dist/esm/features/session_trace/aggregate/index.js +3 -4
  109. package/dist/esm/features/spa/aggregate/index.js +6 -5
  110. package/dist/esm/features/utils/agent-session.js +67 -0
  111. package/dist/esm/features/utils/feature-base.js +1 -1
  112. package/dist/esm/features/utils/instrument-base.js +7 -2
  113. package/dist/esm/features/utils/lazy-loader.js +1 -1
  114. package/dist/esm/loaders/agent.js +1 -1
  115. package/dist/esm/loaders/api/api.js +2 -5
  116. package/dist/esm/loaders/api/apiAsync.js +2 -1
  117. package/dist/esm/loaders/configure/configure.js +2 -8
  118. package/dist/types/common/config/state/configurable.d.ts.map +1 -1
  119. package/dist/types/common/config/state/init.d.ts.map +1 -1
  120. package/dist/types/common/config/state/runtime.d.ts.map +1 -1
  121. package/dist/types/common/context/shared-context.d.ts.map +1 -1
  122. package/dist/types/common/event-listener/event-listener-opts.d.ts +2 -2
  123. package/dist/types/common/event-listener/event-listener-opts.d.ts.map +1 -1
  124. package/dist/types/common/harvest/harvest-scheduler.d.ts +1 -0
  125. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
  126. package/dist/types/common/harvest/harvest.d.ts.map +1 -1
  127. package/dist/types/common/session/constants.d.ts +4 -0
  128. package/dist/types/common/session/constants.d.ts.map +1 -0
  129. package/dist/types/common/session/session-entity.d.ts +72 -0
  130. package/dist/types/common/session/session-entity.d.ts.map +1 -0
  131. package/dist/types/common/storage/first-party-cookies.d.ts +8 -0
  132. package/dist/types/common/storage/first-party-cookies.d.ts.map +1 -0
  133. package/dist/types/common/storage/local-memory.d.ts +8 -0
  134. package/dist/types/common/storage/local-memory.d.ts.map +1 -0
  135. package/dist/types/common/storage/local-storage.d.ts +6 -0
  136. package/dist/types/common/storage/local-storage.d.ts.map +1 -0
  137. package/dist/types/common/timer/interaction-timer.d.ts +11 -0
  138. package/dist/types/common/timer/interaction-timer.d.ts.map +1 -0
  139. package/dist/types/common/timer/timer.d.ts +12 -0
  140. package/dist/types/common/timer/timer.d.ts.map +1 -0
  141. package/dist/types/common/url/canonicalize-url.d.ts +9 -0
  142. package/dist/types/common/url/canonicalize-url.d.ts.map +1 -0
  143. package/dist/types/common/url/clean-url.d.ts +7 -1
  144. package/dist/types/common/url/clean-url.d.ts.map +1 -1
  145. package/dist/types/common/util/data-size.d.ts +7 -1
  146. package/dist/types/common/util/data-size.d.ts.map +1 -1
  147. package/dist/types/common/util/global-scope.d.ts +1 -0
  148. package/dist/types/common/util/global-scope.d.ts.map +1 -1
  149. package/dist/types/common/util/invoke.d.ts +35 -0
  150. package/dist/types/common/util/invoke.d.ts.map +1 -0
  151. package/dist/types/common/util/obfuscate.d.ts.map +1 -1
  152. package/dist/types/common/window/page-visibility.d.ts +1 -1
  153. package/dist/types/common/window/page-visibility.d.ts.map +1 -1
  154. package/dist/types/common/wrap/wrap-fetch.d.ts.map +1 -1
  155. package/dist/types/common/wrap/wrap-function.d.ts.map +1 -1
  156. package/dist/types/features/ajax/aggregate/index.d.ts +2 -2
  157. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  158. package/dist/types/features/jserrors/aggregate/canonical-function-name.d.ts +8 -1
  159. package/dist/types/features/jserrors/aggregate/canonical-function-name.d.ts.map +1 -1
  160. package/dist/types/features/jserrors/aggregate/compute-stack-trace.d.ts +48 -19
  161. package/dist/types/features/jserrors/aggregate/compute-stack-trace.d.ts.map +1 -1
  162. package/dist/types/features/jserrors/aggregate/index.d.ts +14 -5
  163. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  164. package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
  165. package/dist/types/features/metrics/aggregate/index.d.ts +2 -2
  166. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  167. package/dist/types/features/page_action/aggregate/index.d.ts +3 -3
  168. package/dist/types/features/page_action/aggregate/index.d.ts.map +1 -1
  169. package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -2
  170. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  171. package/dist/types/features/page_view_timing/aggregate/index.d.ts +2 -2
  172. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  173. package/dist/types/features/session_trace/aggregate/index.d.ts +2 -2
  174. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  175. package/dist/types/features/spa/aggregate/index.d.ts +2 -2
  176. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  177. package/dist/types/features/utils/agent-session.d.ts +2 -0
  178. package/dist/types/features/utils/agent-session.d.ts.map +1 -0
  179. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  180. package/dist/types/features/utils/lazy-loader.d.ts +2 -2
  181. package/dist/types/features/utils/lazy-loader.d.ts.map +1 -1
  182. package/dist/types/loaders/api/api.d.ts.map +1 -1
  183. package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
  184. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  185. package/package.json +9 -8
  186. package/src/common/config/state/configurable.js +26 -19
  187. package/src/common/config/state/init.js +7 -0
  188. package/src/common/config/state/runtime.js +22 -27
  189. package/src/common/context/shared-context.js +2 -1
  190. package/src/common/event-emitter/contextual-ee.test.js +2 -2
  191. package/src/common/event-emitter/register-handler.test.js +1 -1
  192. package/src/common/event-listener/event-listener-opts.js +4 -4
  193. package/src/common/harvest/harvest-scheduler.js +12 -8
  194. package/src/common/harvest/harvest.js +3 -1
  195. package/src/common/session/constants.js +3 -0
  196. package/src/common/session/session-entity.js +271 -0
  197. package/src/common/session/session-entity.test.js +317 -0
  198. package/src/common/storage/first-party-cookies.js +31 -0
  199. package/src/common/storage/local-memory.js +30 -0
  200. package/src/common/storage/local-memory.test.js +19 -0
  201. package/src/common/storage/local-storage.js +28 -0
  202. package/src/common/storage/local-storage.test.js +17 -0
  203. package/src/common/timer/interaction-timer.js +75 -0
  204. package/src/common/timer/interaction-timer.test.js +167 -0
  205. package/src/common/timer/timer.js +31 -0
  206. package/src/common/timer/timer.test.js +100 -0
  207. package/src/common/unload/eol.js +1 -1
  208. package/src/common/url/canonicalize-url.js +28 -0
  209. package/src/common/url/canonicalize-url.test.js +34 -0
  210. package/src/common/url/clean-url.js +10 -3
  211. package/src/common/util/data-size.js +6 -0
  212. package/src/common/util/data-size.test.js +50 -0
  213. package/src/common/util/global-scope.js +2 -0
  214. package/src/common/util/invoke.js +55 -0
  215. package/src/common/util/invoke.test.js +65 -0
  216. package/src/common/util/obfuscate.js +0 -4
  217. package/src/common/window/page-visibility.js +2 -2
  218. package/src/common/wrap/wrap-fetch.js +1 -2
  219. package/src/common/wrap/wrap-function.js +1 -2
  220. package/src/common/wrap/wrap-timer.js +1 -1
  221. package/src/features/ajax/aggregate/index.js +2 -2
  222. package/src/features/ajax/instrument/index.js +1 -1
  223. package/src/features/jserrors/aggregate/canonical-function-name.js +12 -4
  224. package/src/features/jserrors/aggregate/compute-stack-trace.js +85 -11
  225. package/src/features/jserrors/aggregate/compute-stack-trace.test.js +141 -24
  226. package/src/features/jserrors/aggregate/index.js +24 -50
  227. package/src/features/jserrors/instrument/index.js +0 -1
  228. package/src/features/metrics/aggregate/index.js +18 -3
  229. package/src/features/page_action/aggregate/index.js +2 -2
  230. package/src/features/page_view_event/aggregate/index.js +6 -3
  231. package/src/features/page_view_timing/aggregate/index.js +6 -6
  232. package/src/features/session_trace/aggregate/index.js +3 -4
  233. package/src/features/spa/aggregate/index.js +5 -5
  234. package/src/features/utils/agent-session.js +68 -0
  235. package/src/features/utils/feature-base.js +1 -1
  236. package/src/features/utils/instrument-base.js +5 -2
  237. package/src/features/utils/lazy-loader.js +1 -1
  238. package/src/loaders/agent.js +1 -1
  239. package/src/loaders/api/api.js +2 -5
  240. package/src/loaders/api/apiAsync.js +2 -1
  241. package/src/loaders/configure/configure.js +2 -7
  242. package/dist/cjs/common/util/single.js +0 -23
  243. package/dist/cjs/common/window/session-storage.js +0 -87
  244. package/dist/cjs/features/utils/aggregate-base.js +0 -13
  245. package/dist/esm/common/util/single.js +0 -16
  246. package/dist/esm/common/window/session-storage.js +0 -77
  247. package/dist/esm/features/utils/aggregate-base.js +0 -6
  248. package/dist/types/common/util/single.d.ts +0 -2
  249. package/dist/types/common/util/single.d.ts.map +0 -1
  250. package/dist/types/common/window/session-storage.d.ts +0 -18
  251. package/dist/types/common/window/session-storage.d.ts.map +0 -1
  252. package/dist/types/features/utils/aggregate-base.d.ts +0 -4
  253. package/dist/types/features/utils/aggregate-base.d.ts.map +0 -1
  254. package/src/common/util/single.js +0 -18
  255. package/src/common/window/session-storage.js +0 -75
  256. package/src/features/utils/aggregate-base.js +0 -7
package/README.md CHANGED
@@ -4,11 +4,11 @@
4
4
 
5
5
  The New Relic browser agent instruments your web application or site and provides observability into performance, errors, and other behaviors.
6
6
 
7
- - The instructions on this page pertain to installing the browser agent as an NPM package (currently in pre-release).
7
+ - The instructions on this page pertain to installing the browser agent as an NPM package.
8
8
 
9
9
  - The browser agent is also generally available as a copy-paste JavaScript snippet and via auto-injection by backend apps. See *[Install the browser agent](https://docs.newrelic.com/docs/browser/browser-monitoring/installation/install-browser-monitoring-agent/)* for info on these alternatives.
10
10
 
11
- - For questions and feedback on this pre-release package, please visit the [Explorer's Hub](https://forum.newrelic.com/s/), New Relic's community support forum.
11
+ - For questions and feedback on this package, please visit the [Explorer's Hub](https://forum.newrelic.com/s/), New Relic's community support forum.
12
12
 
13
13
  - Looking to contribute to the browser agent code base? See [DEVELOPING.md](DEVELOPING.md) for instructions on building and testing the browser agent library, and [CONTRIBUTING.md](CONTRIBUTING.md) for general guidance.
14
14
 
@@ -8,26 +8,32 @@ var _featureDependencies = require("../../../loaders/features/featureDependencie
8
8
  var _console = require("../../util/console");
9
9
  class Configurable {
10
10
  constructor(obj, model) {
11
- try {
12
- if (!obj || typeof obj !== 'object') return (0, _console.warn)('New setting a Configurable requires an object as input');
13
- if (!model || typeof model !== 'object') return (0, _console.warn)('Setting a Configurable requires a model to set its initial properties');
14
- Object.assign(this, model);
15
- Object.entries(obj).forEach(_ref => {
16
- let [key, value] = _ref;
17
- const frozenAttrs = (0, _featureDependencies.getFrozenAttributes)(key);
18
- if (frozenAttrs.length && value && typeof value === 'object') {
19
- frozenAttrs.forEach(attr => {
20
- if (attr in value) {
21
- (0, _console.warn)("\"".concat(attr, "\" is a protected attribute and can not be changed in feature ").concat(key, ". It will have no effect."));
22
- delete value[attr];
23
- }
24
- });
25
- }
26
- this[key] = value;
27
- });
28
- } catch (err) {
29
- (0, _console.warn)('An error occured while setting a Configurable', err);
30
- }
11
+ Object.assign(this, setValues(obj, model));
31
12
  }
32
13
  }
33
- exports.Configurable = Configurable;
14
+ exports.Configurable = Configurable;
15
+ function setValues(obj, model) {
16
+ const state = {};
17
+ try {
18
+ if (!obj || typeof obj !== 'object') return (0, _console.warn)('New setting a Configurable requires an object as input');
19
+ if (!model || typeof model !== 'object') return (0, _console.warn)('Setting a Configurable requires a model to set its initial properties');
20
+ Object.assign(state, model);
21
+ Object.entries(obj).forEach(_ref => {
22
+ let [key, value] = _ref;
23
+ if (!Object.keys(model).includes(key)) return;
24
+ const frozenAttrs = (0, _featureDependencies.getFrozenAttributes)(key);
25
+ if (frozenAttrs.length && value && typeof value === 'object') {
26
+ frozenAttrs.forEach(attr => {
27
+ if (attr in value) {
28
+ (0, _console.warn)("\"".concat(attr, "\" is a protected attribute and can not be changed in feature ").concat(key, ". It will have no effect."));
29
+ delete value[attr];
30
+ }
31
+ });
32
+ }
33
+ state[key] = value;
34
+ });
35
+ return state;
36
+ } catch (err) {
37
+ (0, _console.warn)('An error occured while setting a Configurable', err);
38
+ }
39
+ }
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getConfiguration = getConfiguration;
7
7
  exports.getConfigurationValue = getConfigurationValue;
8
8
  exports.setConfiguration = setConfiguration;
9
+ var _constants = require("../../session/constants");
10
+ var _globalScope = require("../../util/global-scope");
9
11
  var _nreum = require("../../window/nreum");
10
12
  var _configurable = require("./configurable");
11
13
  const model = {
@@ -27,6 +29,12 @@ const model = {
27
29
  cors_use_tracecontext_headers: undefined,
28
30
  allowed_origins: undefined
29
31
  },
32
+ session: {
33
+ domain: undefined,
34
+ // used by first party cookies to set the top-level domain
35
+ expiresMs: _constants.DEFAULT_EXPIRES_MS,
36
+ inactiveMs: _constants.DEFAULT_INACTIVE_MS
37
+ },
30
38
  ssl: undefined,
31
39
  obfuscate: undefined,
32
40
  jserrors: {
@@ -8,35 +8,33 @@ exports.setRuntime = setRuntime;
8
8
  var userAgent = _interopRequireWildcard(require("../../util/user-agent"));
9
9
  var _configurable = require("./configurable");
10
10
  var _nreum = require("../../window/nreum");
11
- var _sessionStorage = require("../../window/session-storage");
12
- var _config = require("../config");
13
11
  var _globalScope = require("../../util/global-scope");
14
12
  var _env = require("../../constants/env.npm");
15
13
  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
14
  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
- const model = agentId => {
18
- return {
19
- buildEnv: _env.BUILD_ENV,
20
- bytesSent: {},
21
- customTransaction: undefined,
22
- disabled: false,
23
- distMethod: _env.DIST_METHOD,
24
- isolatedBacklog: false,
25
- loaderType: undefined,
26
- maxBytes: 30000,
27
- // The "timeOrigin" property is the new standard timestamp property shared across main frame and workers, but is not supported in some early Safari browsers (safari<15) + IE
28
- // ingest expects an integer value, and timeOrigin can return a float.
29
- offset: Math.floor(_globalScope.globalScope?.performance?.timeOrigin || _globalScope.globalScope?.performance?.timing?.navigationStart || Date.now()),
30
- onerror: undefined,
31
- origin: '' + _globalScope.globalScope.location,
32
- ptid: undefined,
33
- releaseIds: {},
34
- sessionId: (0, _config.getConfigurationValue)(agentId, 'privacy.cookies_enabled') == true ? (0, _sessionStorage.getCurrentSessionIdOrMakeNew)() : null,
35
- // if cookies (now session tracking) is turned off or can't get session ID, this is null
36
- xhrWrappable: typeof _globalScope.globalScope.XMLHttpRequest?.prototype?.addEventListener === 'function',
37
- userAgent,
38
- version: _env.VERSION
39
- };
15
+ const model = {
16
+ buildEnv: _env.BUILD_ENV,
17
+ bytesSent: {},
18
+ // Used for SM to capture body bytes sent per endpoint
19
+ queryBytesSent: {},
20
+ // Used for SM to capture query parameter bytes sent per endpoint
21
+ customTransaction: undefined,
22
+ disabled: false,
23
+ distMethod: _env.DIST_METHOD,
24
+ isolatedBacklog: false,
25
+ loaderType: undefined,
26
+ maxBytes: 30000,
27
+ // The "timeOrigin" property is the new standard timestamp property shared across main frame and workers, but is not supported in some early Safari browsers (safari<15) + IE
28
+ // ingest expects an integer value, and timeOrigin can return a float.
29
+ offset: Math.floor(_globalScope.globalScope?.performance?.timeOrigin || _globalScope.globalScope?.performance?.timing?.navigationStart || Date.now()),
30
+ onerror: undefined,
31
+ origin: '' + _globalScope.globalScope.location,
32
+ ptid: undefined,
33
+ releaseIds: {},
34
+ session: undefined,
35
+ xhrWrappable: typeof _globalScope.globalScope.XMLHttpRequest?.prototype?.addEventListener === 'function',
36
+ userAgent,
37
+ version: _env.VERSION
40
38
  };
41
39
  const _cache = {};
42
40
  function getRuntime(id) {
@@ -46,6 +44,6 @@ function getRuntime(id) {
46
44
  }
47
45
  function setRuntime(id, obj) {
48
46
  if (!id) throw new Error('All runtime objects require an agent identifier!');
49
- _cache[id] = new _configurable.Configurable(obj, model(id));
47
+ _cache[id] = new _configurable.Configurable(obj, model);
50
48
  (0, _nreum.gosNREUMInitializedAgents)(id, _cache[id], 'runtime');
51
49
  }
@@ -12,7 +12,7 @@ exports.VERSION = exports.DIST_METHOD = exports.BUILD_ENV = void 0;
12
12
  /**
13
13
  * Exposes the version of the agent
14
14
  */
15
- const VERSION = "1.231.0";
15
+ const VERSION = "1.232.1";
16
16
 
17
17
  /**
18
18
  * Exposes the build type of the agent
@@ -12,7 +12,7 @@ exports.VERSION = exports.DIST_METHOD = exports.BUILD_ENV = void 0;
12
12
  /**
13
13
  * Exposes the version of the agent
14
14
  */
15
- const VERSION = "1.231.0";
15
+ const VERSION = "1.232.1";
16
16
 
17
17
  /**
18
18
  * Exposes the build type of the agent
@@ -6,7 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.SharedContext = void 0;
7
7
  var _console = require("../util/console");
8
8
  const model = {
9
- agentIdentifier: ''
9
+ agentIdentifier: '',
10
+ ee: undefined
10
11
  };
11
12
  class SharedContext {
12
13
  constructor(context) {
@@ -257,8 +257,8 @@ describe('event-emitter emit', () => {
257
257
  scopeEE.emit(eventType, eventArgs, {}, false, false);
258
258
  expect(mockScopeListener).toHaveBeenCalledTimes(1);
259
259
  expect(mockListener).not.toHaveBeenCalled();
260
- expect(scopeEE.backlog['feature']).toEqual(expect.arrayContaining([expect.arrayContaining([scopeEE, eventType, eventArgs, {}])]));
261
- expect(ee.backlog['feature']).toEqual(scopeEE.backlog['feature']);
260
+ expect(scopeEE.backlog.feature).toEqual(expect.arrayContaining([expect.arrayContaining([scopeEE, eventType, eventArgs, {}])]));
261
+ expect(ee.backlog.feature).toEqual(scopeEE.backlog.feature);
262
262
  });
263
263
  });
264
264
  describe('getOrSetContext', () => {
@@ -21,7 +21,7 @@ test('should default group to "feature"', async () => {
21
21
  const eventType = _faker.faker.datatype.uuid();
22
22
  const eventHandler = jest.fn();
23
23
  registerHandler(eventType, eventHandler);
24
- expect(registerHandler.handlers['feature']).toEqual(expect.objectContaining({
24
+ expect(registerHandler.handlers.feature).toEqual(expect.objectContaining({
25
25
  [eventType]: [expect.arrayContaining([handleEE, eventHandler])]
26
26
  }));
27
27
  });
@@ -39,10 +39,12 @@ function eventListenerOpts(useCapture, abortSignal) {
39
39
  /** Do not use this within the worker context. */
40
40
  function windowAddEventListener(event, listener) {
41
41
  let capture = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
42
- window.addEventListener(event, listener, eventListenerOpts(capture));
42
+ let abortSignal = arguments.length > 3 ? arguments[3] : undefined;
43
+ window.addEventListener(event, listener, eventListenerOpts(capture, abortSignal));
43
44
  }
44
45
  /** Do not use this within the worker context. */
45
46
  function documentAddEventListener(event, listener) {
46
47
  let capture = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
47
- document.addEventListener(event, listener, eventListenerOpts(capture));
48
+ let abortSignal = arguments.length > 3 ? arguments[3] : undefined;
49
+ document.addEventListener(event, listener, eventListenerOpts(capture, abortSignal));
48
50
  }
@@ -27,17 +27,21 @@ class HarvestScheduler extends _sharedContext.SharedContext {
27
27
  this.aborted = false; // this controls the per-interval and final harvests for the scheduler (currently per feature specific!)
28
28
 
29
29
  this.harvest = new _harvest.Harvest(this.sharedContext);
30
- (0, _eol.subscribeToEOL)(() => {
31
- if (this.aborted) return;
32
30
 
33
- // If opts.onUnload is defined, these are special actions to execute before attempting to send the final payload.
34
- if (this.opts.onUnload) this.opts.onUnload();
35
- this.runHarvest({
36
- unload: true
37
- });
38
- }, (0, _config.getConfigurationValue)(this.sharedContext.agentIdentifier, 'allow_bfcache')); // TO DO: remove feature flag after rls stable
39
- }
31
+ // unload if EOL mechanism fires
32
+ (0, _eol.subscribeToEOL)(this.unload.bind(this), (0, _config.getConfigurationValue)(this.sharedContext.agentIdentifier, 'allow_bfcache')); // TO DO: remove feature flag after rls stable
40
33
 
34
+ // unload if session resets
35
+ this.sharedContext?.ee.on('session-reset', this.unload.bind(this));
36
+ }
37
+ unload() {
38
+ if (this.aborted) return;
39
+ // If opts.onUnload is defined, these are special actions to execute before attempting to send the final payload.
40
+ if (this.opts.onUnload) this.opts.onUnload();
41
+ this.runHarvest({
42
+ unload: true
43
+ });
44
+ }
41
45
  startTimer(interval, initialDelay) {
42
46
  this.interval = interval;
43
47
  this.started = true;
@@ -80,8 +84,7 @@ class HarvestScheduler extends _sharedContext.SharedContext {
80
84
  }
81
85
  }
82
86
  } else {
83
- const runAfterSending = opts?.unload ? undefined : onHarvestFinished; // don't bother running onFinish handler if this is the final harvest
84
- this.harvest.sendX(this.endpoint, opts, runAfterSending);
87
+ this.harvest.sendX(this.endpoint, opts, onHarvestFinished);
85
88
  }
86
89
  if (this.started) {
87
90
  this.scheduleHarvest();
@@ -127,6 +127,8 @@ class Harvest extends _sharedContext.SharedContext {
127
127
 
128
128
  // Get bytes harvested per endpoint as a supportability metric. See metrics aggregator (on unload).
129
129
  agentRuntime.bytesSent[endpoint] = (agentRuntime.bytesSent[endpoint] || 0) + body?.length || 0;
130
+ // Get query bytes harvested per endpoint as a supportability metric. See metrics aggregator (on unload).
131
+ agentRuntime.queryBytesSent[endpoint] = (agentRuntime.queryBytesSent[endpoint] || 0) + fullUrl.split('?').slice(-1)[0]?.length || 0;
130
132
 
131
133
  /* Since workers don't support sendBeacon right now, or Image(), they can only use XHR method.
132
134
  Because they still do permit synch XHR, the idea is that at final harvest time (worker is closing),
@@ -167,7 +169,7 @@ class Harvest extends _sharedContext.SharedContext {
167
169
  var ref = this.obfuscator.shouldObfuscate() ? this.obfuscator.obfuscateString(location) : location;
168
170
  return ['?a=' + info.applicationID, (0, _encode.param)('sa', info.sa ? '' + info.sa : ''), (0, _encode.param)('v', _env.VERSION), transactionNameParam(info), (0, _encode.param)('ct', runtime.customTransaction), '&rst=' + (0, _now.now)(), '&ck=0',
169
171
  // ck param DEPRECATED - still expected by backend
170
- '&s=' + (runtime.sessionId || '0'),
172
+ '&s=' + (runtime.session?.value || '0'),
171
173
  // the 0 id encaps all untrackable and default traffic
172
174
  (0, _encode.param)('ref', ref), (0, _encode.param)('ptid', runtime.ptid ? '' + runtime.ptid : '')].join('');
173
175
  }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PREFIX = exports.DEFAULT_INACTIVE_MS = exports.DEFAULT_EXPIRES_MS = void 0;
7
+ const PREFIX = 'NRBA';
8
+ exports.PREFIX = PREFIX;
9
+ const DEFAULT_EXPIRES_MS = 14400000;
10
+ exports.DEFAULT_EXPIRES_MS = DEFAULT_EXPIRES_MS;
11
+ const DEFAULT_INACTIVE_MS = 1800000;
12
+ exports.DEFAULT_INACTIVE_MS = DEFAULT_INACTIVE_MS;
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.SessionEntity = void 0;
7
+ var _uniqueId = require("../ids/unique-id");
8
+ var _console = require("../util/console");
9
+ var _stringify = require("../util/stringify");
10
+ var _contextualEe = require("../event-emitter/contextual-ee");
11
+ var _timer = require("../timer/timer");
12
+ var _globalScope = require("../util/global-scope");
13
+ var _constants = require("./constants");
14
+ var _localMemory = require("../storage/local-memory");
15
+ var _interactionTimer = require("../timer/interaction-timer");
16
+ var _wrap = require("../wrap");
17
+ var _configurable = require("../config/state/configurable");
18
+ var _handle = require("../event-emitter/handle");
19
+ var _constants2 = require("../../features/metrics/constants");
20
+ var _features = require("../../loaders/features/features");
21
+ const model = {
22
+ value: '',
23
+ inactiveAt: 0,
24
+ expiresAt: 0,
25
+ updatedAt: Date.now(),
26
+ sessionReplayActive: false,
27
+ sessionTraceActive: false,
28
+ custom: {}
29
+ };
30
+ class SessionEntity {
31
+ /**
32
+ * Create a self-managing Session Entity. This entity is scoped to the agent identifier which triggered it, allowing for multiple simultaneous session objects to exist.
33
+ * There is one "namespace" an agent can store data in LS -- NRBA_{key}. If there are two agents on one page, and they both use the same key, they could overwrite each other since they would both use the same namespace in LS by default.
34
+ * The value can be overridden in the constructor, but will default to a unique 16 character hex string
35
+ * expiresMs and inactiveMs are used to "expire" the session, but can be overridden in the constructor. Pass 0 to disable expiration timers.
36
+ */
37
+ constructor(opts) {
38
+ this.setup(opts);
39
+ }
40
+ setup(_ref) {
41
+ let {
42
+ agentIdentifier,
43
+ key,
44
+ value = (0, _uniqueId.generateRandomHexString)(16),
45
+ expiresMs = _constants.DEFAULT_EXPIRES_MS,
46
+ inactiveMs = _constants.DEFAULT_INACTIVE_MS,
47
+ storageAPI = new _localMemory.LocalMemory()
48
+ } = _ref;
49
+ if (!agentIdentifier || !key) throw new Error('Missing Required Fields');
50
+ if (!_globalScope.isBrowserScope) this.storage = new _localMemory.LocalMemory();else this.storage = storageAPI;
51
+ this.sync(model);
52
+ this.agentIdentifier = agentIdentifier;
53
+
54
+ // key is intended to act as the k=v pair
55
+ this.key = key;
56
+ // value is intended to act as the primary value of the k=v pair
57
+ this.value = value;
58
+ this.expiresMs = expiresMs;
59
+ this.inactiveMs = inactiveMs;
60
+ this.ee = _contextualEe.ee.get(agentIdentifier);
61
+ (0, _wrap.wrapEvents)(this.ee);
62
+
63
+ // the first time the session entity class is instantiated, we check the storage API for an existing
64
+ // object. If it exists, the values inside the object are used to inform the timers that run locally.
65
+ // if the initial read is empty, it allows us to set a "fresh" "new" session immediately.
66
+ // the local timers are used after the session is running to "expire" the session, allowing for pausing timers etc.
67
+ // the timestamps stored in the storage API can be checked at initial run, and when the page is restored, otherwise we lean
68
+ // on the local timers to expire the session
69
+ const initialRead = this.read();
70
+
71
+ // the set-up of the timer used to expire the session "naturally" at a certain time
72
+ // this gets ignored if the value is falsy, allowing for session entities that do not expire
73
+ if (expiresMs) {
74
+ this.expiresAt = initialRead?.expiresAt || this.getFutureTimestamp(expiresMs);
75
+ this.expiresTimer = new _timer.Timer({
76
+ // When the inactive timer ends, collect a SM and reset the session
77
+ onEnd: () => {
78
+ this.collectSM('expired', this);
79
+ this.collectSM('duration', this);
80
+ this.reset();
81
+ }
82
+ }, this.expiresAt - Date.now());
83
+ } else {
84
+ this.expiresAt = Infinity;
85
+ }
86
+
87
+ // the set-up of the timer used to expire the session due to "inactivity" at a certain time
88
+ // this gets ignored if the value is falsy, allowing for session entities that do not expire
89
+ // this gets "refreshed" when "activity" is observed
90
+ if (inactiveMs) {
91
+ this.inactiveAt = initialRead?.inactiveAt || this.getFutureTimestamp(inactiveMs);
92
+ this.inactiveTimer = new _interactionTimer.InteractionTimer({
93
+ // When the inactive timer ends, collect a SM and reset the session
94
+ onEnd: () => {
95
+ this.collectSM('inactive', this);
96
+ this.collectSM('duration', this);
97
+ this.reset();
98
+ },
99
+ // When the inactive timer refreshes, it will update the storage values with an update timestamp
100
+ onRefresh: this.refresh.bind(this),
101
+ // When the inactive timer pauses, update the storage values with an update timestamp
102
+ onPause: () => this.write(new _configurable.Configurable(this.read(), model)),
103
+ ee: this.ee,
104
+ refreshEvents: ['click', 'keydown', 'scroll']
105
+ }, this.inactiveAt - Date.now());
106
+ } else {
107
+ this.inactiveAt = Infinity;
108
+ }
109
+
110
+ // The fact that the session is "new" or pre-existing is used in some places in the agent. Session Replay and Trace
111
+ // can use this info to inform whether to trust a new sampling decision vs continue a previous tracking effort.
112
+ this.isNew = !Object.keys(initialRead).length;
113
+ // if its a "new" session, we write to storage API with the default values. These values may change over the lifespan of the agent run.
114
+ // we can use configurable here to help us know and manage what values are being used. -- see "model" above
115
+ if (this.isNew) this.write(new _configurable.Configurable(this, model), true);else this.sync(initialRead);
116
+ this.initialized = true;
117
+ }
118
+
119
+ // This is the actual key appended to the storage API
120
+ get lookupKey() {
121
+ return "".concat(_constants.PREFIX, "_").concat(this.key);
122
+ }
123
+ sync(data) {
124
+ Object.assign(this, data);
125
+ }
126
+
127
+ /**
128
+ * Fetch the stored values from the storage API tied to this entity
129
+ * @returns {Object}
130
+ */
131
+ read() {
132
+ try {
133
+ const val = this.storage.get(this.lookupKey);
134
+ if (!val) return {};
135
+ // TODO - decompression would need to happen here if we decide to do it
136
+ const obj = typeof val === 'string' ? JSON.parse(val) : val;
137
+ if (this.isInvalid(obj)) return {};
138
+ // if the session expires, collect a SM count before resetting
139
+ if (this.isExpired(obj.expiresAt)) {
140
+ this.collectSM('expired', this);
141
+ this.collectSM('duration', obj, true);
142
+ return this.reset();
143
+ }
144
+ // if "inactive" timer is expired at "read" time -- esp. initial read -- reset
145
+ // collect a SM count before resetting
146
+ if (this.isExpired(obj.inactiveAt)) {
147
+ this.collectSM('inactive', this);
148
+ this.collectSM('duration', obj, true);
149
+ return this.reset();
150
+ }
151
+ return obj;
152
+ } catch (e) {
153
+ (0, _console.warn)('Failed to read from storage API', e);
154
+ // storage is inaccessible
155
+ return {};
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Store data to the storage API tied to this entity
161
+ * To preseve existing attributes, the output of ...session.read()
162
+ * should be appended to the data argument
163
+ * @param {Object} data
164
+ * @returns {Object}
165
+ */
166
+ write(data) {
167
+ try {
168
+ if (!data || typeof data !== 'object') return;
169
+ // everytime we update, we can update a timestamp for sanity
170
+ data.updatedAt = Date.now();
171
+ this.sync(data);
172
+ // TODO - compression would need happen here if we decide to do it
173
+ this.storage.set(this.lookupKey, (0, _stringify.stringify)(data));
174
+ return data;
175
+ } catch (e) {
176
+ // storage is inaccessible
177
+ (0, _console.warn)('Failed to write to the storage API', e);
178
+ return null;
179
+ }
180
+ }
181
+ reset() {
182
+ // this method should set off a chain of actions across the features by emitting 'new-session'
183
+ // * send off pending payloads
184
+ // * stop recording (stn and sr)...
185
+ // * delete the session and start over
186
+ try {
187
+ if (this.initialized) this.ee.emit('session-reset');
188
+ this.storage.remove(this.lookupKey);
189
+ this.inactiveTimer?.abort?.();
190
+ this.expiresTimer?.clear?.();
191
+ delete this.custom;
192
+ delete this.value;
193
+ this.setup({
194
+ agentIdentifier: this.agentIdentifier,
195
+ key: this.key,
196
+ storageAPI: this.storage,
197
+ expiresMs: this.expiresMs,
198
+ inactiveMs: this.inactiveMs
199
+ });
200
+ return this.read();
201
+ } catch (e) {
202
+ return {};
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Refresh the inactivity timer data
208
+ */
209
+ refresh() {
210
+ // read here & invalidate
211
+ const existingData = this.read();
212
+ this.inactiveAt = this.getFutureTimestamp(this.inactiveMs);
213
+ this.write({
214
+ ...existingData,
215
+ inactiveAt: this.inactiveAt
216
+ });
217
+ }
218
+
219
+ /**
220
+ * @param {number} timestamp
221
+ * @returns {boolean}
222
+ */
223
+ isExpired(timestamp) {
224
+ return Date.now() > timestamp;
225
+ }
226
+
227
+ /**
228
+ * @param {Object} data
229
+ * @returns {boolean}
230
+ */
231
+ isInvalid(data) {
232
+ const requiredKeys = ['value', 'expiresAt', 'inactiveAt'];
233
+ return !requiredKeys.every(x => Object.keys(data).includes(x));
234
+ }
235
+ collectSM(type, data, useUpdatedAt) {
236
+ let value, tag;
237
+ if (type === 'duration') {
238
+ const startingTimestamp = data.expiresAt - data.expiresMs;
239
+ const endingTimestamp = useUpdatedAt ? data.updatedAt : Date.now();
240
+ value = endingTimestamp - startingTimestamp;
241
+ tag = 'Session/Duration/Ms';
242
+ }
243
+ if (type === 'expired') tag = 'Session/Expired/Seen';
244
+ if (type === 'inactive') tag = 'Session/Inactive/Seen';
245
+ if (tag) (0, _handle.handle)(_constants2.SUPPORTABILITY_METRIC_CHANNEL, [tag, value], undefined, _features.FEATURE_NAMES.metrics, this.ee);
246
+ }
247
+
248
+ /**
249
+ * @param {number} futureMs - The number of ms to use to generate a future timestamp
250
+ * @returns {number}
251
+ */
252
+ getFutureTimestamp(futureMs) {
253
+ return Date.now() + futureMs;
254
+ }
255
+ syncCustomAttribute(key, value) {
256
+ if (!_globalScope.isBrowserScope) return;
257
+ if (value === null) {
258
+ const curr = this.read();
259
+ if (curr.custom) {
260
+ delete curr.custom[key];
261
+ this.write({
262
+ ...curr
263
+ });
264
+ }
265
+ } else {
266
+ const curr = this.read();
267
+ this.custom = {
268
+ ...(curr?.custom || {}),
269
+ [key]: value
270
+ };
271
+ this.write({
272
+ ...curr,
273
+ custom: this.custom
274
+ });
275
+ }
276
+ }
277
+ }
278
+ exports.SessionEntity = SessionEntity;