@cloudcare/browser-core 1.1.3 → 1.2.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 (134) hide show
  1. package/cjs/{cookie.js → browser/cookie.js} +6 -37
  2. package/cjs/browser/fetchObservable.js +91 -0
  3. package/cjs/browser/xhrObservable.js +118 -0
  4. package/cjs/configuration/configuration.js +70 -0
  5. package/cjs/configuration/transportConfiguration.js +64 -0
  6. package/cjs/console/consoleObservable.js +84 -0
  7. package/cjs/dataMap.js +26 -21
  8. package/cjs/error/trackRuntimeError.js +27 -0
  9. package/cjs/helper/catchUserErrors.js +20 -0
  10. package/cjs/helper/contextHistory.js +134 -0
  11. package/cjs/helper/createEventRateLimiter.js +47 -0
  12. package/cjs/helper/deviceInfo.js +8 -25
  13. package/cjs/helper/display.js +31 -0
  14. package/cjs/helper/enums.js +28 -2
  15. package/cjs/helper/errorTools.js +63 -2
  16. package/cjs/helper/instrumentMethod.js +93 -0
  17. package/cjs/helper/lifeCycle.js +5 -3
  18. package/cjs/helper/observable.js +40 -2
  19. package/cjs/helper/tools.js +185 -9
  20. package/cjs/index.js +153 -23
  21. package/cjs/init.js +17 -27
  22. package/cjs/report/reportObservable.js +112 -0
  23. package/cjs/session/sessionConstants.js +13 -0
  24. package/cjs/session/sessionCookieStore.js +188 -0
  25. package/cjs/session/sessionManagement.js +96 -0
  26. package/cjs/session/sessionStore.js +150 -0
  27. package/cjs/synthetics/syntheticsWorkerValues.js +32 -0
  28. package/cjs/synthetics/usr.js +32 -0
  29. package/cjs/tracekit/computeStackTrace.js +73 -563
  30. package/cjs/tracekit/index.js +3 -15
  31. package/cjs/tracekit/tracekit.js +113 -0
  32. package/cjs/transport/batch.js +332 -0
  33. package/cjs/transport/httpRequest.js +112 -0
  34. package/cjs/transport/index.js +29 -0
  35. package/cjs/transport/sendWithRetryStrategy.js +177 -0
  36. package/cjs/transport/startBatchWithReplica.js +24 -0
  37. package/esm/{cookie.js → browser/cookie.js} +4 -35
  38. package/esm/browser/fetchObservable.js +77 -0
  39. package/esm/browser/xhrObservable.js +106 -0
  40. package/esm/configuration/configuration.js +55 -0
  41. package/esm/configuration/transportConfiguration.js +54 -0
  42. package/esm/console/consoleObservable.js +70 -0
  43. package/esm/dataMap.js +26 -21
  44. package/esm/error/trackRuntimeError.js +16 -0
  45. package/esm/helper/catchUserErrors.js +12 -0
  46. package/esm/helper/contextHistory.js +106 -0
  47. package/esm/helper/createEventRateLimiter.js +38 -0
  48. package/esm/helper/deviceInfo.js +6 -25
  49. package/esm/helper/display.js +21 -0
  50. package/esm/helper/enums.js +25 -1
  51. package/esm/helper/errorTools.js +58 -3
  52. package/esm/helper/instrumentMethod.js +81 -0
  53. package/esm/helper/lifeCycle.js +5 -3
  54. package/esm/helper/observable.js +39 -3
  55. package/esm/helper/tools.js +147 -1
  56. package/esm/index.js +17 -7
  57. package/esm/init.js +17 -22
  58. package/esm/report/reportObservable.js +98 -0
  59. package/esm/session/sessionConstants.js +3 -0
  60. package/esm/session/sessionCookieStore.js +168 -0
  61. package/esm/session/sessionManagement.js +78 -0
  62. package/esm/session/sessionStore.js +139 -0
  63. package/esm/synthetics/syntheticsWorkerValues.js +15 -0
  64. package/esm/synthetics/usr.js +18 -0
  65. package/esm/tracekit/computeStackTrace.js +73 -557
  66. package/esm/tracekit/index.js +1 -1
  67. package/esm/tracekit/tracekit.js +103 -0
  68. package/esm/transport/batch.js +316 -0
  69. package/esm/transport/httpRequest.js +104 -0
  70. package/esm/transport/index.js +3 -0
  71. package/esm/transport/sendWithRetryStrategy.js +165 -0
  72. package/esm/transport/startBatchWithReplica.js +15 -0
  73. package/package.json +2 -2
  74. package/src/.DS_Store +0 -0
  75. package/src/{cookie.js → browser/cookie.js} +6 -34
  76. package/src/browser/fetchObservable.js +86 -0
  77. package/src/browser/xhrObservable.js +102 -0
  78. package/src/configuration/configuration.js +61 -0
  79. package/src/configuration/transportConfiguration.js +42 -0
  80. package/src/console/consoleObservable.js +65 -0
  81. package/src/dataMap.js +26 -21
  82. package/src/error/trackRuntimeError.js +19 -0
  83. package/src/helper/catchUserErrors.js +12 -0
  84. package/src/helper/contextHistory.js +85 -0
  85. package/src/helper/createEventRateLimiter.js +37 -0
  86. package/src/helper/deviceInfo.js +5 -51
  87. package/src/helper/display.js +21 -0
  88. package/src/helper/enums.js +38 -14
  89. package/src/helper/errorTools.js +76 -12
  90. package/src/helper/instrumentMethod.js +97 -0
  91. package/src/helper/lifeCycle.js +5 -3
  92. package/src/helper/observable.js +33 -2
  93. package/src/helper/tools.js +135 -4
  94. package/src/index.js +18 -7
  95. package/src/init.js +17 -18
  96. package/src/report/reportObservable.js +113 -0
  97. package/src/session/sessionConstants.js +3 -0
  98. package/src/session/sessionCookieStore.js +159 -0
  99. package/src/session/sessionManagement.js +89 -0
  100. package/src/session/sessionStore.js +139 -0
  101. package/src/synthetics/syntheticsWorkerValues.js +22 -0
  102. package/src/synthetics/usr.js +18 -0
  103. package/src/tracekit/computeStackTrace.js +75 -551
  104. package/src/tracekit/index.js +1 -1
  105. package/src/tracekit/tracekit.js +100 -0
  106. package/src/transport/batch.js +289 -0
  107. package/src/transport/httpRequest.js +109 -0
  108. package/src/transport/index.js +3 -0
  109. package/src/transport/sendWithRetryStrategy.js +186 -0
  110. package/src/transport/startBatchWithReplica.js +26 -0
  111. package/cjs/configuration.js +0 -193
  112. package/cjs/errorCollection.js +0 -167
  113. package/cjs/fetchProxy.js +0 -161
  114. package/cjs/helper/errorFilter.js +0 -47
  115. package/cjs/sessionManagement.js +0 -221
  116. package/cjs/tracekit/report.js +0 -289
  117. package/cjs/transport.js +0 -373
  118. package/cjs/xhrProxy.js +0 -122
  119. package/esm/configuration.js +0 -176
  120. package/esm/errorCollection.js +0 -141
  121. package/esm/fetchProxy.js +0 -115
  122. package/esm/helper/errorFilter.js +0 -38
  123. package/esm/sessionManagement.js +0 -195
  124. package/esm/tracekit/report.js +0 -273
  125. package/esm/transport.js +0 -357
  126. package/esm/xhrProxy.js +0 -110
  127. package/src/configuration.js +0 -161
  128. package/src/errorCollection.js +0 -170
  129. package/src/fetchProxy.js +0 -108
  130. package/src/helper/errorFilter.js +0 -38
  131. package/src/sessionManagement.js +0 -224
  132. package/src/tracekit/report.js +0 -284
  133. package/src/transport.js +0 -380
  134. package/src/xhrProxy.js +0 -106
@@ -196,6 +196,77 @@ export var map = function map(arr, fn, self) {
196
196
 
197
197
  return ret;
198
198
  };
199
+ export var some = function some(arr, fn, self) {
200
+ if (arr.some) {
201
+ return arr.some(fn);
202
+ }
203
+
204
+ var flag = false;
205
+
206
+ for (var i = 0; i < arr.length; i++) {
207
+ if (!hasOwnProperty.call(arr, i)) {
208
+ continue;
209
+ }
210
+
211
+ var val = arr[i];
212
+
213
+ if (fn.call(self, val, i, arr)) {
214
+ flag = true;
215
+ break;
216
+ }
217
+ }
218
+
219
+ return flag;
220
+ };
221
+ export var every = function every(arr, fn, self) {
222
+ if (arr.every) {
223
+ return arr.every(fn);
224
+ }
225
+
226
+ var flag = true;
227
+
228
+ for (var i = 0; i < arr.length; i++) {
229
+ if (!hasOwnProperty.call(arr, i)) {
230
+ continue;
231
+ }
232
+
233
+ var val = arr[i];
234
+
235
+ if (!fn.call(self, val, i, arr)) {
236
+ flag = false;
237
+ break;
238
+ }
239
+ }
240
+
241
+ return flag;
242
+ };
243
+ export var matchList = function matchList(list, value) {
244
+ return some(list, function (item) {
245
+ return item === value || item instanceof RegExp && item.test(value);
246
+ });
247
+ }; // https://github.com/jquery/jquery/blob/a684e6ba836f7c553968d7d026ed7941e1a612d8/src/selector/escapeSelector.js
248
+
249
+ export var cssEscape = function cssEscape(str) {
250
+ if (window.CSS && window.CSS.escape) {
251
+ return window.CSS.escape(str);
252
+ } // eslint-disable-next-line no-control-regex
253
+
254
+
255
+ return str.replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g, function (ch, asCodePoint) {
256
+ if (asCodePoint) {
257
+ // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
258
+ if (ch === '\0') {
259
+ return '\uFFFD';
260
+ } // Control characters and (dependent upon position) numbers get escaped as code points
261
+
262
+
263
+ return ch.slice(0, -1) + '\\' + ch.charCodeAt(ch.length - 1).toString(16) + ' ';
264
+ } // Other potentially-special ASCII characters get backslash-escaped
265
+
266
+
267
+ return '\\' + ch;
268
+ });
269
+ };
199
270
  export var inherit = function inherit(subclass, superclass) {
200
271
  var F = function F() {};
201
272
 
@@ -671,6 +742,18 @@ export var urlParse = function urlParse(para) {
671
742
 
672
743
  return new URLParser(para);
673
744
  };
745
+ export function elementMatches(element, selector) {
746
+ if (element.matches) {
747
+ return element.matches(selector);
748
+ } // IE11 support
749
+
750
+
751
+ if (element.msMatchesSelector) {
752
+ return element.msMatchesSelector(selector);
753
+ }
754
+
755
+ return false;
756
+ }
674
757
  export var addEvent = function addEvent() {
675
758
  function fixEvent(event) {
676
759
  if (event) {
@@ -1489,7 +1572,8 @@ export var ONE_MINUTE = 60 * ONE_SECOND;
1489
1572
  export var ONE_HOUR = 60 * ONE_MINUTE;
1490
1573
  export var ONE_DAY = 24 * ONE_HOUR;
1491
1574
  export var ONE_YEAR = 365 * ONE_DAY;
1492
- export var ONE_KILO_BYTE = 1024;
1575
+ export var ONE_KIBI_BYTE = 1024;
1576
+ export var ONE_MEBI_BYTE = 1024 * ONE_KIBI_BYTE;
1493
1577
  /**
1494
1578
  * Return true if the draw is successful
1495
1579
  * @param threshold between 0 and 100
@@ -1575,6 +1659,10 @@ export function relativeToClocks(relative) {
1575
1659
  timeStamp: getCorrectedTimeStamp(relative)
1576
1660
  };
1577
1661
  }
1662
+ export function currentDrift() {
1663
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
1664
+ return Math.round(dateNow() - (getNavigationStart() + performance.now()));
1665
+ }
1578
1666
 
1579
1667
  function getCorrectedTimeStamp(relativeTime) {
1580
1668
  var correctedOrigin = dateNow() - performance.now(); // apply correction only for positive drift
@@ -1694,6 +1782,21 @@ export function createContextManager() {
1694
1782
  } else {
1695
1783
  console.error('content 需要传递对象类型数据');
1696
1784
  }
1785
+ },
1786
+ getContext: function getContext() {
1787
+ return deepClone(context);
1788
+ },
1789
+ setContext: function setContext(newContext) {
1790
+ context = deepClone(newContext);
1791
+ },
1792
+ setContextProperty: function setContextProperty(key, property) {
1793
+ context[key] = deepClone(property);
1794
+ },
1795
+ removeContextProperty: function removeContextProperty(key) {
1796
+ delete context[key];
1797
+ },
1798
+ clearContext: function clearContext() {
1799
+ context = {};
1697
1800
  }
1698
1801
  };
1699
1802
  }
@@ -1708,12 +1811,48 @@ export function find(array, predicate) {
1708
1811
 
1709
1812
  return undefined;
1710
1813
  }
1814
+ export function arrayFrom(arrayLike) {
1815
+ if (Array.from) {
1816
+ return Array.from(arrayLike);
1817
+ }
1818
+
1819
+ var array = [];
1820
+
1821
+ if (arrayLike instanceof Set) {
1822
+ arrayLike.forEach(function (item) {
1823
+ array.push(item);
1824
+ });
1825
+ } else {
1826
+ for (var i = 0; i < arrayLike.length; i++) {
1827
+ array.push(arrayLike[i]);
1828
+ }
1829
+ }
1830
+
1831
+ return array;
1832
+ }
1833
+ export function findLast(array, predicate) {
1834
+ for (var i = array.length - 1; i >= 0; i -= 1) {
1835
+ var item = array[i];
1836
+
1837
+ if (predicate(item, i, array)) {
1838
+ return item;
1839
+ }
1840
+ }
1841
+
1842
+ return undefined;
1843
+ }
1711
1844
  export function isPercentage(value) {
1712
1845
  return isNumber(value) && value >= 0 && value <= 100;
1713
1846
  }
1714
1847
  export function getLocationOrigin() {
1715
1848
  return getLinkElementOrigin(window.location);
1716
1849
  }
1850
+ export function isIE() {
1851
+ return Boolean(document.documentMode);
1852
+ }
1853
+ export function isChromium() {
1854
+ return !!window.chrome || /HeadlessChrome/.test(window.navigator.userAgent);
1855
+ }
1717
1856
  /**
1718
1857
  * IE fallback
1719
1858
  * https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/origin
@@ -1782,4 +1921,11 @@ export function escapeRowField(value) {
1782
1921
  } else {
1783
1922
  return value;
1784
1923
  }
1924
+ }
1925
+ export function isNullUndefinedDefaultValue(data, defaultValue) {
1926
+ if (data !== null && data !== void 0) {
1927
+ return data;
1928
+ } else {
1929
+ return defaultValue;
1930
+ }
1785
1931
  }
package/esm/index.js CHANGED
@@ -1,22 +1,32 @@
1
1
  export * from './helper/boundedBuffer';
2
+ export * from './helper/contextHistory';
2
3
  export * from './helper/deviceInfo';
3
4
  export * from './helper/enums';
4
- export * from './helper/errorFilter';
5
+ export * from './helper/instrumentMethod';
5
6
  export * from './helper/errorTools';
7
+ export * from './error/trackRuntimeError';
8
+ export * from './console/consoleObservable';
9
+ export * from './report/reportObservable';
10
+ export * from './helper/display';
6
11
  export * from './helper/eventEmitter';
7
12
  export * from './helper/lifeCycle';
8
13
  export * from './helper/limitModification';
14
+ export * from './helper/createEventRateLimiter';
9
15
  export * from './helper/observable';
10
16
  export * from './helper/tools';
11
17
  export * from './helper/urlPolyfill';
12
18
  export * from './helper/mobileUtil';
13
19
  export * from './tracekit';
14
- export * from './configuration';
15
- export * from './cookie';
20
+ export * from './configuration/configuration';
21
+ export * from './configuration/transportConfiguration';
22
+ export * from './browser/cookie';
23
+ export * from './browser/fetchObservable';
24
+ export * from './browser/xhrObservable';
16
25
  export * from './dataMap';
17
- export * from './errorCollection';
18
- export * from './fetchProxy';
19
26
  export * from './init';
20
- export * from './sessionManagement';
27
+ export * from './session/sessionManagement';
28
+ export * from './session/sessionConstants';
29
+ export * from './session/sessionCookieStore';
30
+ export * from './session/sessionStore';
21
31
  export * from './transport';
22
- export * from './xhrProxy';
32
+ export * from './synthetics/syntheticsWorkerValues';
package/esm/init.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { extend, each } from './helper/tools';
2
- import { areCookiesAuthorized } from './cookie';
3
2
  export function makeGlobal(stub) {
4
3
  var global = extend({}, stub, {
5
4
  onReady: function onReady(callback) {
@@ -63,24 +62,20 @@ export function getGlobalObject() {
63
62
  }
64
63
 
65
64
  return globalObject;
66
- }
67
- export function checkCookiesAuthorized(options) {
68
- if (!areCookiesAuthorized(options)) {
69
- console.warn('Cookies are not authorized, we will not send any data.');
70
- return false;
71
- }
72
-
73
- return true;
74
- }
75
- export function checkIsNotLocalFile() {
76
- if (isLocalFile()) {
77
- console.error('Execution is not allowed in the current context.');
78
- return false;
79
- }
80
-
81
- return true;
82
- }
83
-
84
- function isLocalFile() {
85
- return window.location.protocol === 'file:';
86
- }
65
+ } // export function checkCookiesAuthorized(options) {
66
+ // if (!areCookiesAuthorized(options)) {
67
+ // console.warn('Cookies are not authorized, we will not send any data.')
68
+ // return false
69
+ // }
70
+ // return true
71
+ // }
72
+ // export function checkIsNotLocalFile() {
73
+ // if (isLocalFile()) {
74
+ // console.error('Execution is not allowed in the current context.')
75
+ // return false
76
+ // }
77
+ // return true
78
+ // }
79
+ // function isLocalFile() {
80
+ // return window.location.protocol === 'file:'
81
+ // }
@@ -0,0 +1,98 @@
1
+ import { toStackTraceString } from '../helper/errorTools';
2
+ import { mergeObservables, Observable } from '../helper/observable';
3
+ import { includes, addEventListener, safeTruncate, filter, each } from '../helper/tools';
4
+ import { DOM_EVENT } from '../helper/enums';
5
+ export var RawReportType = {
6
+ intervention: 'intervention',
7
+ deprecation: 'deprecation',
8
+ cspViolation: 'csp_violation'
9
+ };
10
+ export function initReportObservable(apis) {
11
+ var observables = [];
12
+
13
+ if (includes(apis, RawReportType.cspViolation)) {
14
+ observables.push(createCspViolationReportObservable());
15
+ }
16
+
17
+ var reportTypes = filter(apis, function (api) {
18
+ return api !== RawReportType.cspViolation;
19
+ });
20
+
21
+ if (reportTypes.length) {
22
+ observables.push(createReportObservable(reportTypes));
23
+ }
24
+
25
+ return mergeObservables.apply(this, observables);
26
+ }
27
+
28
+ function createReportObservable(reportTypes) {
29
+ var observable = new Observable(function () {
30
+ if (!window.ReportingObserver) {
31
+ return;
32
+ }
33
+
34
+ var handleReports = function handleReports(reports) {
35
+ each(reports, function (report) {
36
+ observable.notify(buildRawReportFromReport(report));
37
+ });
38
+ };
39
+
40
+ var observer = new window.ReportingObserver(handleReports, {
41
+ types: reportTypes,
42
+ buffered: true
43
+ });
44
+ observer.observe();
45
+ return function () {
46
+ observer.disconnect();
47
+ };
48
+ });
49
+ return observable;
50
+ }
51
+
52
+ function createCspViolationReportObservable() {
53
+ var observable = new Observable(function () {
54
+ var handleCspViolation = function handleCspViolation(event) {
55
+ observable.notify(buildRawReportFromCspViolation(event));
56
+ };
57
+
58
+ var _addEventListener = addEventListener(document, DOM_EVENT.SECURITY_POLICY_VIOLATION, handleCspViolation);
59
+
60
+ return _addEventListener.stop;
61
+ });
62
+ return observable;
63
+ }
64
+
65
+ function buildRawReportFromReport(report) {
66
+ var body = report.body;
67
+ var type = report.type;
68
+ return {
69
+ type: type,
70
+ subtype: body.id,
71
+ message: type + ': ' + body.message,
72
+ stack: buildStack(body.id, body.message, body.sourceFile, body.lineNumber, body.columnNumber)
73
+ };
74
+ }
75
+
76
+ function buildRawReportFromCspViolation(event) {
77
+ var type = RawReportType.cspViolation;
78
+ var message = '\'' + event.blockedURI + '\' blocked by \'' + event.effectiveDirective + '\' directive';
79
+ return {
80
+ type: RawReportType.cspViolation,
81
+ subtype: event.effectiveDirective,
82
+ message: type + ': ' + message,
83
+ stack: buildStack(event.effectiveDirective, message + ' of the policy "' + safeTruncate(event.originalPolicy, 100, '...') + '"', event.sourceFile, event.lineNumber, event.columnNumber)
84
+ };
85
+ }
86
+
87
+ function buildStack(name, message, sourceFile, lineNumber, columnNumber) {
88
+ return sourceFile && toStackTraceString({
89
+ name: name,
90
+ message: message,
91
+ stack: [{
92
+ func: '?',
93
+ url: sourceFile,
94
+ line: lineNumber,
95
+ column: columnNumber
96
+ }]
97
+ });
98
+ }
@@ -0,0 +1,3 @@
1
+ import { ONE_HOUR, ONE_MINUTE } from '../helper/tools';
2
+ export var SESSION_TIME_OUT_DELAY = 4 * ONE_HOUR;
3
+ export var SESSION_EXPIRATION_DELAY = 15 * ONE_MINUTE;
@@ -0,0 +1,168 @@
1
+ import { getCookie, setCookie } from '../browser/cookie';
2
+ import { isChromium, dateNow, isEmptyObject, UUID, objectEntries, map, each } from '../helper/tools';
3
+ import { SESSION_EXPIRATION_DELAY } from './sessionConstants';
4
+ var SESSION_ENTRY_REGEXP = /^([a-z]+)=([a-z0-9-]+)$/;
5
+ var SESSION_ENTRY_SEPARATOR = '&';
6
+ export var SESSION_COOKIE_NAME = '_dataflux_s'; // arbitrary values
7
+
8
+ export var LOCK_RETRY_DELAY = 10;
9
+ export var MAX_NUMBER_OF_LOCK_RETRIES = 100;
10
+ var bufferedOperations = [];
11
+ var ongoingOperations;
12
+ export function withCookieLockAccess(operations, numberOfRetries) {
13
+ if (typeof numberOfRetries === 'undefined') {
14
+ numberOfRetries = 0;
15
+ }
16
+
17
+ if (!ongoingOperations) {
18
+ ongoingOperations = operations;
19
+ }
20
+
21
+ if (operations !== ongoingOperations) {
22
+ bufferedOperations.push(operations);
23
+ return;
24
+ }
25
+
26
+ if (numberOfRetries >= MAX_NUMBER_OF_LOCK_RETRIES) {
27
+ next();
28
+ return;
29
+ }
30
+
31
+ var currentLock;
32
+ var currentSession = retrieveSession();
33
+
34
+ if (isCookieLockEnabled()) {
35
+ // if someone has lock, retry later
36
+ if (currentSession.lock) {
37
+ retryLater(operations, numberOfRetries);
38
+ return;
39
+ } // acquire lock
40
+
41
+
42
+ currentLock = UUID();
43
+ currentSession.lock = currentLock;
44
+ setSession(currentSession, operations.options); // if lock is not acquired, retry later
45
+
46
+ currentSession = retrieveSession();
47
+
48
+ if (currentSession.lock !== currentLock) {
49
+ retryLater(operations, numberOfRetries);
50
+ return;
51
+ }
52
+ }
53
+
54
+ var processedSession = operations.process(currentSession);
55
+
56
+ if (isCookieLockEnabled()) {
57
+ // if lock corrupted after process, retry later
58
+ currentSession = retrieveSession();
59
+
60
+ if (currentSession.lock !== currentLock) {
61
+ retryLater(operations, numberOfRetries);
62
+ return;
63
+ }
64
+ }
65
+
66
+ if (processedSession) {
67
+ persistSession(processedSession, operations.options);
68
+ }
69
+
70
+ if (isCookieLockEnabled()) {
71
+ // correctly handle lock around expiration would require to handle this case properly at several levels
72
+ // since we don't have evidence of lock issues around expiration, let's just not do the corruption check for it
73
+ if (!(processedSession && isExpiredState(processedSession))) {
74
+ // if lock corrupted after persist, retry later
75
+ currentSession = retrieveSession();
76
+
77
+ if (currentSession.lock !== currentLock) {
78
+ retryLater(operations, numberOfRetries);
79
+ return;
80
+ }
81
+
82
+ delete currentSession.lock;
83
+ setSession(currentSession, operations.options);
84
+ processedSession = currentSession;
85
+ }
86
+ } // call after even if session is not persisted in order to perform operations on
87
+ // up-to-date cookie value, the value could have been modified by another tab
88
+
89
+
90
+ if (operations.after) {
91
+ operations.after(processedSession || currentSession);
92
+ }
93
+
94
+ next();
95
+ }
96
+ /**
97
+ * Cookie lock strategy allows mitigating issues due to concurrent access to cookie.
98
+ * This issue concerns only chromium browsers and enabling this on firefox increase cookie write failures.
99
+ */
100
+
101
+ function isCookieLockEnabled() {
102
+ return isChromium();
103
+ }
104
+
105
+ function retryLater(operations, currentNumberOfRetries) {
106
+ setTimeout(function () {
107
+ withCookieLockAccess(operations, currentNumberOfRetries + 1);
108
+ }, LOCK_RETRY_DELAY);
109
+ }
110
+
111
+ function next() {
112
+ ongoingOperations = undefined;
113
+ var nextOperations = bufferedOperations.shift();
114
+
115
+ if (nextOperations) {
116
+ withCookieLockAccess(nextOperations);
117
+ }
118
+ }
119
+
120
+ export function persistSession(session, options) {
121
+ if (isExpiredState(session)) {
122
+ clearSession(options);
123
+ return;
124
+ }
125
+
126
+ session.expire = String(dateNow() + SESSION_EXPIRATION_DELAY);
127
+ setSession(session, options);
128
+ }
129
+
130
+ function setSession(session, options) {
131
+ setCookie(SESSION_COOKIE_NAME, toSessionString(session), SESSION_EXPIRATION_DELAY, options);
132
+ }
133
+
134
+ export function toSessionString(session) {
135
+ return map(objectEntries(session), function (item) {
136
+ return item[0] + '=' + item[1];
137
+ }).join(SESSION_ENTRY_SEPARATOR);
138
+ }
139
+ export function retrieveSession() {
140
+ var sessionString = getCookie(SESSION_COOKIE_NAME);
141
+ var session = {};
142
+
143
+ if (isValidSessionString(sessionString)) {
144
+ each(sessionString.split(SESSION_ENTRY_SEPARATOR), function (entry) {
145
+ var matches = SESSION_ENTRY_REGEXP.exec(entry);
146
+
147
+ if (matches !== null) {
148
+ var key = matches[1];
149
+ var value = matches[2];
150
+ session[key] = value;
151
+ }
152
+ });
153
+ }
154
+
155
+ return session;
156
+ }
157
+
158
+ function isValidSessionString(sessionString) {
159
+ return sessionString !== undefined && (sessionString.indexOf(SESSION_ENTRY_SEPARATOR) !== -1 || SESSION_ENTRY_REGEXP.test(sessionString));
160
+ }
161
+
162
+ function isExpiredState(session) {
163
+ return isEmptyObject(session);
164
+ }
165
+
166
+ function clearSession(options) {
167
+ setCookie(SESSION_COOKIE_NAME, '', 0, options);
168
+ }
@@ -0,0 +1,78 @@
1
+ import { relativeNow, clocksOrigin, ONE_MINUTE, each, addEventListeners, addEventListener } from '../helper/tools';
2
+ import { ContextHistory } from '../helper/contextHistory';
3
+ import { startSessionStore } from './sessionStore';
4
+ import { SESSION_TIME_OUT_DELAY } from './sessionConstants';
5
+ import { DOM_EVENT } from '../helper/enums';
6
+ export var VISIBILITY_CHECK_DELAY = ONE_MINUTE;
7
+ var SESSION_CONTEXT_TIMEOUT_DELAY = SESSION_TIME_OUT_DELAY;
8
+ var stopCallbacks = [];
9
+ export var startSessionManager = function startSessionManager(options, productKey, computeSessionState) {
10
+ var sessionStore = startSessionStore(options, productKey, computeSessionState);
11
+ stopCallbacks.push(function () {
12
+ return sessionStore.stop();
13
+ });
14
+ var sessionContextHistory = new ContextHistory(SESSION_CONTEXT_TIMEOUT_DELAY);
15
+ stopCallbacks.push(function () {
16
+ return sessionContextHistory.stop();
17
+ });
18
+ sessionStore.renewObservable.subscribe(function () {
19
+ sessionContextHistory.add(buildSessionContext(), relativeNow());
20
+ });
21
+ sessionStore.expireObservable.subscribe(function () {
22
+ sessionContextHistory.closeActive(relativeNow());
23
+ });
24
+ sessionStore.expandOrRenewSession();
25
+ sessionContextHistory.add(buildSessionContext(), clocksOrigin().relative);
26
+ trackActivity(function () {
27
+ return sessionStore.expandOrRenewSession();
28
+ });
29
+ trackVisibility(function () {
30
+ return sessionStore.expandSession();
31
+ });
32
+
33
+ function buildSessionContext() {
34
+ return {
35
+ id: sessionStore.getSession().id,
36
+ trackingType: sessionStore.getSession()[productKey]
37
+ };
38
+ }
39
+
40
+ return {
41
+ findActiveSession: function findActiveSession(startTime) {
42
+ return sessionContextHistory.find(startTime);
43
+ },
44
+ renewObservable: sessionStore.renewObservable,
45
+ expireObservable: sessionStore.expireObservable
46
+ };
47
+ };
48
+ export function stopSessionManager() {
49
+ each(stopCallbacks, function (e) {
50
+ return e();
51
+ });
52
+ stopCallbacks = [];
53
+ }
54
+
55
+ function trackActivity(expandOrRenewSession) {
56
+ var _addEventListeners = addEventListeners(window, [DOM_EVENT.CLICK, DOM_EVENT.TOUCH_START, DOM_EVENT.KEY_DOWN, DOM_EVENT.SCROLL], expandOrRenewSession, {
57
+ capture: true,
58
+ passive: true
59
+ });
60
+
61
+ stopCallbacks.push(_addEventListeners.stop);
62
+ }
63
+
64
+ function trackVisibility(expandSession) {
65
+ var expandSessionWhenVisible = function expandSessionWhenVisible() {
66
+ if (document.visibilityState === 'visible') {
67
+ expandSession();
68
+ }
69
+ };
70
+
71
+ var _addEventListener = addEventListener(document, DOM_EVENT.VISIBILITY_CHANGE, expandSessionWhenVisible);
72
+
73
+ stopCallbacks.push(_addEventListener.stop);
74
+ var visibilityCheckInterval = setInterval(expandSessionWhenVisible, VISIBILITY_CHECK_DELAY);
75
+ stopCallbacks.push(function () {
76
+ clearInterval(visibilityCheckInterval);
77
+ });
78
+ }