@cloudcare/browser-core 3.2.3 → 3.2.6

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 (82) hide show
  1. package/cjs/browser/cookie.js +14 -9
  2. package/cjs/browser/cookie.js.map +1 -1
  3. package/cjs/configuration/configuration.js +2 -23
  4. package/cjs/configuration/configuration.js.map +1 -1
  5. package/cjs/helper/requestIdleCallback.js +46 -0
  6. package/cjs/helper/requestIdleCallback.js.map +1 -0
  7. package/cjs/helper/taskQueue.js +59 -0
  8. package/cjs/helper/taskQueue.js.map +1 -0
  9. package/cjs/helper/tools.js +1 -1
  10. package/cjs/helper/tools.js.map +1 -1
  11. package/cjs/index.js +112 -41
  12. package/cjs/index.js.map +1 -1
  13. package/cjs/init.js +0 -19
  14. package/cjs/init.js.map +1 -1
  15. package/cjs/session/sessionConstants.js +3 -1
  16. package/cjs/session/sessionConstants.js.map +1 -1
  17. package/cjs/session/sessionInCookie.js +59 -0
  18. package/cjs/session/sessionInCookie.js.map +1 -0
  19. package/cjs/session/sessionInLocalStorage.js +44 -0
  20. package/cjs/session/sessionInLocalStorage.js.map +1 -0
  21. package/cjs/session/sessionManagement.js +38 -31
  22. package/cjs/session/sessionManagement.js.map +1 -1
  23. package/cjs/session/sessionState.js +73 -0
  24. package/cjs/session/sessionState.js.map +1 -0
  25. package/cjs/session/sessionStore.js +113 -90
  26. package/cjs/session/sessionStore.js.map +1 -1
  27. package/cjs/session/sessionStoreOperations.js +117 -0
  28. package/cjs/session/sessionStoreOperations.js.map +1 -0
  29. package/esm/browser/cookie.js +15 -8
  30. package/esm/browser/cookie.js.map +1 -1
  31. package/esm/configuration/configuration.js +2 -22
  32. package/esm/configuration/configuration.js.map +1 -1
  33. package/esm/helper/requestIdleCallback.js +38 -0
  34. package/esm/helper/requestIdleCallback.js.map +1 -0
  35. package/esm/helper/taskQueue.js +52 -0
  36. package/esm/helper/taskQueue.js.map +1 -0
  37. package/esm/helper/tools.js +1 -1
  38. package/esm/helper/tools.js.map +1 -1
  39. package/esm/index.js +5 -4
  40. package/esm/index.js.map +1 -1
  41. package/esm/init.js +0 -19
  42. package/esm/init.js.map +1 -1
  43. package/esm/session/sessionConstants.js +1 -0
  44. package/esm/session/sessionConstants.js.map +1 -1
  45. package/esm/session/sessionInCookie.js +51 -0
  46. package/esm/session/sessionInCookie.js.map +1 -0
  47. package/esm/session/sessionInLocalStorage.js +37 -0
  48. package/esm/session/sessionInLocalStorage.js.map +1 -0
  49. package/esm/session/sessionManagement.js +35 -28
  50. package/esm/session/sessionManagement.js.map +1 -1
  51. package/esm/session/sessionState.js +59 -0
  52. package/esm/session/sessionState.js.map +1 -0
  53. package/esm/session/sessionStore.js +113 -90
  54. package/esm/session/sessionStore.js.map +1 -1
  55. package/esm/session/sessionStoreOperations.js +108 -0
  56. package/esm/session/sessionStoreOperations.js.map +1 -0
  57. package/package.json +2 -2
  58. package/src/browser/cookie.js +23 -11
  59. package/src/configuration/configuration.js +3 -30
  60. package/src/helper/requestIdleCallback.js +38 -0
  61. package/src/helper/taskQueue.js +55 -0
  62. package/src/helper/tools.js +6 -1
  63. package/src/index.js +11 -4
  64. package/src/init.js +0 -19
  65. package/src/session/sessionConstants.js +1 -0
  66. package/src/session/sessionInCookie.js +87 -0
  67. package/src/session/sessionInLocalStorage.js +45 -0
  68. package/src/session/sessionManagement.js +48 -36
  69. package/src/session/sessionState.js +72 -0
  70. package/src/session/sessionStore.js +163 -108
  71. package/src/session/sessionStoreOperations.js +134 -0
  72. package/types/index.d.ts +4 -0
  73. package/cjs/session/sessionCookieStore.js +0 -156
  74. package/cjs/session/sessionCookieStore.js.map +0 -1
  75. package/cjs/synthetics/usr.js +0 -26
  76. package/cjs/synthetics/usr.js.map +0 -1
  77. package/esm/session/sessionCookieStore.js +0 -142
  78. package/esm/session/sessionCookieStore.js.map +0 -1
  79. package/esm/synthetics/usr.js +0 -17
  80. package/esm/synthetics/usr.js.map +0 -1
  81. package/src/session/sessionCookieStore.js +0 -169
  82. package/src/synthetics/usr.js +0 -18
@@ -0,0 +1,55 @@
1
+ import { ONE_SECOND } from './tools'
2
+ import { requestIdleCallback } from './requestIdleCallback'
3
+
4
+ /**
5
+ * Maximum delay before starting to execute tasks in the queue. We don't want to wait too long
6
+ * before running tasks, as it might hurt reliability (ex: if the user navigates away, we might lose
7
+ * the opportunity to send some data). We also don't want to run tasks too often, as it might hurt
8
+ * performance.
9
+ */
10
+ const IDLE_CALLBACK_TIMEOUT = ONE_SECOND
11
+
12
+ /**
13
+ * Maximum amount of time allocated to running tasks when a timeout (`IDLE_CALLBACK_TIMEOUT`) is
14
+ * reached. We should not run tasks for too long as it will hurt performance, but we should still
15
+ * run some tasks to avoid postponing them forever.
16
+ *
17
+ * Rational: Running tasks for 30ms every second (IDLE_CALLBACK_TIMEOUT) should be acceptable.
18
+ */
19
+ export const MAX_EXECUTION_TIME_ON_TIMEOUT = 30
20
+
21
+ export function createTaskQueue() {
22
+ const pendingTasks = []
23
+
24
+ function run(deadline) {
25
+ let executionTimeRemaining
26
+ if (deadline.didTimeout) {
27
+ const start = performance.now()
28
+ executionTimeRemaining = function () {
29
+ return MAX_EXECUTION_TIME_ON_TIMEOUT - (performance.now() - start)
30
+ }
31
+ } else {
32
+ executionTimeRemaining = deadline.timeRemaining.bind(deadline)
33
+ }
34
+
35
+ while (executionTimeRemaining() > 0 && pendingTasks.length) {
36
+ pendingTasks.shift()()
37
+ }
38
+
39
+ if (pendingTasks.length) {
40
+ scheduleNextRun()
41
+ }
42
+ }
43
+
44
+ function scheduleNextRun() {
45
+ requestIdleCallback(run, { timeout: IDLE_CALLBACK_TIMEOUT })
46
+ }
47
+
48
+ return {
49
+ push(task) {
50
+ if (pendingTasks.push(task) === 1) {
51
+ scheduleNextRun()
52
+ }
53
+ }
54
+ }
55
+ }
@@ -1553,7 +1553,12 @@ export function findByPath(source, path) {
1553
1553
  var pathArr = path.split('.')
1554
1554
  while (pathArr.length) {
1555
1555
  var key = pathArr.shift()
1556
- if (source && key in source && hasOwnProperty.call(source, key)) {
1556
+ if (
1557
+ source &&
1558
+ isObject(source) &&
1559
+ key in source &&
1560
+ hasOwnProperty.call(source, key)
1561
+ ) {
1557
1562
  source = source[key]
1558
1563
  } else {
1559
1564
  return undefined
package/src/index.js CHANGED
@@ -22,6 +22,8 @@ export * from './helper/mobileUtil'
22
22
  export * from './helper/getZoneJsOriginalValue'
23
23
  export * from './helper/timer'
24
24
  export * from './helper/readBytesFromStream'
25
+ export * from './helper/requestIdleCallback'
26
+ export * from './helper/taskQueue'
25
27
  export * from './tracekit'
26
28
  export * from './configuration/configuration'
27
29
  export * from './configuration/transportConfiguration'
@@ -36,10 +38,15 @@ export * from './browser/scroll'
36
38
 
37
39
  export * from './dataMap'
38
40
  export * from './init'
39
- export * from './session/sessionManagement'
40
- export * from './session/sessionConstants'
41
- export * from './session/sessionCookieStore'
42
- export * from './session/sessionStore'
41
+ export {
42
+ startSessionManager,
43
+ stopSessionManager
44
+ } from './session/sessionManagement'
45
+ export {
46
+ SESSION_TIME_OUT_DELAY,
47
+ SESSION_STORE_KEY
48
+ } from './session/sessionConstants'
49
+ export { STORAGE_POLL_DELAY } from './session/sessionStore'
43
50
  export * from './transport'
44
51
  export * from './synthetics/syntheticsWorkerValues'
45
52
 
package/src/init.js CHANGED
@@ -60,22 +60,3 @@ export function getGlobalObject() {
60
60
  }
61
61
  return globalObject
62
62
  }
63
- // export function checkCookiesAuthorized(options) {
64
- // if (!areCookiesAuthorized(options)) {
65
- // console.warn('Cookies are not authorized, we will not send any data.')
66
- // return false
67
- // }
68
- // return true
69
- // }
70
-
71
- // export function checkIsNotLocalFile() {
72
- // if (isLocalFile()) {
73
- // console.error('Execution is not allowed in the current context.')
74
- // return false
75
- // }
76
- // return true
77
- // }
78
-
79
- // function isLocalFile() {
80
- // return window.location.protocol === 'file:'
81
- // }
@@ -1,3 +1,4 @@
1
1
  import { ONE_HOUR, ONE_MINUTE } from '../helper/tools'
2
2
  export var SESSION_TIME_OUT_DELAY = 4 * ONE_HOUR
3
3
  export var SESSION_EXPIRATION_DELAY = 15 * ONE_MINUTE
4
+ export var SESSION_STORE_KEY = '_gc_s'
@@ -0,0 +1,87 @@
1
+ import { isChromium } from '../helper/tools'
2
+ import {
3
+ getCurrentSite,
4
+ areCookiesAuthorized,
5
+ getCookie,
6
+ setCookie
7
+ } from '../browser/cookie'
8
+ import {
9
+ SESSION_EXPIRATION_DELAY,
10
+ SESSION_TIME_OUT_DELAY,
11
+ SESSION_STORE_KEY
12
+ } from './sessionConstants'
13
+ import {
14
+ toSessionString,
15
+ toSessionState,
16
+ getExpiredSessionState
17
+ } from './sessionState'
18
+
19
+ export function selectCookieStrategy(initConfiguration) {
20
+ const cookieOptions = buildCookieOptions(initConfiguration)
21
+ return areCookiesAuthorized(cookieOptions)
22
+ ? { type: 'Cookie', cookieOptions }
23
+ : undefined
24
+ }
25
+
26
+ export function initCookieStrategy(cookieOptions) {
27
+ const cookieStore = {
28
+ /**
29
+ * Lock strategy allows mitigating issues due to concurrent access to cookie.
30
+ * This issue concerns only chromium browsers and enabling this on firefox increases cookie write failures.
31
+ */
32
+ isLockEnabled: isChromium(),
33
+ persistSession: persistSessionCookie(cookieOptions),
34
+ retrieveSession: retrieveSessionCookie(cookieOptions),
35
+ expireSession: function () {
36
+ return expireSessionCookie(cookieOptions)
37
+ }
38
+ }
39
+ return cookieStore
40
+ }
41
+
42
+ function persistSessionCookie(options) {
43
+ return function (session) {
44
+ setCookie(
45
+ SESSION_STORE_KEY,
46
+ toSessionString(session),
47
+ SESSION_EXPIRATION_DELAY,
48
+ options
49
+ )
50
+ }
51
+ }
52
+
53
+ function expireSessionCookie(options) {
54
+ setCookie(
55
+ SESSION_STORE_KEY,
56
+ toSessionString(getExpiredSessionState()),
57
+ SESSION_TIME_OUT_DELAY,
58
+ options
59
+ )
60
+ }
61
+
62
+ function retrieveSessionCookie(options) {
63
+ return function () {
64
+ var sessionString = getCookie(SESSION_STORE_KEY, options)
65
+ return toSessionState(sessionString)
66
+ }
67
+ }
68
+
69
+ export function buildCookieOptions(initConfiguration) {
70
+ const cookieOptions = {}
71
+
72
+ cookieOptions.secure =
73
+ !!initConfiguration.useSecureSessionCookie ||
74
+ !!initConfiguration.usePartitionedCrossSiteSessionCookie ||
75
+ !!initConfiguration.useCrossSiteSessionCookie
76
+ cookieOptions.crossSite =
77
+ !!initConfiguration.usePartitionedCrossSiteSessionCookie ||
78
+ !!initConfiguration.useCrossSiteSessionCookie
79
+ cookieOptions.partitioned =
80
+ !!initConfiguration.usePartitionedCrossSiteSessionCookie
81
+
82
+ if (initConfiguration.trackSessionAcrossSubdomains) {
83
+ cookieOptions.domain = getCurrentSite()
84
+ }
85
+
86
+ return cookieOptions
87
+ }
@@ -0,0 +1,45 @@
1
+ import { UUID } from '../helper/tools'
2
+ import {
3
+ toSessionString,
4
+ toSessionState,
5
+ getExpiredSessionState
6
+ } from './sessionState'
7
+
8
+ import { SESSION_STORE_KEY } from './sessionConstants'
9
+
10
+ const LOCAL_STORAGE_TEST_KEY = '_gc_test_'
11
+
12
+ export function selectLocalStorageStrategy() {
13
+ try {
14
+ const id = UUID()
15
+ const testKey = `${LOCAL_STORAGE_TEST_KEY}${id}`
16
+ localStorage.setItem(testKey, id)
17
+ const retrievedId = localStorage.getItem(testKey)
18
+ localStorage.removeItem(testKey)
19
+ return id === retrievedId ? { type: 'LocalStorage' } : undefined
20
+ } catch (e) {
21
+ return undefined
22
+ }
23
+ }
24
+
25
+ export function initLocalStorageStrategy() {
26
+ return {
27
+ isLockEnabled: false,
28
+ persistSession: persistInLocalStorage,
29
+ retrieveSession: retrieveSessionFromLocalStorage,
30
+ expireSession: expireSessionFromLocalStorage
31
+ }
32
+ }
33
+
34
+ function persistInLocalStorage(sessionState) {
35
+ localStorage.setItem(SESSION_STORE_KEY, toSessionString(sessionState))
36
+ }
37
+
38
+ function retrieveSessionFromLocalStorage() {
39
+ const sessionString = localStorage.getItem(SESSION_STORE_KEY)
40
+ return toSessionState(sessionString)
41
+ }
42
+
43
+ function expireSessionFromLocalStorage() {
44
+ persistInLocalStorage(getExpiredSessionState())
45
+ }
@@ -1,31 +1,37 @@
1
- import { relativeNow, clocksOrigin, ONE_MINUTE, each } from '../helper/tools'
2
- import {
3
- addEventListeners,
4
- addEventListener
5
- } from '../browser/addEventListener'
1
+ import { Observable } from '../helper/observable'
6
2
  import { createValueHistory } from '../helper/valueHistory'
7
- import { startSessionStore } from './sessionStore'
8
- import { SESSION_TIME_OUT_DELAY } from './sessionConstants'
3
+ import { relativeNow, clocksOrigin, ONE_MINUTE } from '../helper/tools'
9
4
  import { DOM_EVENT } from '../helper/enums'
5
+ import {
6
+ addEventListener,
7
+ addEventListeners
8
+ } from '../browser/addEventListener'
10
9
  import { clearInterval, setInterval } from '../helper/timer'
11
- import { Observable } from '../helper/observable'
12
- export var VISIBILITY_CHECK_DELAY = ONE_MINUTE
13
- var SESSION_CONTEXT_TIMEOUT_DELAY = SESSION_TIME_OUT_DELAY
14
- var stopCallbacks = []
10
+ import { SESSION_TIME_OUT_DELAY } from './sessionConstants'
11
+ import { startSessionStore } from './sessionStore'
15
12
 
16
- export var startSessionManager = function (
17
- options,
13
+ export const VISIBILITY_CHECK_DELAY = ONE_MINUTE
14
+ const SESSION_CONTEXT_TIMEOUT_DELAY = SESSION_TIME_OUT_DELAY
15
+ let stopCallbacks = []
16
+
17
+ export function startSessionManager(
18
+ configuration,
18
19
  productKey,
19
20
  computeSessionState
20
21
  ) {
21
- var renewObservable = new Observable()
22
- var expireObservable = new Observable()
23
- var sessionStore = startSessionStore(options, productKey, computeSessionState)
22
+ const renewObservable = new Observable()
23
+ const expireObservable = new Observable()
24
+
25
+ const sessionStore = startSessionStore(
26
+ configuration.sessionStoreStrategyType,
27
+ productKey,
28
+ computeSessionState
29
+ )
24
30
  stopCallbacks.push(function () {
25
31
  return sessionStore.stop()
26
32
  })
27
33
 
28
- var sessionContextHistory = createValueHistory({
34
+ const sessionContextHistory = createValueHistory({
29
35
  expireDelay: SESSION_CONTEXT_TIMEOUT_DELAY
30
36
  })
31
37
  stopCallbacks.push(function () {
@@ -41,18 +47,20 @@ export var startSessionManager = function (
41
47
  sessionContextHistory.closeActive(relativeNow())
42
48
  })
43
49
 
50
+ // We expand/renew session unconditionally as tracking consent is always granted when the session
51
+ // manager is started.
44
52
  sessionStore.expandOrRenewSession()
45
53
  sessionContextHistory.add(buildSessionContext(), clocksOrigin().relative)
46
54
 
47
55
  trackActivity(function () {
48
- return sessionStore.expandOrRenewSession()
56
+ sessionStore.expandOrRenewSession()
49
57
  })
50
58
  trackVisibility(function () {
51
59
  return sessionStore.expandSession()
52
60
  })
53
- // trackResume(function () {
54
- // return sessionStore.expandSession()
55
- // })
61
+ trackResume(function () {
62
+ sessionStore.restartSession()
63
+ })
56
64
 
57
65
  function buildSessionContext() {
58
66
  return {
@@ -62,24 +70,26 @@ export var startSessionManager = function (
62
70
  }
63
71
 
64
72
  return {
65
- findActiveSession: function (startTime) {
66
- return sessionContextHistory.find(startTime)
73
+ findSession: function (startTime, options) {
74
+ return sessionContextHistory.find(startTime, options)
67
75
  },
68
- renewObservable: renewObservable,
69
- expireObservable: expireObservable,
70
- expire: sessionStore.expire
76
+ renewObservable,
77
+ expireObservable,
78
+ sessionStateUpdateObservable: sessionStore.sessionStateUpdateObservable,
79
+ expire: sessionStore.expire,
80
+ updateSessionState: sessionStore.updateSessionState
71
81
  }
72
82
  }
73
83
 
74
84
  export function stopSessionManager() {
75
- each(stopCallbacks, function (e) {
76
- return e()
85
+ stopCallbacks.forEach(function (e) {
86
+ e()
77
87
  })
78
88
  stopCallbacks = []
79
89
  }
80
90
 
81
91
  function trackActivity(expandOrRenewSession) {
82
- var _addEventListeners = addEventListeners(
92
+ const { stop } = addEventListeners(
83
93
  window,
84
94
  [
85
95
  DOM_EVENT.CLICK,
@@ -90,23 +100,24 @@ function trackActivity(expandOrRenewSession) {
90
100
  expandOrRenewSession,
91
101
  { capture: true, passive: true }
92
102
  )
93
- stopCallbacks.push(_addEventListeners.stop)
103
+ stopCallbacks.push(stop)
94
104
  }
95
105
 
96
106
  function trackVisibility(expandSession) {
97
- var expandSessionWhenVisible = function () {
107
+ const expandSessionWhenVisible = function () {
98
108
  if (document.visibilityState === 'visible') {
99
109
  expandSession()
100
110
  }
101
111
  }
102
- var _addEventListener = addEventListener(
112
+
113
+ const { stop } = addEventListener(
103
114
  document,
104
115
  DOM_EVENT.VISIBILITY_CHANGE,
105
116
  expandSessionWhenVisible
106
117
  )
107
- stopCallbacks.push(_addEventListener.stop)
118
+ stopCallbacks.push(stop)
108
119
 
109
- var visibilityCheckInterval = setInterval(
120
+ const visibilityCheckInterval = setInterval(
110
121
  expandSessionWhenVisible,
111
122
  VISIBILITY_CHECK_DELAY
112
123
  )
@@ -114,9 +125,10 @@ function trackVisibility(expandSession) {
114
125
  clearInterval(visibilityCheckInterval)
115
126
  })
116
127
  }
128
+
117
129
  function trackResume(cb) {
118
- var _addEventListener = addEventListener(window, DOM_EVENT.RESUME, cb, {
130
+ const { stop } = addEventListener(window, DOM_EVENT.RESUME, cb, {
119
131
  capture: true
120
132
  })
121
- stopCallbacks.push(_addEventListener.stop)
133
+ stopCallbacks.push(stop)
122
134
  }
@@ -0,0 +1,72 @@
1
+ import { isEmptyObject, objectEntries, dateNow, map } from '../helper/tools'
2
+ import {
3
+ SESSION_EXPIRATION_DELAY,
4
+ SESSION_TIME_OUT_DELAY
5
+ } from './sessionConstants'
6
+
7
+ const SESSION_ENTRY_REGEXP = /^([a-zA-Z]+)=([a-z0-9-]+)$/
8
+ const SESSION_ENTRY_SEPARATOR = '&'
9
+
10
+ export const EXPIRED = '1'
11
+
12
+ export function getExpiredSessionState() {
13
+ return {
14
+ isExpired: EXPIRED
15
+ }
16
+ }
17
+
18
+ export function isSessionInNotStartedState(session) {
19
+ return isEmptyObject(session)
20
+ }
21
+
22
+ export function isSessionStarted(session) {
23
+ return !isSessionInNotStartedState(session)
24
+ }
25
+
26
+ export function isSessionInExpiredState(session) {
27
+ return session.isExpired !== undefined || !isActiveSession(session)
28
+ }
29
+
30
+ // An active session is a session in either `Tracked` or `NotTracked` state
31
+ function isActiveSession(sessionState) {
32
+ // created and expire can be undefined for versions which was not storing them
33
+ // these checks could be removed when older versions will not be available/live anymore
34
+ return (
35
+ (sessionState.created === undefined ||
36
+ dateNow() - Number(sessionState.created) < SESSION_TIME_OUT_DELAY) &&
37
+ (sessionState.expire === undefined ||
38
+ dateNow() < Number(sessionState.expire))
39
+ )
40
+ }
41
+
42
+ export function expandSessionState(session) {
43
+ session.expire = String(dateNow() + SESSION_EXPIRATION_DELAY)
44
+ }
45
+
46
+ export function toSessionString(session) {
47
+ return map(objectEntries(session), function (item) {
48
+ return item[0] + '=' + item[1]
49
+ }).join(SESSION_ENTRY_SEPARATOR)
50
+ }
51
+
52
+ export function toSessionState(sessionString) {
53
+ const session = {}
54
+ if (isValidSessionString(sessionString)) {
55
+ sessionString.split(SESSION_ENTRY_SEPARATOR).forEach(function (entry) {
56
+ const matches = SESSION_ENTRY_REGEXP.exec(entry)
57
+ if (matches !== null) {
58
+ const [, key, value] = matches
59
+ session[key] = value
60
+ }
61
+ })
62
+ }
63
+ return session
64
+ }
65
+
66
+ function isValidSessionString(sessionString) {
67
+ return (
68
+ !!sessionString &&
69
+ (sessionString.indexOf(SESSION_ENTRY_SEPARATOR) !== -1 ||
70
+ SESSION_ENTRY_REGEXP.test(sessionString))
71
+ )
72
+ }