@cloudcare/browser-core 1.1.2 → 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.
- package/cjs/{cookie.js → browser/cookie.js} +6 -37
- package/cjs/browser/fetchObservable.js +91 -0
- package/cjs/browser/xhrObservable.js +118 -0
- package/cjs/configuration/configuration.js +70 -0
- package/cjs/configuration/transportConfiguration.js +64 -0
- package/cjs/console/consoleObservable.js +84 -0
- package/cjs/dataMap.js +26 -21
- package/cjs/error/trackRuntimeError.js +27 -0
- package/cjs/helper/catchUserErrors.js +20 -0
- package/cjs/helper/contextHistory.js +134 -0
- package/cjs/helper/createEventRateLimiter.js +47 -0
- package/cjs/helper/deviceInfo.js +8 -25
- package/cjs/helper/display.js +31 -0
- package/cjs/helper/enums.js +28 -2
- package/cjs/helper/errorTools.js +63 -2
- package/cjs/helper/instrumentMethod.js +93 -0
- package/cjs/helper/lifeCycle.js +5 -3
- package/cjs/helper/observable.js +40 -2
- package/cjs/helper/tools.js +217 -11
- package/cjs/index.js +153 -23
- package/cjs/init.js +17 -27
- package/cjs/report/reportObservable.js +112 -0
- package/cjs/session/sessionConstants.js +13 -0
- package/cjs/session/sessionCookieStore.js +188 -0
- package/cjs/session/sessionManagement.js +96 -0
- package/cjs/session/sessionStore.js +150 -0
- package/cjs/synthetics/syntheticsWorkerValues.js +32 -0
- package/cjs/synthetics/usr.js +32 -0
- package/cjs/tracekit/computeStackTrace.js +73 -563
- package/cjs/tracekit/index.js +3 -15
- package/cjs/tracekit/tracekit.js +113 -0
- package/cjs/transport/batch.js +332 -0
- package/cjs/transport/httpRequest.js +112 -0
- package/cjs/transport/index.js +29 -0
- package/cjs/transport/sendWithRetryStrategy.js +177 -0
- package/cjs/transport/startBatchWithReplica.js +24 -0
- package/esm/{cookie.js → browser/cookie.js} +4 -35
- package/esm/browser/fetchObservable.js +77 -0
- package/esm/browser/xhrObservable.js +106 -0
- package/esm/configuration/configuration.js +55 -0
- package/esm/configuration/transportConfiguration.js +54 -0
- package/esm/console/consoleObservable.js +70 -0
- package/esm/dataMap.js +26 -21
- package/esm/error/trackRuntimeError.js +16 -0
- package/esm/helper/catchUserErrors.js +12 -0
- package/esm/helper/contextHistory.js +106 -0
- package/esm/helper/createEventRateLimiter.js +38 -0
- package/esm/helper/deviceInfo.js +6 -25
- package/esm/helper/display.js +21 -0
- package/esm/helper/enums.js +25 -1
- package/esm/helper/errorTools.js +58 -3
- package/esm/helper/instrumentMethod.js +81 -0
- package/esm/helper/lifeCycle.js +5 -3
- package/esm/helper/observable.js +39 -3
- package/esm/helper/tools.js +173 -3
- package/esm/index.js +17 -7
- package/esm/init.js +17 -22
- package/esm/report/reportObservable.js +98 -0
- package/esm/session/sessionConstants.js +3 -0
- package/esm/session/sessionCookieStore.js +168 -0
- package/esm/session/sessionManagement.js +78 -0
- package/esm/session/sessionStore.js +139 -0
- package/esm/synthetics/syntheticsWorkerValues.js +15 -0
- package/esm/synthetics/usr.js +18 -0
- package/esm/tracekit/computeStackTrace.js +73 -557
- package/esm/tracekit/index.js +1 -1
- package/esm/tracekit/tracekit.js +103 -0
- package/esm/transport/batch.js +316 -0
- package/esm/transport/httpRequest.js +104 -0
- package/esm/transport/index.js +3 -0
- package/esm/transport/sendWithRetryStrategy.js +165 -0
- package/esm/transport/startBatchWithReplica.js +15 -0
- package/package.json +2 -2
- package/src/.DS_Store +0 -0
- package/src/{cookie.js → browser/cookie.js} +6 -34
- package/src/browser/fetchObservable.js +86 -0
- package/src/browser/xhrObservable.js +102 -0
- package/src/configuration/configuration.js +61 -0
- package/src/configuration/transportConfiguration.js +42 -0
- package/src/console/consoleObservable.js +65 -0
- package/src/dataMap.js +26 -21
- package/src/error/trackRuntimeError.js +19 -0
- package/src/helper/catchUserErrors.js +12 -0
- package/src/helper/contextHistory.js +85 -0
- package/src/helper/createEventRateLimiter.js +37 -0
- package/src/helper/deviceInfo.js +5 -51
- package/src/helper/display.js +21 -0
- package/src/helper/enums.js +38 -14
- package/src/helper/errorTools.js +76 -12
- package/src/helper/instrumentMethod.js +97 -0
- package/src/helper/lifeCycle.js +5 -3
- package/src/helper/observable.js +33 -2
- package/src/helper/tools.js +159 -5
- package/src/index.js +18 -7
- package/src/init.js +17 -18
- package/src/report/reportObservable.js +113 -0
- package/src/session/sessionConstants.js +3 -0
- package/src/session/sessionCookieStore.js +159 -0
- package/src/session/sessionManagement.js +89 -0
- package/src/session/sessionStore.js +139 -0
- package/src/synthetics/syntheticsWorkerValues.js +22 -0
- package/src/synthetics/usr.js +18 -0
- package/src/tracekit/computeStackTrace.js +75 -551
- package/src/tracekit/index.js +1 -1
- package/src/tracekit/tracekit.js +100 -0
- package/src/transport/batch.js +289 -0
- package/src/transport/httpRequest.js +109 -0
- package/src/transport/index.js +3 -0
- package/src/transport/sendWithRetryStrategy.js +186 -0
- package/src/transport/startBatchWithReplica.js +26 -0
- package/cjs/configuration.js +0 -184
- package/cjs/errorCollection.js +0 -167
- package/cjs/fetchProxy.js +0 -162
- package/cjs/helper/errorFilter.js +0 -47
- package/cjs/sessionManagement.js +0 -221
- package/cjs/tracekit/report.js +0 -289
- package/cjs/transport.js +0 -373
- package/cjs/xhrProxy.js +0 -122
- package/esm/configuration.js +0 -167
- package/esm/errorCollection.js +0 -141
- package/esm/fetchProxy.js +0 -116
- package/esm/helper/errorFilter.js +0 -38
- package/esm/sessionManagement.js +0 -195
- package/esm/tracekit/report.js +0 -273
- package/esm/transport.js +0 -357
- package/esm/xhrProxy.js +0 -110
- package/src/configuration.js +0 -156
- package/src/errorCollection.js +0 -170
- package/src/fetchProxy.js +0 -109
- package/src/helper/errorFilter.js +0 -38
- package/src/sessionManagement.js +0 -224
- package/src/tracekit/report.js +0 -284
- package/src/transport.js +0 -380
- package/src/xhrProxy.js +0 -106
package/esm/helper/tools.js
CHANGED
|
@@ -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) {
|
|
@@ -1487,7 +1570,10 @@ export function noop() {}
|
|
|
1487
1570
|
export var ONE_SECOND = 1000;
|
|
1488
1571
|
export var ONE_MINUTE = 60 * ONE_SECOND;
|
|
1489
1572
|
export var ONE_HOUR = 60 * ONE_MINUTE;
|
|
1490
|
-
export var
|
|
1573
|
+
export var ONE_DAY = 24 * ONE_HOUR;
|
|
1574
|
+
export var ONE_YEAR = 365 * ONE_DAY;
|
|
1575
|
+
export var ONE_KIBI_BYTE = 1024;
|
|
1576
|
+
export var ONE_MEBI_BYTE = 1024 * ONE_KIBI_BYTE;
|
|
1491
1577
|
/**
|
|
1492
1578
|
* Return true if the draw is successful
|
|
1493
1579
|
* @param threshold between 0 and 100
|
|
@@ -1527,7 +1613,7 @@ export function preferredNow() {
|
|
|
1527
1613
|
return relativeNow();
|
|
1528
1614
|
}
|
|
1529
1615
|
export function getTimestamp(relativeTime) {
|
|
1530
|
-
return Math.
|
|
1616
|
+
return Math.round(getNavigationStart() + relativeTime);
|
|
1531
1617
|
}
|
|
1532
1618
|
export function relativeNow() {
|
|
1533
1619
|
return performance.now();
|
|
@@ -1539,6 +1625,17 @@ export function clocksNow() {
|
|
|
1539
1625
|
};
|
|
1540
1626
|
}
|
|
1541
1627
|
export function timeStampNow() {
|
|
1628
|
+
return dateNow();
|
|
1629
|
+
}
|
|
1630
|
+
export function looksLikeRelativeTime(time) {
|
|
1631
|
+
return time < ONE_YEAR;
|
|
1632
|
+
}
|
|
1633
|
+
export function dateNow() {
|
|
1634
|
+
// Do not use `Date.now` because sometimes websites are wrongly "polyfilling" it. For example, we
|
|
1635
|
+
// had some users using a very old version of `datejs`, which patched `Date.now` to return a Date
|
|
1636
|
+
// instance instead of a timestamp[1]. Those users are unlikely to fix this, so let's handle this
|
|
1637
|
+
// case ourselves.
|
|
1638
|
+
// [1]: https://github.com/datejs/Datejs/blob/97f5c7c58c5bc5accdab8aa7602b6ac56462d778/src/core-debug.js#L14-L16
|
|
1542
1639
|
return new Date().getTime();
|
|
1543
1640
|
}
|
|
1544
1641
|
export function elapsed(start, end) {
|
|
@@ -1559,13 +1656,28 @@ export function preferredTimeStamp(clocks) {
|
|
|
1559
1656
|
export function relativeToClocks(relative) {
|
|
1560
1657
|
return {
|
|
1561
1658
|
relative: relative,
|
|
1562
|
-
timeStamp:
|
|
1659
|
+
timeStamp: getCorrectedTimeStamp(relative)
|
|
1563
1660
|
};
|
|
1564
1661
|
}
|
|
1662
|
+
export function currentDrift() {
|
|
1663
|
+
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
|
1664
|
+
return Math.round(dateNow() - (getNavigationStart() + performance.now()));
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
function getCorrectedTimeStamp(relativeTime) {
|
|
1668
|
+
var correctedOrigin = dateNow() - performance.now(); // apply correction only for positive drift
|
|
1669
|
+
|
|
1670
|
+
if (correctedOrigin > getNavigationStart()) {
|
|
1671
|
+
return Math.round(correctedOrigin + relativeTime);
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
return getTimestamp(relativeTime);
|
|
1675
|
+
}
|
|
1565
1676
|
/**
|
|
1566
1677
|
* Navigation start slightly change on some rare cases
|
|
1567
1678
|
*/
|
|
1568
1679
|
|
|
1680
|
+
|
|
1569
1681
|
var navigationStart;
|
|
1570
1682
|
export function getNavigationStart() {
|
|
1571
1683
|
if (navigationStart === undefined) {
|
|
@@ -1670,6 +1782,21 @@ export function createContextManager() {
|
|
|
1670
1782
|
} else {
|
|
1671
1783
|
console.error('content 需要传递对象类型数据');
|
|
1672
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 = {};
|
|
1673
1800
|
}
|
|
1674
1801
|
};
|
|
1675
1802
|
}
|
|
@@ -1684,12 +1811,48 @@ export function find(array, predicate) {
|
|
|
1684
1811
|
|
|
1685
1812
|
return undefined;
|
|
1686
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
|
+
}
|
|
1687
1844
|
export function isPercentage(value) {
|
|
1688
1845
|
return isNumber(value) && value >= 0 && value <= 100;
|
|
1689
1846
|
}
|
|
1690
1847
|
export function getLocationOrigin() {
|
|
1691
1848
|
return getLinkElementOrigin(window.location);
|
|
1692
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
|
+
}
|
|
1693
1856
|
/**
|
|
1694
1857
|
* IE fallback
|
|
1695
1858
|
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/origin
|
|
@@ -1758,4 +1921,11 @@ export function escapeRowField(value) {
|
|
|
1758
1921
|
} else {
|
|
1759
1922
|
return value;
|
|
1760
1923
|
}
|
|
1924
|
+
}
|
|
1925
|
+
export function isNullUndefinedDefaultValue(data, defaultValue) {
|
|
1926
|
+
if (data !== null && data !== void 0) {
|
|
1927
|
+
return data;
|
|
1928
|
+
} else {
|
|
1929
|
+
return defaultValue;
|
|
1930
|
+
}
|
|
1761
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/
|
|
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 './
|
|
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 './
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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,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
|
+
}
|