@cloudcare/browser-core 3.2.4 → 3.2.7

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 (67) 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 +3 -24
  4. package/cjs/configuration/configuration.js.map +1 -1
  5. package/cjs/index.js +90 -41
  6. package/cjs/index.js.map +1 -1
  7. package/cjs/init.js +0 -19
  8. package/cjs/init.js.map +1 -1
  9. package/cjs/session/sessionConstants.js +3 -1
  10. package/cjs/session/sessionConstants.js.map +1 -1
  11. package/cjs/session/sessionInCookie.js +59 -0
  12. package/cjs/session/sessionInCookie.js.map +1 -0
  13. package/cjs/session/sessionInLocalStorage.js +44 -0
  14. package/cjs/session/sessionInLocalStorage.js.map +1 -0
  15. package/cjs/session/sessionManagement.js +38 -31
  16. package/cjs/session/sessionManagement.js.map +1 -1
  17. package/cjs/session/sessionState.js +73 -0
  18. package/cjs/session/sessionState.js.map +1 -0
  19. package/cjs/session/sessionStore.js +113 -90
  20. package/cjs/session/sessionStore.js.map +1 -1
  21. package/cjs/session/sessionStoreOperations.js +117 -0
  22. package/cjs/session/sessionStoreOperations.js.map +1 -0
  23. package/esm/browser/cookie.js +15 -8
  24. package/esm/browser/cookie.js.map +1 -1
  25. package/esm/configuration/configuration.js +3 -23
  26. package/esm/configuration/configuration.js.map +1 -1
  27. package/esm/index.js +3 -4
  28. package/esm/index.js.map +1 -1
  29. package/esm/init.js +0 -19
  30. package/esm/init.js.map +1 -1
  31. package/esm/session/sessionConstants.js +1 -0
  32. package/esm/session/sessionConstants.js.map +1 -1
  33. package/esm/session/sessionInCookie.js +51 -0
  34. package/esm/session/sessionInCookie.js.map +1 -0
  35. package/esm/session/sessionInLocalStorage.js +37 -0
  36. package/esm/session/sessionInLocalStorage.js.map +1 -0
  37. package/esm/session/sessionManagement.js +35 -28
  38. package/esm/session/sessionManagement.js.map +1 -1
  39. package/esm/session/sessionState.js +59 -0
  40. package/esm/session/sessionState.js.map +1 -0
  41. package/esm/session/sessionStore.js +113 -90
  42. package/esm/session/sessionStore.js.map +1 -1
  43. package/esm/session/sessionStoreOperations.js +108 -0
  44. package/esm/session/sessionStoreOperations.js.map +1 -0
  45. package/package.json +2 -2
  46. package/src/browser/cookie.js +23 -11
  47. package/src/configuration/configuration.js +8 -32
  48. package/src/index.js +9 -4
  49. package/src/init.js +0 -19
  50. package/src/session/sessionConstants.js +1 -0
  51. package/src/session/sessionInCookie.js +87 -0
  52. package/src/session/sessionInLocalStorage.js +45 -0
  53. package/src/session/sessionManagement.js +48 -36
  54. package/src/session/sessionState.js +72 -0
  55. package/src/session/sessionStore.js +163 -108
  56. package/src/session/sessionStoreOperations.js +134 -0
  57. package/types/index.d.ts +4 -0
  58. package/cjs/session/sessionCookieStore.js +0 -156
  59. package/cjs/session/sessionCookieStore.js.map +0 -1
  60. package/cjs/synthetics/usr.js +0 -26
  61. package/cjs/synthetics/usr.js.map +0 -1
  62. package/esm/session/sessionCookieStore.js +0 -142
  63. package/esm/session/sessionCookieStore.js.map +0 -1
  64. package/esm/synthetics/usr.js +0 -17
  65. package/esm/synthetics/usr.js.map +0 -1
  66. package/src/session/sessionCookieStore.js +0 -169
  67. package/src/synthetics/usr.js +0 -18
@@ -1,170 +1,225 @@
1
- import { COOKIE_ACCESS_DELAY } from '../browser/cookie'
1
+ import { clearInterval, setInterval } from '../helper/timer'
2
2
  import { Observable } from '../helper/observable'
3
- import { dateNow, UUID, throttle, ONE_SECOND } from '../helper/tools'
4
- import { SESSION_TIME_OUT_DELAY } from './sessionConstants'
3
+ import { ONE_SECOND, dateNow, throttle, UUID, assign } from '../helper/tools'
4
+ import { selectCookieStrategy, initCookieStrategy } from './sessionInCookie'
5
5
  import {
6
- retrieveSession,
7
- withCookieLockAccess,
8
- clearSession
9
- } from './sessionCookieStore'
10
- import { clearInterval, setInterval } from '../helper/timer'
6
+ getExpiredSessionState,
7
+ isSessionInExpiredState,
8
+ isSessionInNotStartedState,
9
+ isSessionStarted
10
+ } from './sessionState'
11
+ import {
12
+ initLocalStorageStrategy,
13
+ selectLocalStorageStrategy
14
+ } from './sessionInLocalStorage'
15
+ import { processSessionStoreOperations } from './sessionStoreOperations'
16
+
17
+ /**
18
+ * Every second, the storage will be polled to check for any change that can occur
19
+ * to the session state in another browser tab, or another window.
20
+ * This value has been determined from our previous cookie-only implementation.
21
+ */
22
+ export const STORAGE_POLL_DELAY = ONE_SECOND
23
+
24
+ /**
25
+ * Checks if cookies are available as the preferred storage
26
+ * Else, checks if LocalStorage is allowed and available
27
+ */
28
+ export function selectSessionStoreStrategyType(initConfiguration) {
29
+ let sessionStoreStrategyType = selectCookieStrategy(initConfiguration)
30
+ if (
31
+ !sessionStoreStrategyType &&
32
+ initConfiguration.allowFallbackToLocalStorage
33
+ ) {
34
+ sessionStoreStrategyType = selectLocalStorageStrategy()
35
+ }
36
+ return sessionStoreStrategyType
37
+ }
11
38
 
12
- export var STORAGE_POLL_DELAY = ONE_SECOND
13
39
  /**
14
40
  * Different session concepts:
15
41
  * - tracked, the session has an id and is updated along the user navigation
16
42
  * - not tracked, the session does not have an id but it is updated along the user navigation
17
43
  * - inactive, no session in store or session expired, waiting for a renew session
18
44
  */
19
- export function startSessionStore(options, productKey, computeSessionState) {
20
- var renewObservable = new Observable()
21
- var expireObservable = new Observable()
22
-
23
- var watchSessionTimeoutId = setInterval(watchSession, STORAGE_POLL_DELAY)
24
- var sessionCache = retrieveActiveSession()
25
- var _throttleExpandOrRenewSession = throttle(function () {
26
- var isTracked
27
- withCookieLockAccess({
28
- options: options,
29
- process: function (cookieSession) {
30
- var synchronizedSession = synchronizeSession(cookieSession)
31
- isTracked = expandOrRenewCookie(synchronizedSession)
32
- return synchronizedSession
33
- },
34
- after: function (cookieSession) {
35
- if (isTracked && !hasSessionInCache()) {
36
- renewSession(cookieSession)
45
+ export function startSessionStore(
46
+ sessionStoreStrategyType,
47
+ productKey,
48
+ computeSessionState
49
+ ) {
50
+ const renewObservable = new Observable()
51
+ const expireObservable = new Observable()
52
+ const sessionStateUpdateObservable = new Observable()
53
+ const sessionStoreStrategy =
54
+ sessionStoreStrategyType.type === 'Cookie'
55
+ ? initCookieStrategy(sessionStoreStrategyType.cookieOptions)
56
+ : initLocalStorageStrategy()
57
+ const { expireSession } = sessionStoreStrategy
58
+
59
+ const watchSessionTimeoutId = setInterval(watchSession, STORAGE_POLL_DELAY)
60
+ let sessionCache
61
+
62
+ startSession()
63
+
64
+ const {
65
+ throttled: throttledExpandOrRenewSession,
66
+ cancel: cancelExpandOrRenewSession
67
+ } = throttle(function () {
68
+ processSessionStoreOperations(
69
+ {
70
+ process: function (sessionState) {
71
+ if (isSessionInNotStartedState(sessionState)) {
72
+ return
73
+ }
74
+
75
+ const synchronizedSession = synchronizeSession(sessionState)
76
+ expandOrRenewSessionState(synchronizedSession)
77
+ return synchronizedSession
78
+ },
79
+ after: function (sessionState) {
80
+ if (isSessionStarted(sessionState) && !hasSessionInCache()) {
81
+ renewSessionInCache(sessionState)
82
+ }
83
+ sessionCache = sessionState
37
84
  }
38
- sessionCache = cookieSession
39
- }
40
- })
85
+ },
86
+ sessionStoreStrategy
87
+ )
41
88
  }, STORAGE_POLL_DELAY)
42
- var throttledExpandOrRenewSession = _throttleExpandOrRenewSession.throttled
43
- var cancelExpandOrRenewSession = _throttleExpandOrRenewSession.cancel
44
- // function expandOrRenewSession() {
45
- // var isTracked
46
- // withCookieLockAccess({
47
- // options: options,
48
- // process: function (cookieSession) {
49
- // var synchronizedSession = synchronizeSession(cookieSession)
50
- // isTracked = expandOrRenewCookie(synchronizedSession)
51
- // return synchronizedSession
52
- // },
53
- // after: function (cookieSession) {
54
- // if (isTracked && !hasSessionInCache()) {
55
- // renewSession(cookieSession)
56
- // }
57
- // sessionCache = cookieSession
58
- // }
59
- // })
60
- // }
61
89
 
62
90
  function expandSession() {
63
- withCookieLockAccess({
64
- options: options,
65
- process: function (cookieSession) {
66
- return hasSessionInCache()
67
- ? synchronizeSession(cookieSession)
68
- : undefined
69
- }
70
- })
91
+ processSessionStoreOperations(
92
+ {
93
+ process: function (sessionState) {
94
+ return hasSessionInCache()
95
+ ? synchronizeSession(sessionState)
96
+ : undefined
97
+ }
98
+ },
99
+ sessionStoreStrategy
100
+ )
71
101
  }
72
102
 
73
103
  /**
74
104
  * allows two behaviors:
75
- * - if the session is active, synchronize the session cache without updating the session cookie
76
- * - if the session is not active, clear the session cookie and expire the session cache
105
+ * - if the session is active, synchronize the session cache without updating the session store
106
+ * - if the session is not active, clear the session store and expire the session cache
77
107
  */
78
108
  function watchSession() {
79
- withCookieLockAccess({
80
- options: options,
81
- process: function (cookieSession) {
82
- return !isActiveSession(cookieSession) ? {} : undefined
109
+ processSessionStoreOperations(
110
+ {
111
+ process: function (sessionState) {
112
+ return isSessionInExpiredState(sessionState)
113
+ ? getExpiredSessionState()
114
+ : undefined
115
+ },
116
+ after: synchronizeSession
83
117
  },
84
- after: synchronizeSession
85
- })
118
+ sessionStoreStrategy
119
+ )
86
120
  }
87
121
 
88
- function synchronizeSession(cookieSession) {
89
- if (!isActiveSession(cookieSession)) {
90
- cookieSession = {}
122
+ function synchronizeSession(sessionState) {
123
+ if (isSessionInExpiredState(sessionState)) {
124
+ sessionState = getExpiredSessionState()
91
125
  }
92
126
  if (hasSessionInCache()) {
93
- if (isSessionInCacheOutdated(cookieSession)) {
127
+ if (isSessionInCacheOutdated(sessionState)) {
94
128
  expireSessionInCache()
95
129
  } else {
96
- sessionCache = cookieSession
130
+ sessionStateUpdateObservable.notify({
131
+ previousState: sessionCache,
132
+ newState: sessionState
133
+ })
134
+ sessionCache = sessionState
97
135
  }
98
136
  }
99
- return cookieSession
137
+ return sessionState
138
+ }
139
+
140
+ function startSession() {
141
+ processSessionStoreOperations(
142
+ {
143
+ process: function (sessionState) {
144
+ if (isSessionInNotStartedState(sessionState)) {
145
+ return getExpiredSessionState()
146
+ }
147
+ },
148
+ after: function (sessionState) {
149
+ sessionCache = sessionState
150
+ }
151
+ },
152
+ sessionStoreStrategy
153
+ )
100
154
  }
101
155
 
102
- function expandOrRenewCookie(cookieSession) {
103
- var sessionState = computeSessionState(cookieSession[productKey])
104
- var trackingType = sessionState.trackingType
105
- var isTracked = sessionState.isTracked
106
- cookieSession[productKey] = trackingType
107
- if (isTracked && !cookieSession.id) {
108
- cookieSession.id = UUID()
109
- cookieSession.created = String(dateNow())
156
+ function expandOrRenewSessionState(sessionState) {
157
+ if (isSessionInNotStartedState(sessionState)) {
158
+ return false
159
+ }
160
+
161
+ const { trackingType, isTracked } = computeSessionState(
162
+ sessionState[productKey]
163
+ )
164
+ sessionState[productKey] = trackingType
165
+ delete sessionState.isExpired
166
+ if (isTracked && !sessionState.id) {
167
+ sessionState.id = UUID()
168
+ sessionState.created = String(dateNow())
110
169
  }
111
- return isTracked
112
170
  }
113
171
 
114
172
  function hasSessionInCache() {
115
173
  return sessionCache[productKey] !== undefined
116
174
  }
117
175
 
118
- function isSessionInCacheOutdated(cookieSession) {
176
+ function isSessionInCacheOutdated(sessionState) {
119
177
  return (
120
- sessionCache.id !== cookieSession.id ||
121
- sessionCache[productKey] !== cookieSession[productKey]
178
+ sessionCache.id !== sessionState.id ||
179
+ sessionCache[productKey] !== sessionState[productKey]
122
180
  )
123
181
  }
124
182
 
125
183
  function expireSessionInCache() {
126
- sessionCache = {}
184
+ sessionCache = getExpiredSessionState()
127
185
  expireObservable.notify()
128
186
  }
129
187
 
130
- function renewSession(cookieSession) {
131
- sessionCache = cookieSession
188
+ function renewSessionInCache(sessionState) {
189
+ sessionCache = sessionState
132
190
  renewObservable.notify()
133
191
  }
134
192
 
135
- function retrieveActiveSession() {
136
- var session = retrieveSession()
137
- if (isActiveSession(session)) {
138
- return session
139
- }
140
- return {}
141
- }
142
-
143
- function isActiveSession(session) {
144
- // created and expire can be undefined for versions which was not storing them
145
- // these checks could be removed when older versions will not be available/live anymore
146
- return (
147
- (session.created === undefined ||
148
- dateNow() - Number(session.created) < SESSION_TIME_OUT_DELAY) &&
149
- (session.expire === undefined || dateNow() < Number(session.expire))
193
+ function updateSessionState(partialSessionState) {
194
+ processSessionStoreOperations(
195
+ {
196
+ process: function (sessionState) {
197
+ return assign({}, sessionState, partialSessionState)
198
+ },
199
+ after: synchronizeSession
200
+ },
201
+ sessionStoreStrategy
150
202
  )
151
203
  }
152
204
 
153
205
  return {
154
206
  expandOrRenewSession: throttledExpandOrRenewSession,
155
- expandSession: expandSession,
207
+ expandSession,
156
208
  getSession: function () {
157
- return sessionCache
209
+ return sessionCache || {}
158
210
  },
159
- renewObservable: renewObservable,
160
- expireObservable: expireObservable,
211
+ renewObservable,
212
+ expireObservable,
213
+ sessionStateUpdateObservable,
214
+ restartSession: startSession,
161
215
  expire: function () {
162
216
  cancelExpandOrRenewSession()
163
- clearSession(options)
164
- synchronizeSession({})
217
+ expireSession()
218
+ synchronizeSession(getExpiredSessionState())
165
219
  },
166
220
  stop: function () {
167
221
  clearInterval(watchSessionTimeoutId)
168
- }
222
+ },
223
+ updateSessionState
169
224
  }
170
225
  }
@@ -0,0 +1,134 @@
1
+ import { setTimeout } from '../helper/timer'
2
+ import { UUID, assign } from '../helper/tools'
3
+ import {
4
+ expandSessionState,
5
+ isSessionInExpiredState,
6
+ isSessionInNotStartedState
7
+ } from './sessionState'
8
+
9
+ export const LOCK_RETRY_DELAY = 10
10
+ export const LOCK_MAX_TRIES = 100
11
+ const bufferedOperations = []
12
+ let ongoingOperations
13
+
14
+ export function processSessionStoreOperations(
15
+ operations,
16
+ sessionStoreStrategy,
17
+ numberOfRetries = 0
18
+ ) {
19
+ const { isLockEnabled, persistSession, expireSession } = sessionStoreStrategy
20
+ const persistWithLock = function (session) {
21
+ return persistSession(assign({}, session, { lock: currentLock }))
22
+ }
23
+ const retrieveStore = function () {
24
+ const session = sessionStoreStrategy.retrieveSession()
25
+ const lock = session.lock
26
+ if (session.lock) {
27
+ delete session.lock
28
+ }
29
+
30
+ return {
31
+ session,
32
+ lock
33
+ }
34
+ }
35
+
36
+ if (!ongoingOperations) {
37
+ ongoingOperations = operations
38
+ }
39
+ if (operations !== ongoingOperations) {
40
+ bufferedOperations.push(operations)
41
+ return
42
+ }
43
+ if (isLockEnabled && numberOfRetries >= LOCK_MAX_TRIES) {
44
+ next(sessionStoreStrategy)
45
+ return
46
+ }
47
+ let currentLock
48
+ let currentStore = retrieveStore()
49
+ if (isLockEnabled) {
50
+ // if someone has lock, retry later
51
+ if (
52
+ currentStore.lock &&
53
+ !isSessionInNotStartedState(currentStore.session)
54
+ ) {
55
+ retryLater(operations, sessionStoreStrategy, numberOfRetries)
56
+ return
57
+ }
58
+ // acquire lock
59
+ currentLock = UUID()
60
+ persistWithLock(currentStore.session)
61
+ // if lock is not acquired, retry later
62
+ currentStore = retrieveStore()
63
+ if (
64
+ currentStore.lock !== currentLock &&
65
+ !isSessionInNotStartedState(currentStore.session)
66
+ ) {
67
+ retryLater(operations, sessionStoreStrategy, numberOfRetries)
68
+ return
69
+ }
70
+ }
71
+ let processedSession = operations.process(currentStore.session)
72
+ if (isLockEnabled) {
73
+ // if lock corrupted after process, retry later
74
+ currentStore = retrieveStore()
75
+ if (
76
+ currentStore.lock !== currentLock &&
77
+ !isSessionInNotStartedState(currentStore.session)
78
+ ) {
79
+ retryLater(operations, sessionStoreStrategy, numberOfRetries)
80
+ return
81
+ }
82
+ }
83
+ if (processedSession) {
84
+ if (isSessionInExpiredState(processedSession)) {
85
+ expireSession()
86
+ } else {
87
+ expandSessionState(processedSession)
88
+ isLockEnabled
89
+ ? persistWithLock(processedSession)
90
+ : persistSession(processedSession)
91
+ }
92
+ }
93
+ if (isLockEnabled) {
94
+ // correctly handle lock around expiration would require to handle this case properly at several levels
95
+ // since we don't have evidence of lock issues around expiration, let's just not do the corruption check for it
96
+ if (!(processedSession && isSessionInExpiredState(processedSession))) {
97
+ // if lock corrupted after persist, retry later
98
+ currentStore = retrieveStore()
99
+ if (
100
+ currentStore.lock !== currentLock &&
101
+ !isSessionInNotStartedState(currentStore.session)
102
+ ) {
103
+ retryLater(operations, sessionStoreStrategy, numberOfRetries)
104
+ return
105
+ }
106
+ persistSession(currentStore.session)
107
+ processedSession = currentStore.session
108
+ }
109
+ }
110
+ // call after even if session is not persisted in order to perform operations on
111
+ // up-to-date session state value => the value could have been modified by another tab
112
+ if (operations.after) {
113
+ operations.after(processedSession || currentStore.session)
114
+ }
115
+ next(sessionStoreStrategy)
116
+ }
117
+
118
+ function retryLater(operations, sessionStore, currentNumberOfRetries) {
119
+ setTimeout(function () {
120
+ processSessionStoreOperations(
121
+ operations,
122
+ sessionStore,
123
+ currentNumberOfRetries + 1
124
+ )
125
+ }, LOCK_RETRY_DELAY)
126
+ }
127
+
128
+ function next(sessionStore) {
129
+ ongoingOperations = undefined
130
+ const nextOperations = bufferedOperations.shift()
131
+ if (nextOperations) {
132
+ processSessionStoreOperations(nextOperations, sessionStore)
133
+ }
134
+ }
package/types/index.d.ts CHANGED
@@ -87,6 +87,10 @@ export interface InitConfiguration {
87
87
  * 数据以 application/json 的发送方式,默认text
88
88
  */
89
89
  sendContentTypeByJson?: boolean | undefined
90
+ /**
91
+ * 在 cookie 不可用的情况下,可以开启该选项,把数据储存到 localstorage
92
+ */
93
+ allowFallbackToLocalStorage?: boolean | undefined
90
94
  }
91
95
  export enum TraceType {
92
96
  DDTRACE = 'ddtrace',
@@ -1,156 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.SESSION_COOKIE_NAME = exports.MAX_NUMBER_OF_LOCK_RETRIES = exports.LOCK_RETRY_DELAY = void 0;
7
- exports.clearSession = clearSession;
8
- exports.persistSession = persistSession;
9
- exports.retrieveSession = retrieveSession;
10
- exports.toSessionString = toSessionString;
11
- exports.withCookieLockAccess = withCookieLockAccess;
12
- var _cookie = require("../browser/cookie");
13
- var _tools = require("../helper/tools");
14
- var _sessionConstants = require("./sessionConstants");
15
- var _timer = require("../helper/timer");
16
- var SESSION_ENTRY_REGEXP = /^([a-z]+)=([a-z0-9-]+)$/;
17
- var SESSION_ENTRY_SEPARATOR = '&';
18
- var SESSION_COOKIE_NAME = '_dataflux_s';
19
-
20
- // arbitrary values
21
- exports.SESSION_COOKIE_NAME = SESSION_COOKIE_NAME;
22
- var LOCK_RETRY_DELAY = 10;
23
- exports.LOCK_RETRY_DELAY = LOCK_RETRY_DELAY;
24
- var MAX_NUMBER_OF_LOCK_RETRIES = 100;
25
- exports.MAX_NUMBER_OF_LOCK_RETRIES = MAX_NUMBER_OF_LOCK_RETRIES;
26
- var bufferedOperations = [];
27
- var ongoingOperations;
28
- function withCookieLockAccess(operations, numberOfRetries) {
29
- if (typeof numberOfRetries === 'undefined') {
30
- numberOfRetries = 0;
31
- }
32
- if (!ongoingOperations) {
33
- ongoingOperations = operations;
34
- }
35
- if (operations !== ongoingOperations) {
36
- bufferedOperations.push(operations);
37
- return;
38
- }
39
- if (numberOfRetries >= MAX_NUMBER_OF_LOCK_RETRIES) {
40
- next();
41
- return;
42
- }
43
- var currentLock;
44
- var currentSession = retrieveSession();
45
- if (isCookieLockEnabled()) {
46
- // if someone has lock, retry later
47
- if (currentSession.lock) {
48
- retryLater(operations, numberOfRetries);
49
- return;
50
- }
51
- // acquire lock
52
- currentLock = (0, _tools.UUID)();
53
- currentSession.lock = currentLock;
54
- setSession(currentSession, operations.options);
55
- // if lock is not acquired, retry later
56
- currentSession = retrieveSession();
57
- if (currentSession.lock !== currentLock) {
58
- retryLater(operations, numberOfRetries);
59
- return;
60
- }
61
- }
62
- var processedSession = operations.process(currentSession);
63
- if (isCookieLockEnabled()) {
64
- // if lock corrupted after process, retry later
65
- currentSession = retrieveSession();
66
- if (currentSession.lock !== currentLock) {
67
- retryLater(operations, numberOfRetries);
68
- return;
69
- }
70
- }
71
- if (processedSession) {
72
- persistSession(processedSession, operations.options);
73
- }
74
- if (isCookieLockEnabled()) {
75
- // correctly handle lock around expiration would require to handle this case properly at several levels
76
- // since we don't have evidence of lock issues around expiration, let's just not do the corruption check for it
77
- if (!(processedSession && isExpiredState(processedSession))) {
78
- // if lock corrupted after persist, retry later
79
- currentSession = retrieveSession();
80
- if (currentSession.lock !== currentLock) {
81
- retryLater(operations, numberOfRetries);
82
- return;
83
- }
84
- delete currentSession.lock;
85
- setSession(currentSession, operations.options);
86
- processedSession = currentSession;
87
- }
88
- }
89
- // call after even if session is not persisted in order to perform operations on
90
- // up-to-date cookie value, the value could have been modified by another tab
91
- if (operations.after) {
92
- operations.after(processedSession || currentSession);
93
- }
94
- next();
95
- }
96
-
97
- /**
98
- * Cookie lock strategy allows mitigating issues due to concurrent access to cookie.
99
- * This issue concerns only chromium browsers and enabling this on firefox increase cookie write failures.
100
- */
101
- function isCookieLockEnabled() {
102
- return (0, _tools.isChromium)();
103
- }
104
- function retryLater(operations, currentNumberOfRetries) {
105
- (0, _timer.setTimeout)(function () {
106
- withCookieLockAccess(operations, currentNumberOfRetries + 1);
107
- }, LOCK_RETRY_DELAY);
108
- }
109
- function next() {
110
- ongoingOperations = undefined;
111
- var nextOperations = bufferedOperations.shift();
112
- if (nextOperations) {
113
- withCookieLockAccess(nextOperations);
114
- }
115
- }
116
- function persistSession(session, options) {
117
- if (isExpiredState(session)) {
118
- clearSession(options);
119
- return;
120
- }
121
- session.expire = String((0, _tools.dateNow)() + _sessionConstants.SESSION_EXPIRATION_DELAY);
122
- setSession(session, options);
123
- }
124
- function setSession(session, options) {
125
- (0, _cookie.setCookie)(SESSION_COOKIE_NAME, toSessionString(session), _sessionConstants.SESSION_EXPIRATION_DELAY, options);
126
- }
127
- function toSessionString(session) {
128
- return (0, _tools.map)((0, _tools.objectEntries)(session), function (item) {
129
- return item[0] + '=' + item[1];
130
- }).join(SESSION_ENTRY_SEPARATOR);
131
- }
132
- function retrieveSession() {
133
- var sessionString = (0, _cookie.getCookie)(SESSION_COOKIE_NAME);
134
- var session = {};
135
- if (isValidSessionString(sessionString)) {
136
- (0, _tools.each)(sessionString.split(SESSION_ENTRY_SEPARATOR), function (entry) {
137
- var matches = SESSION_ENTRY_REGEXP.exec(entry);
138
- if (matches !== null) {
139
- var key = matches[1];
140
- var value = matches[2];
141
- session[key] = value;
142
- }
143
- });
144
- }
145
- return session;
146
- }
147
- function isValidSessionString(sessionString) {
148
- return sessionString !== undefined && (sessionString.indexOf(SESSION_ENTRY_SEPARATOR) !== -1 || SESSION_ENTRY_REGEXP.test(sessionString));
149
- }
150
- function isExpiredState(session) {
151
- return (0, _tools.isEmptyObject)(session);
152
- }
153
- function clearSession(options) {
154
- (0, _cookie.setCookie)(SESSION_COOKIE_NAME, '', 0, options);
155
- }
156
- //# sourceMappingURL=sessionCookieStore.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sessionCookieStore.js","names":["_cookie","require","_tools","_sessionConstants","_timer","SESSION_ENTRY_REGEXP","SESSION_ENTRY_SEPARATOR","SESSION_COOKIE_NAME","exports","LOCK_RETRY_DELAY","MAX_NUMBER_OF_LOCK_RETRIES","bufferedOperations","ongoingOperations","withCookieLockAccess","operations","numberOfRetries","push","next","currentLock","currentSession","retrieveSession","isCookieLockEnabled","lock","retryLater","UUID","setSession","options","processedSession","process","persistSession","isExpiredState","after","isChromium","currentNumberOfRetries","setTimeout","undefined","nextOperations","shift","session","clearSession","expire","String","dateNow","SESSION_EXPIRATION_DELAY","setCookie","toSessionString","map","objectEntries","item","join","sessionString","getCookie","isValidSessionString","each","split","entry","matches","exec","key","value","indexOf","test","isEmptyObject"],"sources":["../../src/session/sessionCookieStore.js"],"sourcesContent":["import { getCookie, setCookie } from '../browser/cookie'\nimport {\n isChromium,\n dateNow,\n isEmptyObject,\n UUID,\n objectEntries,\n map,\n each\n} from '../helper/tools'\nimport { SESSION_EXPIRATION_DELAY } from './sessionConstants'\nimport { setTimeout } from '../helper/timer'\nvar SESSION_ENTRY_REGEXP = /^([a-z]+)=([a-z0-9-]+)$/\nvar SESSION_ENTRY_SEPARATOR = '&'\n\nexport var SESSION_COOKIE_NAME = '_dataflux_s'\n\n// arbitrary values\nexport var LOCK_RETRY_DELAY = 10\nexport var MAX_NUMBER_OF_LOCK_RETRIES = 100\n\nvar bufferedOperations = []\nvar ongoingOperations\n\nexport function withCookieLockAccess(operations, numberOfRetries) {\n if (typeof numberOfRetries === 'undefined') {\n numberOfRetries = 0\n }\n if (!ongoingOperations) {\n ongoingOperations = operations\n }\n if (operations !== ongoingOperations) {\n bufferedOperations.push(operations)\n return\n }\n if (numberOfRetries >= MAX_NUMBER_OF_LOCK_RETRIES) {\n next()\n return\n }\n var currentLock\n var currentSession = retrieveSession()\n if (isCookieLockEnabled()) {\n // if someone has lock, retry later\n if (currentSession.lock) {\n retryLater(operations, numberOfRetries)\n return\n }\n // acquire lock\n currentLock = UUID()\n currentSession.lock = currentLock\n setSession(currentSession, operations.options)\n // if lock is not acquired, retry later\n currentSession = retrieveSession()\n if (currentSession.lock !== currentLock) {\n retryLater(operations, numberOfRetries)\n return\n }\n }\n var processedSession = operations.process(currentSession)\n if (isCookieLockEnabled()) {\n // if lock corrupted after process, retry later\n currentSession = retrieveSession()\n if (currentSession.lock !== currentLock) {\n retryLater(operations, numberOfRetries)\n return\n }\n }\n if (processedSession) {\n persistSession(processedSession, operations.options)\n }\n if (isCookieLockEnabled()) {\n // correctly handle lock around expiration would require to handle this case properly at several levels\n // since we don't have evidence of lock issues around expiration, let's just not do the corruption check for it\n if (!(processedSession && isExpiredState(processedSession))) {\n // if lock corrupted after persist, retry later\n currentSession = retrieveSession()\n if (currentSession.lock !== currentLock) {\n retryLater(operations, numberOfRetries)\n return\n }\n delete currentSession.lock\n setSession(currentSession, operations.options)\n processedSession = currentSession\n }\n }\n // call after even if session is not persisted in order to perform operations on\n // up-to-date cookie value, the value could have been modified by another tab\n if (operations.after) {\n operations.after(processedSession || currentSession)\n }\n next()\n}\n\n/**\n * Cookie lock strategy allows mitigating issues due to concurrent access to cookie.\n * This issue concerns only chromium browsers and enabling this on firefox increase cookie write failures.\n */\nfunction isCookieLockEnabled() {\n return isChromium()\n}\n\nfunction retryLater(operations, currentNumberOfRetries) {\n setTimeout(function () {\n withCookieLockAccess(operations, currentNumberOfRetries + 1)\n }, LOCK_RETRY_DELAY)\n}\n\nfunction next() {\n ongoingOperations = undefined\n var nextOperations = bufferedOperations.shift()\n if (nextOperations) {\n withCookieLockAccess(nextOperations)\n }\n}\n\nexport function persistSession(session, options) {\n if (isExpiredState(session)) {\n clearSession(options)\n return\n }\n session.expire = String(dateNow() + SESSION_EXPIRATION_DELAY)\n setSession(session, options)\n}\n\nfunction setSession(session, options) {\n setCookie(\n SESSION_COOKIE_NAME,\n toSessionString(session),\n SESSION_EXPIRATION_DELAY,\n options\n )\n}\n\nexport function toSessionString(session) {\n return map(objectEntries(session), function (item) {\n return item[0] + '=' + item[1]\n }).join(SESSION_ENTRY_SEPARATOR)\n}\n\nexport function retrieveSession() {\n var sessionString = getCookie(SESSION_COOKIE_NAME)\n var session = {}\n if (isValidSessionString(sessionString)) {\n each(sessionString.split(SESSION_ENTRY_SEPARATOR), function (entry) {\n var matches = SESSION_ENTRY_REGEXP.exec(entry)\n if (matches !== null) {\n var key = matches[1]\n var value = matches[2]\n session[key] = value\n }\n })\n }\n return session\n}\n\nfunction isValidSessionString(sessionString) {\n return (\n sessionString !== undefined &&\n (sessionString.indexOf(SESSION_ENTRY_SEPARATOR) !== -1 ||\n SESSION_ENTRY_REGEXP.test(sessionString))\n )\n}\n\nfunction isExpiredState(session) {\n return isEmptyObject(session)\n}\nexport function clearSession(options) {\n setCookie(SESSION_COOKIE_NAME, '', 0, options)\n}\n"],"mappings":"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","ignoreList":[]}