@newrelic/browser-agent 0.1.230 → 1.232.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 (365) hide show
  1. package/README.md +27 -3
  2. package/dist/cjs/common/browser-version/ios-version.js +4 -3
  3. package/dist/cjs/common/config/state/configurable.js +27 -21
  4. package/dist/cjs/common/config/state/info.js +1 -1
  5. package/dist/cjs/common/config/state/init.js +9 -1
  6. package/dist/cjs/common/config/state/loader-config.js +1 -1
  7. package/dist/cjs/common/config/state/runtime.js +26 -28
  8. package/dist/cjs/common/constants/env.cdn.js +29 -0
  9. package/dist/cjs/common/constants/env.js +32 -0
  10. package/dist/cjs/common/constants/env.npm.js +30 -0
  11. package/dist/cjs/common/context/shared-context.js +2 -1
  12. package/dist/cjs/common/event-emitter/contextual-ee.test.js +282 -0
  13. package/dist/cjs/common/event-emitter/handle.test.js +58 -0
  14. package/dist/cjs/common/event-emitter/register-handler.test.js +55 -0
  15. package/dist/cjs/common/event-listener/event-listener-opts.js +4 -2
  16. package/dist/cjs/common/harvest/harvest-scheduler.js +14 -11
  17. package/dist/cjs/common/harvest/harvest.js +5 -3
  18. package/dist/cjs/common/ids/id.js +14 -6
  19. package/dist/cjs/common/ids/id.test.js +85 -0
  20. package/dist/cjs/common/ids/unique-id.js +75 -51
  21. package/dist/cjs/common/ids/unique-id.test.js +49 -0
  22. package/dist/cjs/common/session/constants.js +12 -0
  23. package/dist/cjs/common/session/session-entity.js +278 -0
  24. package/dist/cjs/common/session/session-entity.test.js +436 -0
  25. package/dist/cjs/common/storage/first-party-cookies.js +35 -0
  26. package/dist/cjs/common/storage/local-memory.js +35 -0
  27. package/dist/cjs/common/storage/local-memory.test.js +20 -0
  28. package/dist/cjs/common/storage/local-storage.js +33 -0
  29. package/dist/cjs/common/storage/local-storage.test.js +14 -0
  30. package/dist/cjs/common/timer/interaction-timer.js +78 -0
  31. package/dist/cjs/common/timer/interaction-timer.test.js +216 -0
  32. package/dist/cjs/common/timer/timer.js +32 -0
  33. package/dist/cjs/common/timer/timer.test.js +105 -0
  34. package/dist/cjs/common/timing/nav-timing.js +51 -30
  35. package/dist/cjs/common/timing/nav-timing.test.js +192 -0
  36. package/dist/cjs/common/unload/eol.js +2 -2
  37. package/dist/cjs/common/url/clean-url.test.js +9 -0
  38. package/dist/cjs/common/url/encode.test.js +74 -0
  39. package/dist/cjs/common/url/location.js +4 -0
  40. package/dist/cjs/common/url/location.test.js +13 -0
  41. package/dist/cjs/common/url/parse-url.test.js +111 -0
  42. package/dist/cjs/common/url/protocol.js +2 -12
  43. package/dist/cjs/common/url/protocol.test.js +16 -0
  44. package/dist/cjs/common/util/console.js +1 -1
  45. package/dist/cjs/common/util/data-size.js +6 -0
  46. package/dist/cjs/common/util/data-size.test.js +47 -0
  47. package/dist/cjs/common/util/invoke.js +73 -0
  48. package/dist/cjs/common/util/invoke.test.js +49 -0
  49. package/dist/cjs/common/util/map-own.test.js +3 -3
  50. package/dist/cjs/common/util/obfuscate.js +1 -5
  51. package/dist/cjs/common/window/page-visibility.js +5 -2
  52. package/dist/cjs/common/wrap/index.js +0 -7
  53. package/dist/cjs/common/wrap/wrap-events.js +6 -9
  54. package/dist/cjs/common/wrap/wrap-fetch.js +6 -6
  55. package/dist/cjs/common/wrap/wrap-history.js +7 -6
  56. package/dist/cjs/common/wrap/wrap-jsonp.js +7 -6
  57. package/dist/cjs/common/wrap/wrap-mutation.js +7 -6
  58. package/dist/cjs/common/wrap/wrap-promise.js +7 -6
  59. package/dist/cjs/common/wrap/wrap-promise.test.js +119 -0
  60. package/dist/cjs/common/wrap/wrap-raf.js +6 -6
  61. package/dist/cjs/common/wrap/wrap-timer.js +7 -7
  62. package/dist/cjs/common/wrap/wrap-xhr.js +5 -6
  63. package/dist/cjs/features/ajax/aggregate/index.js +3 -3
  64. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +5 -5
  65. package/dist/cjs/features/jserrors/aggregate/format-stack-trace.test.js +1 -1
  66. package/dist/cjs/features/jserrors/aggregate/index.js +6 -6
  67. package/dist/cjs/features/jserrors/instrument/index.js +2 -2
  68. package/dist/cjs/features/metrics/aggregate/index.js +19 -9
  69. package/dist/cjs/features/metrics/instrument/index.js +0 -25
  70. package/dist/cjs/features/metrics/instrument/workers-helper.js +5 -5
  71. package/dist/cjs/features/page_action/aggregate/index.js +3 -3
  72. package/dist/cjs/features/page_view_event/aggregate/index.js +23 -9
  73. package/dist/cjs/features/page_view_timing/aggregate/index.js +40 -30
  74. package/dist/cjs/features/session_trace/aggregate/index.js +18 -15
  75. package/dist/cjs/features/spa/aggregate/index.js +6 -5
  76. package/dist/cjs/features/utils/agent-session.js +73 -0
  77. package/dist/cjs/features/utils/feature-base.js +1 -1
  78. package/dist/cjs/features/utils/instrument-base.js +12 -3
  79. package/dist/cjs/features/utils/lazy-loader.js +2 -2
  80. package/dist/cjs/loaders/agent.js +2 -2
  81. package/dist/cjs/loaders/api/api.js +9 -9
  82. package/dist/cjs/loaders/api/apiAsync.js +3 -2
  83. package/dist/cjs/loaders/configure/configure.js +0 -6
  84. package/dist/cjs/loaders/features/enabled-features.js +1 -1
  85. package/dist/cjs/loaders/micro-agent.js +2 -1
  86. package/dist/esm/common/browser-version/ios-version.js +4 -3
  87. package/dist/esm/common/config/state/configurable.js +26 -20
  88. package/dist/esm/common/config/state/info.js +1 -1
  89. package/dist/esm/common/config/state/init.js +9 -1
  90. package/dist/esm/common/config/state/loader-config.js +1 -1
  91. package/dist/esm/common/config/state/runtime.js +26 -28
  92. package/dist/esm/common/constants/env.cdn.js +20 -0
  93. package/dist/esm/common/constants/env.js +23 -0
  94. package/dist/esm/common/constants/env.npm.js +21 -0
  95. package/dist/esm/common/context/shared-context.js +2 -1
  96. package/dist/esm/common/event-emitter/contextual-ee.test.js +278 -0
  97. package/dist/esm/common/event-emitter/handle.test.js +54 -0
  98. package/dist/esm/common/event-emitter/register-handler.test.js +51 -0
  99. package/dist/esm/common/event-listener/event-listener-opts.js +4 -2
  100. package/dist/esm/common/harvest/harvest-scheduler.js +14 -11
  101. package/dist/esm/common/harvest/harvest.js +4 -2
  102. package/dist/esm/common/ids/id.js +16 -6
  103. package/dist/esm/common/ids/id.test.js +81 -0
  104. package/dist/esm/common/ids/unique-id.js +75 -51
  105. package/dist/esm/common/ids/unique-id.test.js +44 -0
  106. package/dist/esm/common/session/constants.js +3 -0
  107. package/dist/esm/common/session/session-entity.js +271 -0
  108. package/dist/esm/common/session/session-entity.test.js +434 -0
  109. package/dist/esm/common/storage/first-party-cookies.js +28 -0
  110. package/dist/esm/common/storage/local-memory.js +28 -0
  111. package/dist/esm/common/storage/local-memory.test.js +18 -0
  112. package/dist/esm/common/storage/local-storage.js +26 -0
  113. package/dist/esm/common/storage/local-storage.test.js +12 -0
  114. package/dist/esm/common/timer/interaction-timer.js +71 -0
  115. package/dist/esm/common/timer/interaction-timer.test.js +214 -0
  116. package/dist/esm/common/timer/timer.js +25 -0
  117. package/dist/esm/common/timer/timer.test.js +103 -0
  118. package/dist/esm/common/timing/nav-timing.js +51 -29
  119. package/dist/esm/common/timing/nav-timing.test.js +190 -0
  120. package/dist/esm/common/unload/eol.js +1 -1
  121. package/dist/esm/common/url/clean-url.test.js +7 -0
  122. package/dist/esm/common/url/encode.test.js +70 -0
  123. package/dist/esm/common/url/location.js +4 -0
  124. package/dist/esm/common/url/location.test.js +11 -0
  125. package/dist/esm/common/url/parse-url.test.js +107 -0
  126. package/dist/esm/common/url/protocol.js +3 -12
  127. package/dist/esm/common/url/protocol.test.js +14 -0
  128. package/dist/esm/common/util/console.js +1 -1
  129. package/dist/esm/common/util/data-size.js +7 -0
  130. package/dist/esm/common/util/data-size.test.js +45 -0
  131. package/dist/esm/common/util/invoke.js +66 -0
  132. package/dist/esm/common/util/invoke.test.js +47 -0
  133. package/dist/esm/common/util/map-own.test.js +3 -3
  134. package/dist/esm/common/util/obfuscate.js +2 -6
  135. package/dist/esm/common/window/page-visibility.js +5 -2
  136. package/dist/esm/common/wrap/index.js +1 -2
  137. package/dist/esm/common/wrap/wrap-events.js +6 -9
  138. package/dist/esm/common/wrap/wrap-fetch.js +6 -6
  139. package/dist/esm/common/wrap/wrap-history.js +7 -6
  140. package/dist/esm/common/wrap/wrap-jsonp.js +7 -6
  141. package/dist/esm/common/wrap/wrap-mutation.js +7 -6
  142. package/dist/esm/common/wrap/wrap-promise.js +7 -6
  143. package/dist/esm/common/wrap/wrap-promise.test.js +115 -0
  144. package/dist/esm/common/wrap/wrap-raf.js +6 -6
  145. package/dist/esm/common/wrap/wrap-timer.js +7 -7
  146. package/dist/esm/common/wrap/wrap-xhr.js +5 -6
  147. package/dist/esm/features/ajax/aggregate/index.js +3 -3
  148. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +5 -5
  149. package/dist/esm/features/jserrors/aggregate/format-stack-trace.test.js +1 -1
  150. package/dist/esm/features/jserrors/aggregate/index.js +6 -6
  151. package/dist/esm/features/jserrors/instrument/index.js +2 -2
  152. package/dist/esm/features/metrics/aggregate/index.js +21 -11
  153. package/dist/esm/features/metrics/instrument/index.js +0 -25
  154. package/dist/esm/features/metrics/instrument/workers-helper.js +5 -5
  155. package/dist/esm/features/page_action/aggregate/index.js +3 -3
  156. package/dist/esm/features/page_view_event/aggregate/index.js +23 -9
  157. package/dist/esm/features/page_view_timing/aggregate/index.js +40 -30
  158. package/dist/esm/features/session_trace/aggregate/index.js +18 -15
  159. package/dist/esm/features/spa/aggregate/index.js +6 -5
  160. package/dist/esm/features/utils/agent-session.js +67 -0
  161. package/dist/esm/features/utils/feature-base.js +1 -1
  162. package/dist/esm/features/utils/instrument-base.js +7 -2
  163. package/dist/esm/features/utils/lazy-loader.js +2 -2
  164. package/dist/esm/loaders/agent.js +2 -2
  165. package/dist/esm/loaders/api/api.js +6 -9
  166. package/dist/esm/loaders/api/apiAsync.js +2 -1
  167. package/dist/esm/loaders/configure/configure.js +2 -8
  168. package/dist/esm/loaders/features/enabled-features.js +1 -1
  169. package/dist/types/common/config/state/configurable.d.ts.map +1 -1
  170. package/dist/types/common/config/state/init.d.ts.map +1 -1
  171. package/dist/types/common/config/state/runtime.d.ts.map +1 -1
  172. package/dist/types/common/constants/env.cdn.d.ts +18 -0
  173. package/dist/types/common/constants/env.cdn.d.ts.map +1 -0
  174. package/dist/types/common/constants/env.d.ts +13 -0
  175. package/dist/types/common/constants/env.d.ts.map +1 -0
  176. package/dist/types/common/constants/env.npm.d.ts +19 -0
  177. package/dist/types/common/constants/env.npm.d.ts.map +1 -0
  178. package/dist/types/common/context/shared-context.d.ts.map +1 -1
  179. package/dist/types/common/event-listener/event-listener-opts.d.ts +2 -2
  180. package/dist/types/common/event-listener/event-listener-opts.d.ts.map +1 -1
  181. package/dist/types/common/harvest/harvest-scheduler.d.ts +1 -0
  182. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
  183. package/dist/types/common/harvest/harvest.d.ts.map +1 -1
  184. package/dist/types/common/ids/id.d.ts +11 -1
  185. package/dist/types/common/ids/id.d.ts.map +1 -1
  186. package/dist/types/common/ids/unique-id.d.ts +24 -1
  187. package/dist/types/common/ids/unique-id.d.ts.map +1 -1
  188. package/dist/types/common/session/constants.d.ts +4 -0
  189. package/dist/types/common/session/constants.d.ts.map +1 -0
  190. package/dist/types/common/session/session-entity.d.ts +72 -0
  191. package/dist/types/common/session/session-entity.d.ts.map +1 -0
  192. package/dist/types/common/storage/first-party-cookies.d.ts +8 -0
  193. package/dist/types/common/storage/first-party-cookies.d.ts.map +1 -0
  194. package/dist/types/common/storage/local-memory.d.ts +8 -0
  195. package/dist/types/common/storage/local-memory.d.ts.map +1 -0
  196. package/dist/types/common/storage/local-storage.d.ts +6 -0
  197. package/dist/types/common/storage/local-storage.d.ts.map +1 -0
  198. package/dist/types/common/timer/interaction-timer.d.ts +11 -0
  199. package/dist/types/common/timer/interaction-timer.d.ts.map +1 -0
  200. package/dist/types/common/timer/timer.d.ts +12 -0
  201. package/dist/types/common/timer/timer.d.ts.map +1 -0
  202. package/dist/types/common/timing/nav-timing.d.ts +1 -2
  203. package/dist/types/common/timing/nav-timing.d.ts.map +1 -1
  204. package/dist/types/common/unload/eol.d.ts.map +1 -1
  205. package/dist/types/common/url/location.d.ts +4 -0
  206. package/dist/types/common/url/location.d.ts.map +1 -1
  207. package/dist/types/common/url/parse-url.d.ts.map +1 -1
  208. package/dist/types/common/url/protocol.d.ts +1 -6
  209. package/dist/types/common/url/protocol.d.ts.map +1 -1
  210. package/dist/types/common/util/data-size.d.ts +7 -1
  211. package/dist/types/common/util/data-size.d.ts.map +1 -1
  212. package/dist/types/common/util/global-scope.d.ts.map +1 -1
  213. package/dist/types/common/util/invoke.d.ts +35 -0
  214. package/dist/types/common/util/invoke.d.ts.map +1 -0
  215. package/dist/types/common/util/obfuscate.d.ts.map +1 -1
  216. package/dist/types/common/window/page-visibility.d.ts +1 -1
  217. package/dist/types/common/window/page-visibility.d.ts.map +1 -1
  218. package/dist/types/common/wrap/index.d.ts +1 -2
  219. package/dist/types/common/wrap/index.d.ts.map +1 -1
  220. package/dist/types/common/wrap/wrap-fetch.d.ts.map +1 -1
  221. package/dist/types/common/wrap/wrap-history.d.ts.map +1 -1
  222. package/dist/types/common/wrap/wrap-jsonp.d.ts.map +1 -1
  223. package/dist/types/common/wrap/wrap-mutation.d.ts.map +1 -1
  224. package/dist/types/common/wrap/wrap-promise.d.ts.map +1 -1
  225. package/dist/types/common/wrap/wrap-raf.d.ts.map +1 -1
  226. package/dist/types/common/wrap/wrap-timer.d.ts.map +1 -1
  227. package/dist/types/common/wrap/wrap-xhr.d.ts.map +1 -1
  228. package/dist/types/features/ajax/aggregate/index.d.ts +2 -2
  229. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  230. package/dist/types/features/jserrors/aggregate/index.d.ts +2 -2
  231. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  232. package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
  233. package/dist/types/features/metrics/aggregate/index.d.ts +2 -2
  234. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  235. package/dist/types/features/metrics/instrument/index.d.ts +0 -1
  236. package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
  237. package/dist/types/features/metrics/instrument/workers-helper.d.ts.map +1 -1
  238. package/dist/types/features/page_action/aggregate/index.d.ts +2 -2
  239. package/dist/types/features/page_action/aggregate/index.d.ts.map +1 -1
  240. package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -2
  241. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  242. package/dist/types/features/page_view_timing/aggregate/index.d.ts +3 -4
  243. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  244. package/dist/types/features/session_trace/aggregate/index.d.ts +3 -3
  245. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  246. package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
  247. package/dist/types/features/spa/aggregate/index.d.ts +2 -2
  248. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  249. package/dist/types/features/spa/instrument/index.d.ts.map +1 -1
  250. package/dist/types/features/utils/agent-session.d.ts +2 -0
  251. package/dist/types/features/utils/agent-session.d.ts.map +1 -0
  252. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  253. package/dist/types/features/utils/lazy-loader.d.ts +2 -2
  254. package/dist/types/features/utils/lazy-loader.d.ts.map +1 -1
  255. package/dist/types/loaders/api/api.d.ts.map +1 -1
  256. package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
  257. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  258. package/package.json +12 -32
  259. package/src/common/browser-version/ios-version.js +4 -3
  260. package/src/common/config/state/configurable.js +26 -19
  261. package/src/common/config/state/init.js +7 -0
  262. package/src/common/config/state/runtime.js +7 -10
  263. package/src/common/constants/env.cdn.js +20 -0
  264. package/src/common/constants/env.js +23 -0
  265. package/src/common/constants/env.npm.js +21 -0
  266. package/src/common/context/shared-context.js +2 -1
  267. package/src/common/event-emitter/contextual-ee.test.js +310 -0
  268. package/src/common/event-emitter/handle.test.js +56 -0
  269. package/src/common/event-emitter/register-handler.test.js +61 -0
  270. package/src/common/event-listener/event-listener-opts.js +4 -4
  271. package/src/common/harvest/harvest-scheduler.js +12 -8
  272. package/src/common/harvest/harvest.js +5 -3
  273. package/src/common/ids/id.js +15 -6
  274. package/src/common/ids/id.test.js +92 -0
  275. package/src/common/ids/unique-id.js +77 -54
  276. package/src/common/ids/unique-id.test.js +58 -0
  277. package/src/common/session/constants.js +3 -0
  278. package/src/common/session/session-entity.js +271 -0
  279. package/src/common/session/session-entity.test.js +317 -0
  280. package/src/common/storage/first-party-cookies.js +31 -0
  281. package/src/common/storage/local-memory.js +30 -0
  282. package/src/common/storage/local-memory.test.js +19 -0
  283. package/src/common/storage/local-storage.js +28 -0
  284. package/src/common/storage/local-storage.test.js +17 -0
  285. package/src/common/timer/interaction-timer.js +75 -0
  286. package/src/common/timer/interaction-timer.test.js +167 -0
  287. package/src/common/timer/timer.js +31 -0
  288. package/src/common/timer/timer.test.js +100 -0
  289. package/src/common/timing/nav-timing.js +50 -30
  290. package/src/common/timing/nav-timing.test.js +161 -0
  291. package/src/common/unload/eol.js +2 -3
  292. package/src/common/url/clean-url.test.js +25 -0
  293. package/src/common/url/encode.test.js +80 -0
  294. package/src/common/url/location.js +4 -0
  295. package/src/common/url/location.test.js +15 -0
  296. package/src/common/url/parse-url.js +1 -2
  297. package/src/common/url/parse-url.test.js +110 -0
  298. package/src/common/url/protocol.js +3 -13
  299. package/src/common/url/protocol.test.js +18 -0
  300. package/src/common/util/data-size.js +6 -0
  301. package/src/common/util/data-size.test.js +50 -0
  302. package/src/common/util/global-scope.js +1 -2
  303. package/src/common/util/invoke.js +55 -0
  304. package/src/common/util/invoke.test.js +65 -0
  305. package/src/common/util/obfuscate.js +2 -6
  306. package/src/common/window/page-visibility.js +3 -3
  307. package/src/common/wrap/index.js +1 -2
  308. package/src/common/wrap/wrap-events.js +5 -5
  309. package/src/common/wrap/wrap-fetch.js +4 -3
  310. package/src/common/wrap/wrap-history.js +6 -3
  311. package/src/common/wrap/wrap-jsonp.js +5 -3
  312. package/src/common/wrap/wrap-mutation.js +6 -3
  313. package/src/common/wrap/wrap-promise.js +7 -6
  314. package/src/common/wrap/wrap-promise.test.js +140 -0
  315. package/src/common/wrap/wrap-raf.js +5 -3
  316. package/src/common/wrap/wrap-timer.js +6 -4
  317. package/src/common/wrap/wrap-xhr.js +4 -3
  318. package/src/features/ajax/aggregate/index.js +2 -2
  319. package/src/features/ajax/instrument/index.js +1 -1
  320. package/src/features/jserrors/aggregate/index.js +3 -3
  321. package/src/features/jserrors/instrument/index.js +4 -2
  322. package/src/features/metrics/aggregate/index.js +21 -7
  323. package/src/features/metrics/instrument/index.js +0 -30
  324. package/src/features/metrics/instrument/workers-helper.js +9 -6
  325. package/src/features/page_action/aggregate/index.js +2 -2
  326. package/src/features/page_view_event/aggregate/index.js +21 -9
  327. package/src/features/page_view_timing/aggregate/index.js +40 -29
  328. package/src/features/page_view_timing/long-tasks.js +10 -10
  329. package/src/features/session_trace/aggregate/index.js +17 -14
  330. package/src/features/session_trace/instrument/index.js +3 -2
  331. package/src/features/spa/aggregate/index.js +5 -5
  332. package/src/features/spa/instrument/index.js +4 -2
  333. package/src/features/utils/agent-session.js +68 -0
  334. package/src/features/utils/feature-base.js +1 -1
  335. package/src/features/utils/instrument-base.js +5 -2
  336. package/src/features/utils/lazy-loader.js +1 -1
  337. package/src/loaders/agent.js +1 -1
  338. package/src/loaders/api/api.js +3 -6
  339. package/src/loaders/api/apiAsync.js +2 -1
  340. package/src/loaders/configure/configure.js +2 -7
  341. package/dist/cjs/common/constants/environment-variables.js +0 -20
  342. package/dist/cjs/common/util/single.js +0 -23
  343. package/dist/cjs/common/window/session-storage.js +0 -87
  344. package/dist/cjs/common/wrap/wrap-console.js +0 -54
  345. package/dist/cjs/features/utils/aggregate-base.js +0 -13
  346. package/dist/esm/common/constants/environment-variables.js +0 -11
  347. package/dist/esm/common/util/single.js +0 -16
  348. package/dist/esm/common/window/session-storage.js +0 -77
  349. package/dist/esm/common/wrap/wrap-console.js +0 -46
  350. package/dist/esm/features/utils/aggregate-base.js +0 -6
  351. package/dist/types/common/constants/environment-variables.d.ts +0 -4
  352. package/dist/types/common/constants/environment-variables.d.ts.map +0 -1
  353. package/dist/types/common/util/single.d.ts +0 -2
  354. package/dist/types/common/util/single.d.ts.map +0 -1
  355. package/dist/types/common/window/session-storage.d.ts +0 -18
  356. package/dist/types/common/window/session-storage.d.ts.map +0 -1
  357. package/dist/types/common/wrap/wrap-console.d.ts +0 -16
  358. package/dist/types/common/wrap/wrap-console.d.ts.map +0 -1
  359. package/dist/types/features/utils/aggregate-base.d.ts +0 -4
  360. package/dist/types/features/utils/aggregate-base.d.ts.map +0 -1
  361. package/src/common/constants/environment-variables.js +0 -11
  362. package/src/common/util/single.js +0 -18
  363. package/src/common/window/session-storage.js +0 -75
  364. package/src/common/wrap/wrap-console.js +0 -47
  365. package/src/features/utils/aggregate-base.js +0 -7
@@ -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;
@@ -0,0 +1,436 @@
1
+ "use strict";
2
+
3
+ var _localMemory = require("../storage/local-memory");
4
+ var _localStorage = require("../storage/local-storage");
5
+ var _constants = require("./constants");
6
+ var _sessionEntity = require("./session-entity");
7
+ const agentIdentifier = 'test_agent_identifier';
8
+ const key = 'test_key';
9
+ const value = 'test_value';
10
+ jest.mock('../timer/timer');
11
+ jest.mock('../timer/interaction-timer');
12
+ jest.useFakeTimers();
13
+ const mockBrowserScope = jest.fn().mockImplementation(() => true);
14
+ jest.mock('../util/global-scope', () => ({
15
+ __esModule: true,
16
+ get isBrowserScope() {
17
+ return mockBrowserScope();
18
+ },
19
+ get globalScope() {
20
+ return global.window;
21
+ }
22
+ }));
23
+ beforeEach(() => {
24
+ jest.restoreAllMocks();
25
+ mockBrowserScope.mockReturnValue(true);
26
+ });
27
+ describe('constructor', () => {
28
+ test('must use required fields', () => {
29
+ try {
30
+ expect(new _sessionEntity.SessionEntity({})).toThrow(new Error('Missing Required Fields'));
31
+ } catch (err) {}
32
+ });
33
+ test('top-level properties are set and exposed', () => {
34
+ const session = new _sessionEntity.SessionEntity({
35
+ agentIdentifier,
36
+ key
37
+ });
38
+ expect(session).toMatchObject({
39
+ agentIdentifier: expect.any(String),
40
+ key: expect.any(String),
41
+ value: expect.any(String),
42
+ expiresMs: expect.any(Number),
43
+ expiresAt: expect.any(Number),
44
+ expiresTimer: expect.any(Object),
45
+ inactiveMs: expect.any(Number),
46
+ inactiveAt: expect.any(Number),
47
+ inactiveTimer: expect.any(Object),
48
+ isNew: expect.any(Boolean),
49
+ sessionReplayActive: expect.any(Boolean),
50
+ sessionTraceActive: expect.any(Boolean),
51
+ storage: expect.any(Object)
52
+ });
53
+ });
54
+ test('can use sane defaults', () => {
55
+ const session = new _sessionEntity.SessionEntity({
56
+ agentIdentifier,
57
+ key
58
+ });
59
+ expect(session).toEqual(expect.objectContaining({
60
+ value: expect.any(String),
61
+ expiresAt: expect.any(Number),
62
+ inactiveAt: expect.any(Number),
63
+ sessionReplayActive: expect.any(Boolean),
64
+ sessionTraceActive: expect.any(Boolean)
65
+ }));
66
+ });
67
+ test('Workers are forced to use local memory', () => {
68
+ mockBrowserScope.mockReturnValueOnce(false);
69
+ const session = new _sessionEntity.SessionEntity({
70
+ agentIdentifier,
71
+ key,
72
+ storageAPI: new _localStorage.LocalStorage()
73
+ });
74
+ expect(session.storage instanceof _localMemory.LocalMemory).toEqual(true);
75
+ });
76
+ test('expiresAt is the correct future timestamp - new session', () => {
77
+ const now = Date.now();
78
+ jest.setSystemTime(now);
79
+ const session = new _sessionEntity.SessionEntity({
80
+ agentIdentifier,
81
+ key,
82
+ expiresMs: 100
83
+ });
84
+ expect(session.expiresAt).toEqual(now + 100);
85
+ });
86
+ test('expiresAt is the correct future timestamp - existing session', () => {
87
+ const now = Date.now();
88
+ jest.setSystemTime(now);
89
+ const existingData = new _localMemory.LocalMemory({
90
+ ["".concat(_constants.PREFIX, "_").concat(key)]: {
91
+ value,
92
+ expiresAt: now + 5000,
93
+ inactiveAt: Infinity
94
+ }
95
+ });
96
+ const session = new _sessionEntity.SessionEntity({
97
+ agentIdentifier,
98
+ key,
99
+ expiresMs: 100,
100
+ storageAPI: existingData
101
+ });
102
+ expect(session.expiresAt).toEqual(now + 5000);
103
+ });
104
+ test('expiresAt never expires if 0', () => {
105
+ const session = new _sessionEntity.SessionEntity({
106
+ agentIdentifier,
107
+ key,
108
+ expiresMs: 0
109
+ });
110
+ expect(session.expiresAt).toEqual(Infinity);
111
+ });
112
+ test('inactiveAt is the correct future timestamp - new session', () => {
113
+ const now = Date.now();
114
+ jest.setSystemTime(now);
115
+ const session = new _sessionEntity.SessionEntity({
116
+ agentIdentifier,
117
+ key,
118
+ inactiveMs: 100
119
+ });
120
+ expect(session.inactiveAt).toEqual(now + 100);
121
+ });
122
+ test('inactiveAt is the correct future timestamp - existing session', () => {
123
+ const now = Date.now();
124
+ jest.setSystemTime(now);
125
+ const existingData = new _localMemory.LocalMemory({
126
+ ["".concat(_constants.PREFIX, "_").concat(key)]: {
127
+ value,
128
+ inactiveAt: now + 5000,
129
+ expiresAt: Infinity
130
+ }
131
+ });
132
+ const session = new _sessionEntity.SessionEntity({
133
+ agentIdentifier,
134
+ key,
135
+ inactiveMs: 100,
136
+ storageAPI: existingData
137
+ });
138
+ expect(session.inactiveAt).toEqual(now + 5000);
139
+ });
140
+ test('inactiveAt never expires if 0', () => {
141
+ const session = new _sessionEntity.SessionEntity({
142
+ agentIdentifier,
143
+ key,
144
+ inactiveMs: 0
145
+ });
146
+ expect(session.inactiveAt).toEqual(Infinity);
147
+ });
148
+ test('should handle isNew', () => {
149
+ const newSession = new _sessionEntity.SessionEntity({
150
+ agentIdentifier,
151
+ key,
152
+ expiresMs: 10
153
+ });
154
+ expect(newSession.isNew).toBeTruthy();
155
+ const storageAPI = new _localMemory.LocalMemory({
156
+ ["".concat(_constants.PREFIX, "_").concat(key)]: {
157
+ value,
158
+ expiresAt: Infinity,
159
+ inactiveAt: Infinity
160
+ }
161
+ });
162
+ const existingSession = new _sessionEntity.SessionEntity({
163
+ agentIdentifier,
164
+ key,
165
+ expiresMs: 10,
166
+ storageAPI
167
+ });
168
+ expect(existingSession.isNew).toBeFalsy();
169
+ });
170
+ test('invalid stored values sets new defaults', () => {
171
+ // missing required fields
172
+ const storageAPI = new _localMemory.LocalMemory({
173
+ ["".concat(_constants.PREFIX, "_").concat(key)]: {
174
+ invalid_fields: true
175
+ }
176
+ });
177
+ const session = new _sessionEntity.SessionEntity({
178
+ agentIdentifier,
179
+ key,
180
+ storageAPI
181
+ });
182
+ expect(session).toEqual(expect.objectContaining({
183
+ value: expect.any(String),
184
+ expiresAt: expect.any(Number),
185
+ inactiveAt: expect.any(Number),
186
+ sessionReplayActive: expect.any(Boolean),
187
+ sessionTraceActive: expect.any(Boolean)
188
+ }));
189
+ });
190
+ test('expired expiresAt value in storage sets new defaults', () => {
191
+ const now = Date.now();
192
+ jest.setSystemTime(now);
193
+ const storageAPI = new _localMemory.LocalMemory({
194
+ ["".concat(_constants.PREFIX, "_").concat(key)]: {
195
+ value,
196
+ expiresAt: now - 100,
197
+ inactiveAt: Infinity
198
+ }
199
+ });
200
+ const session = new _sessionEntity.SessionEntity({
201
+ agentIdentifier,
202
+ key,
203
+ storageAPI
204
+ });
205
+ expect(session).toEqual(expect.objectContaining({
206
+ value: expect.any(String),
207
+ expiresAt: expect.any(Number),
208
+ inactiveAt: expect.any(Number),
209
+ sessionReplayActive: expect.any(Boolean),
210
+ sessionTraceActive: expect.any(Boolean)
211
+ }));
212
+ });
213
+ test('expired inactiveAt value in storage sets new defaults', () => {
214
+ const now = Date.now();
215
+ jest.setSystemTime(now);
216
+ const storageAPI = new _localMemory.LocalMemory({
217
+ ["".concat(_constants.PREFIX, "_").concat(key)]: {
218
+ value,
219
+ inactiveAt: now - 100,
220
+ expiresAt: Infinity
221
+ }
222
+ });
223
+ const session = new _sessionEntity.SessionEntity({
224
+ agentIdentifier,
225
+ key,
226
+ storageAPI
227
+ });
228
+ expect(session).toEqual(expect.objectContaining({
229
+ value: expect.any(String),
230
+ expiresAt: expect.any(Number),
231
+ inactiveAt: expect.any(Number),
232
+ sessionReplayActive: expect.any(Boolean),
233
+ sessionTraceActive: expect.any(Boolean)
234
+ }));
235
+ });
236
+ });
237
+ describe('reset()', () => {
238
+ test('should create new default values when resetting', () => {
239
+ const now = Date.now();
240
+ jest.setSystemTime(now);
241
+ const session = new _sessionEntity.SessionEntity({
242
+ agentIdentifier,
243
+ key,
244
+ expiresMs: 10
245
+ });
246
+ const sessionVal = session.value;
247
+ expect(session.value).toBeTruthy();
248
+ session.reset();
249
+ expect(session.value).toBeTruthy();
250
+ expect(session.value).not.toEqual(sessionVal);
251
+ });
252
+ test('custom data should be wiped on reset', () => {
253
+ const now = Date.now();
254
+ jest.setSystemTime(now);
255
+ const session = new _sessionEntity.SessionEntity({
256
+ agentIdentifier,
257
+ key,
258
+ expiresMs: 10
259
+ });
260
+ session.syncCustomAttribute('test', 123);
261
+ expect(session.custom.test).toEqual(123);
262
+ expect(session.read().custom.test).toEqual(123);
263
+
264
+ // simulate a timer expiring
265
+ session.reset();
266
+ expect(session.custom?.test).toEqual(undefined);
267
+ expect(session.read()?.custom?.test).toEqual(undefined);
268
+ });
269
+ });
270
+ describe('read()', () => {
271
+ test('"new" sessions get data from read()', () => {
272
+ const newSession = new _sessionEntity.SessionEntity({
273
+ agentIdentifier,
274
+ key,
275
+ expiresMs: 10
276
+ });
277
+ expect(newSession.isNew).toBeTruthy();
278
+ expect(newSession.read()).toEqual(expect.objectContaining({
279
+ value: expect.any(String),
280
+ expiresAt: expect.any(Number),
281
+ inactiveAt: expect.any(Number),
282
+ sessionReplayActive: expect.any(Boolean),
283
+ sessionTraceActive: expect.any(Boolean)
284
+ }));
285
+ });
286
+ test('"pre-existing" sessions get data from read()', () => {
287
+ const storageAPI = new _localMemory.LocalMemory({
288
+ ["".concat(_constants.PREFIX, "_").concat(key)]: {
289
+ value,
290
+ expiresAt: Infinity,
291
+ inactiveAt: Infinity
292
+ }
293
+ });
294
+ const session = new _sessionEntity.SessionEntity({
295
+ agentIdentifier,
296
+ key,
297
+ storageAPI
298
+ });
299
+ expect(session.isNew).toBeFalsy();
300
+ expect(session.read()).toEqual(expect.objectContaining({
301
+ value,
302
+ expiresAt: Infinity,
303
+ inactiveAt: Infinity
304
+ }));
305
+ });
306
+ });
307
+ describe('write()', () => {
308
+ test('write() sets data to top-level wrapper', () => {
309
+ const session = new _sessionEntity.SessionEntity({
310
+ agentIdentifier,
311
+ key
312
+ });
313
+ expect(session.value).not.toEqual(value);
314
+ expect(session.expiresAt).not.toEqual(Infinity);
315
+ expect(session.inactiveAt).not.toEqual(Infinity);
316
+ session.write({
317
+ value,
318
+ expiresAt: Infinity,
319
+ inactiveAt: Infinity
320
+ });
321
+ expect(session.value).toEqual(value);
322
+ expect(session.expiresAt).toEqual(Infinity);
323
+ expect(session.inactiveAt).toEqual(Infinity);
324
+ });
325
+ test('write() sets data that read() can access', () => {
326
+ const now = Date.now();
327
+ jest.setSystemTime(now);
328
+ const session = new _sessionEntity.SessionEntity({
329
+ agentIdentifier,
330
+ key
331
+ });
332
+ session.write({
333
+ value,
334
+ expiresAt: now + 100,
335
+ inactiveAt: now + 100
336
+ });
337
+ const read = session.read();
338
+ expect(read.value).toEqual(value);
339
+ expect(read.expiresAt).toEqual(now + 100);
340
+ expect(read.inactiveAt).toEqual(now + 100);
341
+ });
342
+ test('write() does not run with invalid data', () => {
343
+ const session = new _sessionEntity.SessionEntity({
344
+ agentIdentifier,
345
+ key
346
+ });
347
+ let out = session.write();
348
+ expect(out).toEqual(undefined);
349
+ out = session.write('string');
350
+ expect(out).toEqual(undefined);
351
+ out = session.write(123);
352
+ expect(out).toEqual(undefined);
353
+ out = session.write(true);
354
+ expect(out).toEqual(undefined);
355
+ out = session.write(false);
356
+ expect(out).toEqual(undefined);
357
+ });
358
+ });
359
+ describe('refresh()', () => {
360
+ test('refresh sets inactiveAt to future time', () => {
361
+ const now = Date.now();
362
+ jest.setSystemTime(now);
363
+ const session = new _sessionEntity.SessionEntity({
364
+ agentIdentifier,
365
+ key,
366
+ inactiveMs: 100
367
+ });
368
+ expect(session.inactiveAt).toEqual(now + 100);
369
+ jest.setSystemTime(now + 1000);
370
+ session.refresh();
371
+ expect(session.inactiveAt).toEqual(now + 100 + 1000);
372
+ });
373
+ test('refresh resets the entity if expiresTimer is invalid', () => {
374
+ const now = Date.now();
375
+ jest.setSystemTime(now);
376
+ const session = new _sessionEntity.SessionEntity({
377
+ agentIdentifier,
378
+ key,
379
+ value
380
+ });
381
+ expect(session.value).toEqual(value);
382
+ session.write({
383
+ ...session.read(),
384
+ expiresAt: now - 1
385
+ });
386
+ session.refresh();
387
+ expect(session.value).not.toEqual(value);
388
+ });
389
+ test('refresh resets the entity if inactiveTimer is invalid', () => {
390
+ const now = Date.now();
391
+ jest.setSystemTime(now);
392
+ const session = new _sessionEntity.SessionEntity({
393
+ agentIdentifier,
394
+ key,
395
+ value
396
+ });
397
+ expect(session.value).toEqual(value);
398
+ session.write({
399
+ ...session.read(),
400
+ inactiveAt: now - 1
401
+ });
402
+ session.refresh();
403
+ expect(session.value).not.toEqual(value);
404
+ });
405
+ });
406
+ describe('syncCustomAttribute()', () => {
407
+ test('Custom data can be managed by session entity', () => {
408
+ const session = new _sessionEntity.SessionEntity({
409
+ agentIdentifier,
410
+ key
411
+ });
412
+
413
+ // if custom has never been set, and a "delete" action is triggered, do nothing
414
+ session.syncCustomAttribute('test', null);
415
+ expect(session?.custom?.test).toEqual(undefined);
416
+ session.syncCustomAttribute('test', 1);
417
+ expect(session?.custom?.test).toEqual(1);
418
+ session.syncCustomAttribute('test', 'string');
419
+ expect(session?.custom?.test).toEqual('string');
420
+ session.syncCustomAttribute('test', false);
421
+ expect(session?.custom?.test).toEqual(false);
422
+
423
+ // null specifically deletes the object completely
424
+ session.syncCustomAttribute('test', null);
425
+ expect(session?.custom?.test).toEqual(undefined);
426
+ });
427
+ test('Only runs in browser scope', () => {
428
+ mockBrowserScope.mockReturnValue(false);
429
+ const session = new _sessionEntity.SessionEntity({
430
+ agentIdentifier,
431
+ key
432
+ });
433
+ session.syncCustomAttribute('test', 1);
434
+ expect(session.read().custom?.test).toEqual(undefined);
435
+ });
436
+ });