@cloudcare/browser-core 1.2.11 → 2.0.1

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 (61) hide show
  1. package/cjs/browser/fetchObservable.js +3 -4
  2. package/cjs/browser/htmlDomUtils.js +45 -0
  3. package/cjs/browser/pageExitObservable.js +72 -0
  4. package/cjs/configuration/configuration.js +8 -0
  5. package/cjs/configuration/transportConfiguration.js +7 -0
  6. package/cjs/dataMap.js +12 -4
  7. package/cjs/helper/deviceInfo.js +44 -2
  8. package/cjs/helper/enums.js +3 -0
  9. package/cjs/helper/getZoneJsOriginalValue.js +34 -0
  10. package/cjs/helper/instrumentMethod.js +7 -1
  11. package/cjs/helper/lifeCycle.js +2 -6
  12. package/cjs/helper/readBytesFromStream.js +74 -0
  13. package/cjs/helper/tools.js +123 -46
  14. package/cjs/index.js +52 -0
  15. package/cjs/session/sessionStore.js +1 -1
  16. package/cjs/transport/batch.js +7 -44
  17. package/cjs/transport/httpRequest.js +4 -2
  18. package/cjs/transport/sendWithRetryStrategy.js +8 -8
  19. package/cjs/transport/startBatchWithReplica.js +2 -2
  20. package/esm/browser/fetchObservable.js +3 -4
  21. package/esm/browser/htmlDomUtils.js +26 -0
  22. package/esm/browser/pageExitObservable.js +57 -0
  23. package/esm/configuration/configuration.js +5 -0
  24. package/esm/configuration/transportConfiguration.js +7 -0
  25. package/esm/dataMap.js +9 -2
  26. package/esm/helper/contextHistory.js +1 -1
  27. package/esm/helper/deviceInfo.js +44 -2
  28. package/esm/helper/enums.js +3 -0
  29. package/esm/helper/getZoneJsOriginalValue.js +27 -0
  30. package/esm/helper/instrumentMethod.js +6 -1
  31. package/esm/helper/lifeCycle.js +2 -6
  32. package/esm/helper/readBytesFromStream.js +67 -0
  33. package/esm/helper/tools.js +99 -44
  34. package/esm/index.js +4 -0
  35. package/esm/session/sessionStore.js +1 -1
  36. package/esm/transport/batch.js +8 -45
  37. package/esm/transport/httpRequest.js +4 -2
  38. package/esm/transport/sendWithRetryStrategy.js +8 -8
  39. package/esm/transport/startBatchWithReplica.js +2 -2
  40. package/package.json +2 -2
  41. package/src/browser/fetchObservable.js +21 -17
  42. package/src/browser/htmlDomUtils.js +35 -0
  43. package/src/browser/pageExitObservable.js +70 -0
  44. package/src/configuration/configuration.js +6 -0
  45. package/src/configuration/transportConfiguration.js +30 -6
  46. package/src/dataMap.js +9 -2
  47. package/src/helper/contextHistory.js +1 -1
  48. package/src/helper/deviceInfo.js +39 -3
  49. package/src/helper/enums.js +40 -37
  50. package/src/helper/getZoneJsOriginalValue.js +27 -0
  51. package/src/helper/instrumentMethod.js +40 -50
  52. package/src/helper/lifeCycle.js +2 -7
  53. package/src/helper/readBytesFromStream.js +69 -0
  54. package/src/helper/tools.js +112 -43
  55. package/src/index.js +4 -1
  56. package/src/session/sessionStore.js +27 -24
  57. package/src/synthetics/syntheticsWorkerValues.js +11 -7
  58. package/src/transport/batch.js +70 -81
  59. package/src/transport/httpRequest.js +25 -25
  60. package/src/transport/sendWithRetryStrategy.js +14 -9
  61. package/src/transport/startBatchWithReplica.js +11 -5
@@ -5,7 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.ONE_YEAR = exports.ONE_SECOND = exports.ONE_MINUTE = exports.ONE_MEBI_BYTE = exports.ONE_KIBI_BYTE = exports.ONE_HOUR = exports.ONE_DAY = void 0;
7
7
  exports.UUID = UUID;
8
- exports.addEvent = exports._URL = void 0;
8
+ exports._URL = void 0;
9
+ exports.addDuration = addDuration;
10
+ exports.addEvent = void 0;
9
11
  exports.addEventListener = addEventListener;
10
12
  exports.addEventListeners = addEventListeners;
11
13
  exports.ajax = exports.addSinglePageEvent = exports.addHashEvent = void 0;
@@ -26,6 +28,7 @@ exports.each = void 0;
26
28
  exports.elapsed = elapsed;
27
29
  exports.elementMatches = elementMatches;
28
30
  exports.encodeDates = void 0;
31
+ exports.endsWith = endsWith;
29
32
  exports.escapeFieldValueStr = escapeFieldValueStr;
30
33
  exports.escapeJsonValue = escapeJsonValue;
31
34
  exports.escapeRowData = escapeRowData;
@@ -39,6 +42,7 @@ exports.getHostname = exports.getCurrentDomain = exports.getCookieTopLevelDomain
39
42
  exports.getLinkElementOrigin = getLinkElementOrigin;
40
43
  exports.getLocationOrigin = getLocationOrigin;
41
44
  exports.getNavigationStart = getNavigationStart;
45
+ exports.getPathFromHash = getPathFromHash;
42
46
  exports.getReferrer = exports.getQueryParamsFromUrl = exports.getQueryParam = void 0;
43
47
  exports.getRelativeTime = getRelativeTime;
44
48
  exports.getScreenOrientation = void 0;
@@ -50,6 +54,7 @@ exports.includes = includes;
50
54
  exports.isBoolean = exports.isArray = exports.isArguments = exports.inherit = exports.indexOf = void 0;
51
55
  exports.isChromium = isChromium;
52
56
  exports.isFunction = exports.isEmptyObject = exports.isElement = exports.isDate = void 0;
57
+ exports.isHashAnAnchor = isHashAnAnchor;
53
58
  exports.isIE = isIE;
54
59
  exports.isJSONString = void 0;
55
60
  exports.isNullUndefinedDefaultValue = isNullUndefinedDefaultValue;
@@ -66,6 +71,7 @@ exports.mergeInto = mergeInto;
66
71
  exports.msToNs = msToNs;
67
72
  exports.noop = noop;
68
73
  exports.objectEntries = exports.now = void 0;
74
+ exports.objectHasValue = objectHasValue;
69
75
  exports.performDraw = performDraw;
70
76
  exports.preferredClock = preferredClock;
71
77
  exports.preferredNow = preferredNow;
@@ -73,20 +79,29 @@ exports.preferredTimeStamp = preferredTimeStamp;
73
79
  exports.relativeNow = relativeNow;
74
80
  exports.relativeToClocks = relativeToClocks;
75
81
  exports.replaceNumberCharByPath = replaceNumberCharByPath;
82
+ exports.requestIdleCallback = requestIdleCallback;
76
83
  exports.round = round;
84
+ exports.runOnReadyState = runOnReadyState;
77
85
  exports.safeJSONParse = void 0;
78
86
  exports.safeTruncate = safeTruncate;
79
87
  exports.sessionStorage = exports.searchObjString = exports.searchObjDate = exports.searchConfigData = void 0;
80
88
  exports.shallowClone = shallowClone;
81
- exports.throttle = exports.strip_sa_properties = exports.strip_empty_properties = exports.stringSplice = exports.strToUnicode = exports.some = void 0;
89
+ exports.some = void 0;
90
+ exports.startsWith = startsWith;
91
+ exports.throttle = exports.strip_sa_properties = exports.strip_empty_properties = exports.stringSplice = exports.strToUnicode = void 0;
82
92
  exports.timeStampNow = timeStampNow;
83
93
  exports.toArray = exports.tirm = void 0;
84
94
  exports.toServerDuration = toServerDuration;
85
95
  exports.toSnakeCase = toSnakeCase;
96
+ exports.tryToClone = tryToClone;
86
97
  exports.values = exports.utf8Encode = exports.urlParse = exports.unique = exports.typeDecide = void 0;
87
98
  exports.withSnakeCaseKeys = withSnakeCaseKeys;
88
99
  exports.xhr = void 0;
89
100
 
101
+ var _enums = require("./enums");
102
+
103
+ var _getZoneJsOriginalValue = require("./getZoneJsOriginalValue");
104
+
90
105
  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
91
106
 
92
107
  var ArrayProto = Array.prototype;
@@ -588,49 +603,42 @@ var now = Date.now || function () {
588
603
 
589
604
  exports.now = now;
590
605
 
591
- var throttle = function throttle(func, wait, options) {
592
- var timeout, context, args, result;
593
- var previous = 0;
594
- if (!options) options = {};
595
-
596
- var later = function later() {
597
- previous = options.leading === false ? 0 : new Date().getTime();
598
- timeout = null;
599
- result = func.apply(context, args);
600
- if (!timeout) context = args = null;
601
- };
602
-
603
- var throttled = function throttled() {
604
- args = arguments;
605
- var now = new Date().getTime();
606
- if (!previous && options.leading === false) previous = now; //下次触发 func 剩余的时间
607
-
608
- var remaining = wait - (now - previous);
609
- context = this; // 如果没有剩余的时间了或者你改了系统时间
610
-
611
- if (remaining <= 0 || remaining > wait) {
612
- if (timeout) {
613
- clearTimeout(timeout);
614
- timeout = null;
606
+ var throttle = function throttle(fn, wait, options) {
607
+ var needLeadingExecution = options && options.leading !== undefined ? options.leading : true;
608
+ var needTrailingExecution = options && options.trailing !== undefined ? options.trailing : true;
609
+ var inWaitPeriod = false;
610
+ var pendingExecutionWithParameters;
611
+ var pendingTimeoutId;
612
+ var context = this;
613
+ return {
614
+ throttled: function throttled() {
615
+ if (inWaitPeriod) {
616
+ pendingExecutionWithParameters = arguments;
617
+ return;
615
618
  }
616
619
 
617
- previous = now;
618
- result = func.apply(context, args);
619
- if (!timeout) context = args = null;
620
- } else if (!timeout && options.trailing !== false) {
621
- timeout = setTimeout(later, remaining);
622
- }
620
+ if (needLeadingExecution) {
621
+ fn.apply(context, arguments);
622
+ } else {
623
+ pendingExecutionWithParameters = arguments;
624
+ }
623
625
 
624
- return result;
625
- };
626
+ inWaitPeriod = true;
627
+ pendingTimeoutId = setTimeout(function () {
628
+ if (needTrailingExecution && pendingExecutionWithParameters) {
629
+ fn.apply(context, pendingExecutionWithParameters);
630
+ }
626
631
 
627
- throttled.cancel = function () {
628
- clearTimeout(timeout);
629
- previous = 0;
630
- timeout = null;
632
+ inWaitPeriod = false;
633
+ pendingExecutionWithParameters = undefined;
634
+ }, wait);
635
+ },
636
+ cancel: function cancel() {
637
+ clearTimeout(pendingTimeoutId);
638
+ inWaitPeriod = false;
639
+ pendingExecutionWithParameters = undefined;
640
+ }
631
641
  };
632
-
633
- return throttled;
634
642
  };
635
643
 
636
644
  exports.throttle = throttle;
@@ -1996,6 +2004,10 @@ function currentDrift() {
1996
2004
  return Math.round(dateNow() - (getNavigationStart() + performance.now()));
1997
2005
  }
1998
2006
 
2007
+ function addDuration(a, b) {
2008
+ return a + b;
2009
+ }
2010
+
1999
2011
  function getCorrectedTimeStamp(relativeTime) {
2000
2012
  var correctedOrigin = dateNow() - performance.now(); // apply correction only for positive drift
2001
2013
 
@@ -2051,8 +2063,8 @@ function safeTruncate(candidate, length) {
2051
2063
  return candidate.slice(0, length);
2052
2064
  }
2053
2065
 
2054
- function addEventListener(emitter, event, listener, options) {
2055
- return addEventListeners(emitter, [event], listener, options);
2066
+ function addEventListener(eventTarget, event, listener, options) {
2067
+ return addEventListeners(eventTarget, [event], listener, options);
2056
2068
  }
2057
2069
  /**
2058
2070
  * Add event listeners to an event emitter object (Window, Element, mock object...). This provides
@@ -2071,8 +2083,8 @@ function addEventListener(emitter, event, listener, options) {
2071
2083
  */
2072
2084
 
2073
2085
 
2074
- function addEventListeners(emitter, events, listener, options) {
2075
- var wrapedListener = options && options.once ? function (event) {
2086
+ function addEventListeners(eventTarget, events, listener, options) {
2087
+ var wrappedListener = options && options.once ? function (event) {
2076
2088
  stop();
2077
2089
  listener(event);
2078
2090
  } : listener;
@@ -2080,13 +2092,15 @@ function addEventListeners(emitter, events, listener, options) {
2080
2092
  capture: options.capture,
2081
2093
  passive: options.passive
2082
2094
  } : options && options.capture;
2095
+ var add = (0, _getZoneJsOriginalValue.getZoneJsOriginalValue)(eventTarget, 'addEventListener');
2083
2096
  each(events, function (event) {
2084
- emitter.addEventListener(event, wrapedListener, options);
2097
+ add.call(eventTarget, event, wrappedListener, options);
2085
2098
  });
2086
2099
 
2087
2100
  var stop = function stop() {
2101
+ var remove = (0, _getZoneJsOriginalValue.getZoneJsOriginalValue)(eventTarget, 'removeEventListener');
2088
2102
  each(events, function (event) {
2089
- emitter.removeEventListener(event, wrapedListener, options);
2103
+ remove.call(eventTarget, event, wrappedListener, options);
2090
2104
  });
2091
2105
  };
2092
2106
 
@@ -2284,4 +2298,67 @@ function isNullUndefinedDefaultValue(data, defaultValue) {
2284
2298
  } else {
2285
2299
  return defaultValue;
2286
2300
  }
2301
+ }
2302
+
2303
+ function runOnReadyState(expectedReadyState, callback) {
2304
+ if (document.readyState === expectedReadyState || document.readyState === 'complete') {
2305
+ callback();
2306
+ } else {
2307
+ var eventName = expectedReadyState === 'complete' ? _enums.DOM_EVENT.LOAD : _enums.DOM_EVENT.DOM_CONTENT_LOADED;
2308
+ addEventListener(window, eventName, callback, {
2309
+ once: true
2310
+ });
2311
+ }
2312
+ }
2313
+
2314
+ function requestIdleCallback(callback, opts) {
2315
+ // Use 'requestIdleCallback' when available: it will throttle the mutation processing if the
2316
+ // browser is busy rendering frames (ex: when frames are below 60fps). When not available, the
2317
+ // fallback on 'requestAnimationFrame' will still ensure the mutations are processed after any
2318
+ // browser rendering process (Layout, Recalculate Style, etc.), so we can serialize DOM nodes
2319
+ // efficiently.
2320
+ if (window.requestIdleCallback) {
2321
+ var id = window.requestIdleCallback(callback, opts);
2322
+ return function () {
2323
+ return window.cancelIdleCallback(id);
2324
+ };
2325
+ }
2326
+
2327
+ var id = window.requestAnimationFrame(callback);
2328
+ return function () {
2329
+ return window.cancelAnimationFrame(id);
2330
+ };
2331
+ }
2332
+
2333
+ function objectHasValue(object, value) {
2334
+ return some(keys(object), function (key) {
2335
+ return object[key] === value;
2336
+ });
2337
+ }
2338
+
2339
+ function startsWith(candidate, search) {
2340
+ return candidate.slice(0, search.length) === search;
2341
+ }
2342
+
2343
+ function endsWith(candidate, search) {
2344
+ return candidate.slice(-search.length) === search;
2345
+ }
2346
+
2347
+ function tryToClone(response) {
2348
+ try {
2349
+ return response.clone();
2350
+ } catch (e) {
2351
+ // clone can throw if the response has already been used by another instrumentation or is disturbed
2352
+ return;
2353
+ }
2354
+ }
2355
+
2356
+ function isHashAnAnchor(hash) {
2357
+ var correspondingId = hash.substr(1);
2358
+ return !!document.getElementById(correspondingId);
2359
+ }
2360
+
2361
+ function getPathFromHash(hash) {
2362
+ var index = hash.indexOf('?');
2363
+ return index < 0 ? hash : hash.slice(0, index);
2287
2364
  }
package/cjs/index.js CHANGED
@@ -238,6 +238,32 @@ Object.keys(_mobileUtil).forEach(function (key) {
238
238
  });
239
239
  });
240
240
 
241
+ var _getZoneJsOriginalValue = require("./helper/getZoneJsOriginalValue");
242
+
243
+ Object.keys(_getZoneJsOriginalValue).forEach(function (key) {
244
+ if (key === "default" || key === "__esModule") return;
245
+ if (key in exports && exports[key] === _getZoneJsOriginalValue[key]) return;
246
+ Object.defineProperty(exports, key, {
247
+ enumerable: true,
248
+ get: function get() {
249
+ return _getZoneJsOriginalValue[key];
250
+ }
251
+ });
252
+ });
253
+
254
+ var _readBytesFromStream = require("./helper/readBytesFromStream");
255
+
256
+ Object.keys(_readBytesFromStream).forEach(function (key) {
257
+ if (key === "default" || key === "__esModule") return;
258
+ if (key in exports && exports[key] === _readBytesFromStream[key]) return;
259
+ Object.defineProperty(exports, key, {
260
+ enumerable: true,
261
+ get: function get() {
262
+ return _readBytesFromStream[key];
263
+ }
264
+ });
265
+ });
266
+
241
267
  var _tracekit = require("./tracekit");
242
268
 
243
269
  Object.keys(_tracekit).forEach(function (key) {
@@ -316,6 +342,32 @@ Object.keys(_xhrObservable).forEach(function (key) {
316
342
  });
317
343
  });
318
344
 
345
+ var _pageExitObservable = require("./browser/pageExitObservable");
346
+
347
+ Object.keys(_pageExitObservable).forEach(function (key) {
348
+ if (key === "default" || key === "__esModule") return;
349
+ if (key in exports && exports[key] === _pageExitObservable[key]) return;
350
+ Object.defineProperty(exports, key, {
351
+ enumerable: true,
352
+ get: function get() {
353
+ return _pageExitObservable[key];
354
+ }
355
+ });
356
+ });
357
+
358
+ var _htmlDomUtils = require("./browser/htmlDomUtils");
359
+
360
+ Object.keys(_htmlDomUtils).forEach(function (key) {
361
+ if (key === "default" || key === "__esModule") return;
362
+ if (key in exports && exports[key] === _htmlDomUtils[key]) return;
363
+ Object.defineProperty(exports, key, {
364
+ enumerable: true,
365
+ get: function get() {
366
+ return _htmlDomUtils[key];
367
+ }
368
+ });
369
+ });
370
+
319
371
  var _dataMap = require("./dataMap");
320
372
 
321
373
  Object.keys(_dataMap).forEach(function (key) {
@@ -136,7 +136,7 @@ function startSessionStore(options, productKey, computeSessionState) {
136
136
  }
137
137
 
138
138
  return {
139
- expandOrRenewSession: (0, _tools.throttle)(expandOrRenewSession, _cookie.COOKIE_ACCESS_DELAY),
139
+ expandOrRenewSession: (0, _tools.throttle)(expandOrRenewSession, _cookie.COOKIE_ACCESS_DELAY).throttled,
140
140
  expandSession: expandSession,
141
141
  getSession: function getSession() {
142
142
  return sessionCache;
@@ -48,7 +48,8 @@ var processedMessageByDataMap = function processedMessageByDataMap(message) {
48
48
  }
49
49
  });
50
50
  var fieldsStr = [];
51
- (0, _tools.each)(value.fields, function (_value, _key) {
51
+ var fields = (0, _tools.extend)({}, _dataMap.commonFields, value.fields);
52
+ (0, _tools.each)(fields, function (_value, _key) {
52
53
  if ((0, _tools.isArray)(_value) && _value.length === 2) {
53
54
  var type = _value[0],
54
55
  value_path = _value[1];
@@ -137,7 +138,7 @@ var processedMessageByDataMap = function processedMessageByDataMap(message) {
137
138
 
138
139
  exports.processedMessageByDataMap = processedMessageByDataMap;
139
140
 
140
- var batch = function batch(request, batchMessagesLimit, batchBytesLimit, messageBytesLimit, flushTimeout, beforeUnloadCallback) {
141
+ var batch = function batch(request, batchMessagesLimit, batchBytesLimit, messageBytesLimit, flushTimeout, pageExitObservable) {
141
142
  this.pushOnlyBuffer = [];
142
143
  this.upsertBuffer = {};
143
144
  this.bufferBytesCount = 0;
@@ -148,13 +149,11 @@ var batch = function batch(request, batchMessagesLimit, batchBytesLimit, message
148
149
  this.messageBytesLimit = messageBytesLimit;
149
150
  this.flushTimeout = flushTimeout;
150
151
 
151
- if (typeof beforeUnloadCallback === 'function') {
152
- this.beforeUnloadCallback = beforeUnloadCallback;
153
- } else {
154
- this.beforeUnloadCallback = _tools.noop;
155
- }
152
+ var _this = this;
156
153
 
157
- this.setupFlushOnExit();
154
+ pageExitObservable.subscribe(function () {
155
+ _this.flush(_this.request.sendOnExit);
156
+ });
158
157
  this.flushPeriodically();
159
158
  };
160
159
 
@@ -292,41 +291,5 @@ batch.prototype.flushPeriodically = function () {
292
291
  }, this.flushTimeout);
293
292
  };
294
293
 
295
- batch.prototype.setupFlushOnExit = function () {
296
- /**
297
- * With sendBeacon, requests are guaranteed to be successfully sent during document unload
298
- */
299
- // @ts-ignore this function is not always defined
300
- var _this = this;
301
-
302
- if (navigator.sendBeacon) {
303
- /**
304
- * beforeunload is called before visibilitychange
305
- * register first to be sure to be called before flush on beforeunload
306
- * caveat: unload can still be canceled by another listener
307
- */
308
- (0, _tools.addEventListener)(window, _enums.DOM_EVENT.BEFORE_UNLOAD, this.beforeUnloadCallback);
309
- /**
310
- * Only event that guarantee to fire on mobile devices when the page transitions to background state
311
- * (e.g. when user switches to a different application, goes to homescreen, etc), or is being unloaded.
312
- */
313
-
314
- (0, _tools.addEventListener)(document, _enums.DOM_EVENT.VISIBILITY_CHANGE, function () {
315
- if (document.visibilityState === 'hidden') {
316
- _this.flushOnExit();
317
- }
318
- });
319
- /**
320
- * Safari does not support yet to send a request during:
321
- * - a visibility change during doc unload (cf: https://bugs.webkit.org/show_bug.cgi?id=194897)
322
- * - a page hide transition (cf: https://bugs.webkit.org/show_bug.cgi?id=188329)
323
- */
324
-
325
- (0, _tools.addEventListener)(window, _enums.DOM_EVENT.BEFORE_UNLOAD, function () {
326
- return _this.flushOnExit();
327
- });
328
- }
329
- };
330
-
331
294
  var Batch = batch;
332
295
  exports.Batch = Batch;
@@ -73,11 +73,13 @@ function fetchKeepAliveStrategy(endpointUrl, bytesLimit, payload, onResponse) {
73
73
  fetch(url, {
74
74
  method: 'POST',
75
75
  body: data,
76
- keepalive: true
76
+ keepalive: true,
77
+ mode: 'cors'
77
78
  }).then(function (response) {
78
79
  if (typeof onResponse === 'function') {
79
80
  onResponse({
80
- status: response.status
81
+ status: response.status,
82
+ type: response.type
81
83
  });
82
84
  }
83
85
  }, function () {
@@ -22,13 +22,13 @@ exports.MAX_BACKOFF_TIME = MAX_BACKOFF_TIME;
22
22
  var INITIAL_BACKOFF_TIME = _tools.ONE_SECOND;
23
23
  exports.INITIAL_BACKOFF_TIME = INITIAL_BACKOFF_TIME;
24
24
  var TransportStatus = {
25
- UP: 'UP',
26
- FAILURE_DETECTED: 'FAILURE_DETECTED',
27
- DOWN: 'DOWN'
25
+ UP: 0,
26
+ FAILURE_DETECTED: 1,
27
+ DOWN: 2
28
28
  };
29
29
  var RetryReason = {
30
- AFTER_SUCCESS: 'AFTER_SUCCESS',
31
- AFTER_RESUME: 'AFTER_RESUME'
30
+ AFTER_SUCCESS: 0,
31
+ AFTER_RESUME: 1
32
32
  };
33
33
 
34
34
  function sendWithRetryStrategy(payload, state, sendStrategy, reportError) {
@@ -80,7 +80,7 @@ function send(payload, state, sendStrategy, responseData) {
80
80
  sendStrategy(payload, function (response) {
81
81
  state.bandwidthMonitor.remove(payload);
82
82
 
83
- if (wasRequestSuccessful(response)) {
83
+ if (!shouldRetryRequest(response)) {
84
84
  state.transportStatus = TransportStatus.UP;
85
85
  onSuccess();
86
86
  } else {
@@ -110,8 +110,8 @@ function retryQueuedPayloads(reason, state, sendStrategy, reportError) {
110
110
  }
111
111
  }
112
112
 
113
- function wasRequestSuccessful(response) {
114
- return response.status !== 0 && response.status < 500;
113
+ function shouldRetryRequest(response) {
114
+ return response.type !== 'opaque' && (response.status === 0 && !navigator.onLine || response.status === 408 || response.status === 429 || response.status >= 500);
115
115
  }
116
116
 
117
117
  function newRetryState() {
@@ -9,11 +9,11 @@ var _batch = require("./batch");
9
9
 
10
10
  var _httpRequest = require("./httpRequest");
11
11
 
12
- function startBatchWithReplica(configuration, endpointUrl, reportError) {
12
+ function startBatchWithReplica(configuration, endpointUrl, reportError, pageExitObservable) {
13
13
  var primaryBatch = createBatch(endpointUrl);
14
14
 
15
15
  function createBatch(endpointUrl) {
16
- return new _batch.Batch((0, _httpRequest.createHttpRequest)(endpointUrl, configuration.batchBytesLimit, reportError), configuration.batchMessagesLimit, configuration.batchBytesLimit, configuration.messageBytesLimit, configuration.flushTimeout);
16
+ return new _batch.Batch((0, _httpRequest.createHttpRequest)(endpointUrl, configuration.batchBytesLimit, reportError), configuration.batchMessagesLimit, configuration.batchBytesLimit, configuration.messageBytesLimit, configuration.flushTimeout, pageExitObservable);
17
17
  }
18
18
 
19
19
  return {
@@ -56,21 +56,20 @@ function beforeSend(observable, input, init) {
56
56
  function afterSend(observable, responsePromise, startContext) {
57
57
  var reportFetch = function reportFetch(response) {
58
58
  var context = startContext;
59
- context.state = 'complete';
60
- context.duration = elapsed(context.startClocks.timeStamp, timeStampNow());
59
+ context.state = 'resolve'; // context.duration = elapsed(context.startClocks.timeStamp, timeStampNow())
61
60
 
62
61
  if ('stack' in response || response instanceof Error) {
63
62
  context.status = 0;
64
63
  context.isAborted = response instanceof DOMException && response.code === DOMException.ABORT_ERR;
65
64
  context.error = response;
66
- observable.notify(context);
67
65
  } else if ('status' in response) {
68
66
  context.response = response;
69
67
  context.responseType = response.type;
70
68
  context.status = response.status;
71
69
  context.isAborted = false;
72
- observable.notify(context);
73
70
  }
71
+
72
+ observable.notify(context);
74
73
  };
75
74
 
76
75
  responsePromise.then(reportFetch, reportFetch);
@@ -0,0 +1,26 @@
1
+ export function isTextNode(node) {
2
+ return node.nodeType === Node.TEXT_NODE;
3
+ }
4
+ export function isCommentNode(node) {
5
+ return node.nodeType === Node.COMMENT_NODE;
6
+ }
7
+ export function isElementNode(node) {
8
+ return node.nodeType === Node.ELEMENT_NODE;
9
+ }
10
+ export function isNodeShadowHost(node) {
11
+ return isElementNode(node) && Boolean(node.shadowRoot);
12
+ }
13
+ export function isNodeShadowRoot(node) {
14
+ var shadowRoot = node;
15
+ return !!shadowRoot.host && shadowRoot.nodeType === Node.DOCUMENT_FRAGMENT_NODE && isElementNode(shadowRoot.host);
16
+ }
17
+ export function getChildNodes(node) {
18
+ return isNodeShadowHost(node) ? node.shadowRoot.childNodes : node.childNodes;
19
+ }
20
+ /**
21
+ * Return `host` in case if the current node is a shadow root otherwise will return the `parentNode`
22
+ */
23
+
24
+ export function getParentNode(node) {
25
+ return isNodeShadowRoot(node) ? node.host : node.parentNode;
26
+ }
@@ -0,0 +1,57 @@
1
+ import { Observable } from '../helper/observable';
2
+ import { addEventListener, addEventListeners, includes, values } from '../helper/tools';
3
+ import { DOM_EVENT } from '../helper/enums';
4
+ export var PageExitReason = {
5
+ HIDDEN: 'visibility_hidden',
6
+ UNLOADING: 'before_unload',
7
+ PAGEHIDE: 'page_hide',
8
+ FROZEN: 'page_frozen'
9
+ };
10
+ export function createPageExitObservable() {
11
+ var observable = new Observable(function () {
12
+ /**
13
+ * Only event that guarantee to fire on mobile devices when the page transitions to background state
14
+ * (e.g. when user switches to a different application, goes to homescreen, etc), or is being unloaded.
15
+ */
16
+ var visibilityChangeListener = addEventListeners(document, [DOM_EVENT.VISIBILITY_CHANGE, DOM_EVENT.FREEZE, DOM_EVENT.PAGE_HIDE], function (event) {
17
+ if (event.type === DOM_EVENT.VISIBILITY_CHANGE && document.visibilityState === 'hidden') {
18
+ /**
19
+ * Only event that guarantee to fire on mobile devices when the page transitions to background state
20
+ * (e.g. when user switches to a different application, goes to homescreen, etc), or is being unloaded.
21
+ */
22
+ observable.notify({
23
+ reason: PageExitReason.HIDDEN
24
+ });
25
+ } else if (event.type === DOM_EVENT.FREEZE) {
26
+ /**
27
+ * After transitioning in background a tab can be freezed to preserve resources. (cf: https://developer.chrome.com/blog/page-lifecycle-api)
28
+ * Allow to collect events happening between hidden and frozen state.
29
+ */
30
+ observable.notify({
31
+ reason: PageExitReason.FROZEN
32
+ });
33
+ }
34
+ }, {
35
+ capture: true
36
+ });
37
+ /**
38
+ * Safari does not support yet to send a request during:
39
+ * - a visibility change during doc unload (cf: https://bugs.webkit.org/show_bug.cgi?id=194897)
40
+ * - a page hide transition (cf: https://bugs.webkit.org/show_bug.cgi?id=188329)
41
+ */
42
+
43
+ var beforeUnloadListener = addEventListener(window, DOM_EVENT.BEFORE_UNLOAD, function () {
44
+ observable.notify({
45
+ reason: PageExitReason.UNLOADING
46
+ });
47
+ });
48
+ return function () {
49
+ visibilityChangeListener.stop();
50
+ beforeUnloadListener.stop();
51
+ };
52
+ });
53
+ return observable;
54
+ }
55
+ export function isPageExitReason(reason) {
56
+ return includes(values(PageExitReason), reason);
57
+ }
@@ -3,6 +3,11 @@ import { catchUserErrors } from '../helper/catchUserErrors';
3
3
  import { display } from '../helper/display';
4
4
  import { assign, isPercentage, ONE_KIBI_BYTE, ONE_SECOND, isNullUndefinedDefaultValue } from '../helper/tools';
5
5
  import { computeTransportConfiguration } from './transportConfiguration';
6
+ export var DefaultPrivacyLevel = {
7
+ ALLOW: 'allow',
8
+ MASK: 'mask',
9
+ MASK_USER_INPUT: 'mask-user-input'
10
+ };
6
11
  export function validateAndBuildConfiguration(initConfiguration) {
7
12
  if (initConfiguration.sampleRate !== undefined && !isPercentage(initConfiguration.sampleRate)) {
8
13
  display.error('Sample Rate should be a number between 0 and 100');
@@ -15,6 +15,12 @@ function getLogsEndPoint(url) {
15
15
  return trim(url) + '/v1/write/logging';
16
16
  }
17
17
 
18
+ function getSessionReplayEndPoint(url) {
19
+ // return 'http://localhost:3002/write_data'
20
+ if (url.lastIndexOf('/') === url.length - 1) return trim(url) + 'v1/write/rum/replay';
21
+ return trim(url) + '/v1/write/rum/replay';
22
+ }
23
+
18
24
  export function computeTransportConfiguration(initConfiguration) {
19
25
  var isIntakeUrl = function isIntakeUrl(url) {
20
26
  return false;
@@ -35,6 +41,7 @@ export function computeTransportConfiguration(initConfiguration) {
35
41
  return {
36
42
  datakitUrl: getDatakitUrl(initConfiguration.datakitUrl || initConfiguration.datakitOrigin),
37
43
  logsEndpoint: getLogsEndPoint(initConfiguration.datakitOrigin),
44
+ sessionReplayEndPoint: getSessionReplayEndPoint(initConfiguration.datakitOrigin),
38
45
  isIntakeUrl: isIntakeUrl,
39
46
  isServerError: isServerError
40
47
  };