@cloudcare/browser-core 3.2.13 → 3.2.15

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 (41) hide show
  1. package/cjs/dataMap.js +1 -1
  2. package/cjs/dataMap.js.map +1 -1
  3. package/cjs/helper/lifeCycle.js +1 -0
  4. package/cjs/helper/lifeCycle.js.map +1 -1
  5. package/cjs/helper/limitModification.js +39 -38
  6. package/cjs/helper/limitModification.js.map +1 -1
  7. package/cjs/helper/serialisation/const.js +18 -0
  8. package/cjs/helper/serialisation/const.js.map +1 -0
  9. package/cjs/helper/serialisation/contextManager.js +45 -50
  10. package/cjs/helper/serialisation/contextManager.js.map +1 -1
  11. package/cjs/helper/serialisation/customerDataTracker.js +127 -0
  12. package/cjs/helper/serialisation/customerDataTracker.js.map +1 -0
  13. package/cjs/index.js +16 -4
  14. package/cjs/index.js.map +1 -1
  15. package/esm/dataMap.js +1 -1
  16. package/esm/dataMap.js.map +1 -1
  17. package/esm/helper/lifeCycle.js +1 -0
  18. package/esm/helper/lifeCycle.js.map +1 -1
  19. package/esm/helper/limitModification.js +40 -40
  20. package/esm/helper/limitModification.js.map +1 -1
  21. package/esm/helper/serialisation/const.js +11 -0
  22. package/esm/helper/serialisation/const.js.map +1 -0
  23. package/esm/helper/serialisation/contextManager.js +46 -49
  24. package/esm/helper/serialisation/contextManager.js.map +1 -1
  25. package/esm/helper/serialisation/customerDataTracker.js +116 -0
  26. package/esm/helper/serialisation/customerDataTracker.js.map +1 -0
  27. package/esm/index.js +2 -1
  28. package/esm/index.js.map +1 -1
  29. package/package.json +2 -2
  30. package/src/dataMap.js +1 -1
  31. package/src/helper/lifeCycle.js +1 -0
  32. package/src/helper/limitModification.js +43 -48
  33. package/src/helper/serialisation/const.js +10 -0
  34. package/src/helper/serialisation/contextManager.js +41 -64
  35. package/src/helper/serialisation/customerDataTracker.js +139 -0
  36. package/src/index.js +2 -1
  37. package/cjs/helper/serialisation/heavyCustomerDataWarning.js +0 -29
  38. package/cjs/helper/serialisation/heavyCustomerDataWarning.js.map +0 -1
  39. package/esm/helper/serialisation/heavyCustomerDataWarning.js +0 -21
  40. package/esm/helper/serialisation/heavyCustomerDataWarning.js.map +0 -1
  41. package/src/helper/serialisation/heavyCustomerDataWarning.js +0 -28
@@ -1,77 +1,74 @@
1
- import { computeBytesCount } from '../byteUtils';
2
- import { deepClone, throttle, getType } from '../tools';
1
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
2
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
5
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
6
+ function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
7
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
8
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
9
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
10
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
12
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
13
+ import { deepClone, getType } from '../tools';
3
14
  import { sanitize } from '../sanitize';
4
- import { jsonStringify } from './jsonStringify';
5
15
  import { Observable } from '../observable';
6
- import { warnIfCustomerDataLimitReached } from './heavyCustomerDataWarning';
7
- export var BYTES_COMPUTATION_THROTTLING_DELAY = 200;
8
- export function createContextManager(customerDataType, computeBytesCountImpl) {
9
- if (typeof computeBytesCountImpl === 'undefined') {
10
- computeBytesCountImpl = computeBytesCount;
16
+ import { display } from '../display';
17
+ function ensureProperties(context, propertiesConfig, name) {
18
+ var newContext = _objectSpread({}, context);
19
+ for (var _i = 0, _Object$entries = Object.entries(propertiesConfig); _i < _Object$entries.length; _i++) {
20
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
21
+ key = _Object$entries$_i[0],
22
+ _Object$entries$_i$ = _Object$entries$_i[1],
23
+ required = _Object$entries$_i$.required,
24
+ type = _Object$entries$_i$.type;
25
+ /**
26
+ * Ensure specified properties are strings as defined here:
27
+ */
28
+ if (type === 'string' && key in newContext) {
29
+ newContext[key] = String(newContext[key]);
30
+ }
31
+ if (required && !(key in context)) {
32
+ display.warn("The property ".concat(key, " of ").concat(name, " context is required; context will not be sent to the intake."));
33
+ }
11
34
  }
35
+ return newContext;
36
+ }
37
+ export function createContextManager() {
38
+ var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
39
+ var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
40
+ customerDataTracker = _ref.customerDataTracker,
41
+ _ref$propertiesConfig = _ref.propertiesConfig,
42
+ propertiesConfig = _ref$propertiesConfig === void 0 ? {} : _ref$propertiesConfig;
12
43
  var context = {};
13
- var bytesCountCache;
14
- var alreadyWarned = false;
15
44
  var changeObservable = new Observable();
16
- // Throttle the bytes computation to minimize the impact on performance.
17
- // Especially useful if the user call context APIs synchronously multiple times in a row
18
- var computeBytesCountThrottled = throttle(function (context) {
19
- bytesCountCache = computeBytesCountImpl(jsonStringify(context));
20
- if (!alreadyWarned) {
21
- alreadyWarned = warnIfCustomerDataLimitReached(bytesCountCache, customerDataType);
22
- }
23
- }, BYTES_COMPUTATION_THROTTLING_DELAY).throttled;
24
45
  var contextManager = {
25
- getBytesCount: function getBytesCount() {
26
- return bytesCountCache;
27
- },
28
- /** @deprecated use getContext instead */
29
- get: function get() {
30
- return context;
31
- },
32
- /** @deprecated use setContextProperty instead */
33
- add: function add(key, value) {
34
- context[key] = value;
35
- computeBytesCountThrottled(context);
36
- changeObservable.notify();
37
- },
38
- /** @deprecated renamed to removeContextProperty */
39
- remove: function remove(key) {
40
- delete context[key];
41
- computeBytesCountThrottled(context);
42
- changeObservable.notify();
43
- },
44
- /** @deprecated use setContext instead */
45
- set: function set(newContext) {
46
- context = newContext;
47
- computeBytesCountThrottled(context);
48
- changeObservable.notify();
49
- },
50
46
  getContext: function getContext() {
51
47
  return deepClone(context);
52
48
  },
53
49
  setContext: function setContext(newContext) {
54
50
  if (getType(newContext) === 'object') {
55
- context = sanitize(newContext);
56
- computeBytesCountThrottled(context);
51
+ context = sanitize(ensureProperties(newContext, propertiesConfig, name));
52
+ customerDataTracker === null || customerDataTracker === void 0 ? void 0 : customerDataTracker.updateCustomerData(context);
57
53
  } else {
58
54
  contextManager.clearContext();
59
55
  }
60
56
  changeObservable.notify();
61
57
  },
62
58
  setContextProperty: function setContextProperty(key, property) {
63
- context[key] = deepClone(property);
64
- computeBytesCountThrottled(context);
59
+ context[key] = sanitize(ensureProperties(_defineProperty({}, key, property), propertiesConfig, name)[key]);
60
+ customerDataTracker === null || customerDataTracker === void 0 ? void 0 : customerDataTracker.updateCustomerData(context);
65
61
  changeObservable.notify();
66
62
  },
67
63
  removeContextProperty: function removeContextProperty(key) {
68
64
  delete context[key];
69
- computeBytesCountThrottled(context);
65
+ customerDataTracker === null || customerDataTracker === void 0 ? void 0 : customerDataTracker.updateCustomerData(context);
66
+ ensureProperties(context, propertiesConfig, name);
70
67
  changeObservable.notify();
71
68
  },
72
69
  clearContext: function clearContext() {
73
70
  context = {};
74
- bytesCountCache = 0;
71
+ customerDataTracker === null || customerDataTracker === void 0 ? void 0 : customerDataTracker.resetCustomerData();
75
72
  changeObservable.notify();
76
73
  },
77
74
  changeObservable: changeObservable
@@ -1 +1 @@
1
- {"version":3,"file":"contextManager.js","names":["computeBytesCount","deepClone","throttle","getType","sanitize","jsonStringify","Observable","warnIfCustomerDataLimitReached","BYTES_COMPUTATION_THROTTLING_DELAY","createContextManager","customerDataType","computeBytesCountImpl","context","bytesCountCache","alreadyWarned","changeObservable","computeBytesCountThrottled","throttled","contextManager","getBytesCount","get","add","key","value","notify","remove","set","newContext","getContext","setContext","clearContext","setContextProperty","property","removeContextProperty"],"sources":["../../../src/helper/serialisation/contextManager.js"],"sourcesContent":["import { computeBytesCount } from '../byteUtils'\nimport { deepClone, throttle, getType } from '../tools'\nimport { sanitize } from '../sanitize'\nimport { jsonStringify } from './jsonStringify'\nimport { Observable } from '../observable'\nimport { warnIfCustomerDataLimitReached } from './heavyCustomerDataWarning'\n\nexport var BYTES_COMPUTATION_THROTTLING_DELAY = 200\n\nexport function createContextManager(customerDataType, computeBytesCountImpl) {\n if (typeof computeBytesCountImpl === 'undefined') {\n computeBytesCountImpl = computeBytesCount\n }\n var context = {}\n var bytesCountCache\n var alreadyWarned = false\n var changeObservable = new Observable()\n // Throttle the bytes computation to minimize the impact on performance.\n // Especially useful if the user call context APIs synchronously multiple times in a row\n var computeBytesCountThrottled = throttle(function (context) {\n bytesCountCache = computeBytesCountImpl(jsonStringify(context))\n if (!alreadyWarned) {\n alreadyWarned = warnIfCustomerDataLimitReached(\n bytesCountCache,\n customerDataType\n )\n }\n }, BYTES_COMPUTATION_THROTTLING_DELAY).throttled\n\n var contextManager = {\n getBytesCount: function () {\n return bytesCountCache\n },\n /** @deprecated use getContext instead */\n get: function () {\n return context\n },\n\n /** @deprecated use setContextProperty instead */\n add: function (key, value) {\n context[key] = value\n computeBytesCountThrottled(context)\n changeObservable.notify()\n },\n\n /** @deprecated renamed to removeContextProperty */\n remove: function (key) {\n delete context[key]\n computeBytesCountThrottled(context)\n changeObservable.notify()\n },\n\n /** @deprecated use setContext instead */\n set: function (newContext) {\n context = newContext\n computeBytesCountThrottled(context)\n changeObservable.notify()\n },\n\n getContext: function () {\n return deepClone(context)\n },\n\n setContext: function (newContext) {\n if (getType(newContext) === 'object') {\n context = sanitize(newContext)\n computeBytesCountThrottled(context)\n } else {\n contextManager.clearContext()\n }\n changeObservable.notify()\n },\n\n setContextProperty: function (key, property) {\n context[key] = deepClone(property)\n computeBytesCountThrottled(context)\n changeObservable.notify()\n },\n\n removeContextProperty: function (key) {\n delete context[key]\n computeBytesCountThrottled(context)\n changeObservable.notify()\n },\n\n clearContext: function () {\n context = {}\n bytesCountCache = 0\n changeObservable.notify()\n },\n changeObservable: changeObservable\n }\n return contextManager\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"contextManager.js","names":["deepClone","getType","sanitize","Observable","display","ensureProperties","context","propertiesConfig","name","newContext","_objectSpread","_i","_Object$entries","Object","entries","length","_Object$entries$_i","_slicedToArray","key","_Object$entries$_i$","required","type","String","warn","concat","createContextManager","arguments","undefined","_ref","customerDataTracker","_ref$propertiesConfig","changeObservable","contextManager","getContext","setContext","updateCustomerData","clearContext","notify","setContextProperty","property","_defineProperty","removeContextProperty","resetCustomerData"],"sources":["../../../src/helper/serialisation/contextManager.js"],"sourcesContent":["import { deepClone, getType } from '../tools'\nimport { sanitize } from '../sanitize'\nimport { Observable } from '../observable'\nimport { display } from '../display'\n\nfunction ensureProperties(context, propertiesConfig, name) {\n const newContext = { ...context }\n\n for (const [key, { required, type }] of Object.entries(propertiesConfig)) {\n /**\n * Ensure specified properties are strings as defined here:\n */\n if (type === 'string' && key in newContext) {\n newContext[key] = String(newContext[key])\n }\n\n if (required && !(key in context)) {\n display.warn(\n `The property ${key} of ${name} context is required; context will not be sent to the intake.`\n )\n }\n }\n\n return newContext\n}\n\nexport function createContextManager(\n name = '',\n { customerDataTracker, propertiesConfig = {} } = {}\n) {\n let context = {}\n const changeObservable = new Observable()\n\n const contextManager = {\n getContext: () => deepClone(context),\n\n setContext: (newContext) => {\n if (getType(newContext) === 'object') {\n context = sanitize(ensureProperties(newContext, propertiesConfig, name))\n customerDataTracker?.updateCustomerData(context)\n } else {\n contextManager.clearContext()\n }\n changeObservable.notify()\n },\n\n setContextProperty: (key, property) => {\n context[key] = sanitize(\n ensureProperties({ [key]: property }, propertiesConfig, name)[key]\n )\n customerDataTracker?.updateCustomerData(context)\n changeObservable.notify()\n },\n\n removeContextProperty: (key) => {\n delete context[key]\n customerDataTracker?.updateCustomerData(context)\n ensureProperties(context, propertiesConfig, name)\n changeObservable.notify()\n },\n\n clearContext: () => {\n context = {}\n customerDataTracker?.resetCustomerData()\n changeObservable.notify()\n },\n\n changeObservable\n }\n return contextManager\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,116 @@
1
+ import { ONE_KIBI_BYTE, computeBytesCount } from '../byteUtils';
2
+ import { throttle, isEmptyObject } from '../tools';
3
+ import { jsonStringify } from './jsonStringify';
4
+ import { display } from '../display';
5
+
6
+ // RUM and logs batch bytes limit is 16KB
7
+ // ensure that we leave room for other event attributes and maintain a decent amount of event per batch
8
+ // (3KB (customer data) + 1KB (other attributes)) * 4 (events per batch) = 16KB
9
+ export var CUSTOMER_DATA_BYTES_LIMIT = 3 * ONE_KIBI_BYTE;
10
+
11
+ // We observed that the compression ratio is around 8 in general, but we also want to keep a margin
12
+ // because some data might not be compressed (ex: last view update on page exit). We chose 16KiB
13
+ // because it is also the limit of the 'batchBytesCount' that we use for RUM and Logs data, but this
14
+ // is a bit arbitrary.
15
+ export var CUSTOMER_COMPRESSED_DATA_BYTES_LIMIT = 16 * ONE_KIBI_BYTE;
16
+ export var BYTES_COMPUTATION_THROTTLING_DELAY = 200;
17
+ export var CustomerDataCompressionStatus = {
18
+ Unknown: 0,
19
+ Enabled: 1,
20
+ Disabled: 2
21
+ };
22
+ export function createCustomerDataTrackerManager() {
23
+ var compressionStatus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : CustomerDataCompressionStatus.Disabled;
24
+ var customerDataTrackers = new Map();
25
+ var alreadyWarned = false;
26
+ function checkCustomerDataLimit() {
27
+ var initialBytesCount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
28
+ if (alreadyWarned || compressionStatus === CustomerDataCompressionStatus.Unknown) {
29
+ return;
30
+ }
31
+ var bytesCountLimit = compressionStatus === CustomerDataCompressionStatus.Disabled ? CUSTOMER_DATA_BYTES_LIMIT : CUSTOMER_COMPRESSED_DATA_BYTES_LIMIT;
32
+ var bytesCount = initialBytesCount;
33
+ customerDataTrackers.forEach(function (tracker) {
34
+ bytesCount += tracker.getBytesCount();
35
+ });
36
+ if (bytesCount > bytesCountLimit) {
37
+ displayCustomerDataLimitReachedWarning(bytesCountLimit);
38
+ alreadyWarned = true;
39
+ }
40
+ }
41
+ return {
42
+ /**
43
+ * Creates a detached tracker. The manager will not store a reference to that tracker, and the
44
+ * bytes count will be counted independently from other detached trackers.
45
+ *
46
+ * This is particularly useful when we don't know when the tracker will be unused, so we don't
47
+ * leak memory (ex: when used in Logger instances).
48
+ */
49
+ createDetachedTracker: function createDetachedTracker() {
50
+ var tracker = createCustomerDataTracker(function () {
51
+ return checkCustomerDataLimit(tracker.getBytesCount());
52
+ });
53
+ return tracker;
54
+ },
55
+ /**
56
+ * Creates a tracker if it doesn't exist, and returns it.
57
+ */
58
+ getOrCreateTracker: function getOrCreateTracker(type) {
59
+ if (!customerDataTrackers.has(type)) {
60
+ customerDataTrackers.set(type, createCustomerDataTracker(checkCustomerDataLimit));
61
+ }
62
+ return customerDataTrackers.get(type);
63
+ },
64
+ setCompressionStatus: function setCompressionStatus(newCompressionStatus) {
65
+ if (compressionStatus === CustomerDataCompressionStatus.Unknown) {
66
+ compressionStatus = newCompressionStatus;
67
+ checkCustomerDataLimit();
68
+ }
69
+ },
70
+ getCompressionStatus: function getCompressionStatus() {
71
+ return compressionStatus;
72
+ },
73
+ stop: function stop() {
74
+ customerDataTrackers.forEach(function (tracker) {
75
+ return tracker.stop();
76
+ });
77
+ customerDataTrackers.clear();
78
+ }
79
+ };
80
+ }
81
+ export function createCustomerDataTracker(checkCustomerDataLimit) {
82
+ var bytesCountCache = 0;
83
+
84
+ // Throttle the bytes computation to minimize the impact on performance.
85
+ // Especially useful if the user call context APIs synchronously multiple times in a row
86
+ var _throttle = throttle(function (context) {
87
+ bytesCountCache = computeBytesCount(jsonStringify(context));
88
+ checkCustomerDataLimit();
89
+ }, BYTES_COMPUTATION_THROTTLING_DELAY),
90
+ computeBytesCountThrottled = _throttle.throttled,
91
+ cancelComputeBytesCount = _throttle.cancel;
92
+ var resetBytesCount = function resetBytesCount() {
93
+ cancelComputeBytesCount();
94
+ bytesCountCache = 0;
95
+ };
96
+ return {
97
+ updateCustomerData: function updateCustomerData(context) {
98
+ if (isEmptyObject(context)) {
99
+ resetBytesCount();
100
+ } else {
101
+ computeBytesCountThrottled(context);
102
+ }
103
+ },
104
+ resetCustomerData: resetBytesCount,
105
+ getBytesCount: function getBytesCount() {
106
+ return bytesCountCache;
107
+ },
108
+ stop: function stop() {
109
+ cancelComputeBytesCount();
110
+ }
111
+ };
112
+ }
113
+ function displayCustomerDataLimitReachedWarning(bytesCountLimit) {
114
+ display.warn("Customer data exceeds the recommended ".concat(bytesCountLimit / ONE_KIBI_BYTE, "KiB threshold."));
115
+ }
116
+ //# sourceMappingURL=customerDataTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customerDataTracker.js","names":["ONE_KIBI_BYTE","computeBytesCount","throttle","isEmptyObject","jsonStringify","display","CUSTOMER_DATA_BYTES_LIMIT","CUSTOMER_COMPRESSED_DATA_BYTES_LIMIT","BYTES_COMPUTATION_THROTTLING_DELAY","CustomerDataCompressionStatus","Unknown","Enabled","Disabled","createCustomerDataTrackerManager","compressionStatus","arguments","length","undefined","customerDataTrackers","Map","alreadyWarned","checkCustomerDataLimit","initialBytesCount","bytesCountLimit","bytesCount","forEach","tracker","getBytesCount","displayCustomerDataLimitReachedWarning","createDetachedTracker","createCustomerDataTracker","getOrCreateTracker","type","has","set","get","setCompressionStatus","newCompressionStatus","getCompressionStatus","stop","clear","bytesCountCache","_throttle","context","computeBytesCountThrottled","throttled","cancelComputeBytesCount","cancel","resetBytesCount","updateCustomerData","resetCustomerData","warn","concat"],"sources":["../../../src/helper/serialisation/customerDataTracker.js"],"sourcesContent":["import { ONE_KIBI_BYTE, computeBytesCount } from '../byteUtils'\nimport { throttle, isEmptyObject } from '../tools'\nimport { jsonStringify } from './jsonStringify'\nimport { display } from '../display'\n\n// RUM and logs batch bytes limit is 16KB\n// ensure that we leave room for other event attributes and maintain a decent amount of event per batch\n// (3KB (customer data) + 1KB (other attributes)) * 4 (events per batch) = 16KB\nexport const CUSTOMER_DATA_BYTES_LIMIT = 3 * ONE_KIBI_BYTE\n\n// We observed that the compression ratio is around 8 in general, but we also want to keep a margin\n// because some data might not be compressed (ex: last view update on page exit). We chose 16KiB\n// because it is also the limit of the 'batchBytesCount' that we use for RUM and Logs data, but this\n// is a bit arbitrary.\nexport const CUSTOMER_COMPRESSED_DATA_BYTES_LIMIT = 16 * ONE_KIBI_BYTE\n\nexport const BYTES_COMPUTATION_THROTTLING_DELAY = 200\n\nexport const CustomerDataCompressionStatus = {\n Unknown: 0,\n Enabled: 1,\n Disabled: 2\n}\n\nexport function createCustomerDataTrackerManager(\n compressionStatus = CustomerDataCompressionStatus.Disabled\n) {\n const customerDataTrackers = new Map()\n\n let alreadyWarned = false\n function checkCustomerDataLimit(initialBytesCount = 0) {\n if (\n alreadyWarned ||\n compressionStatus === CustomerDataCompressionStatus.Unknown\n ) {\n return\n }\n\n const bytesCountLimit =\n compressionStatus === CustomerDataCompressionStatus.Disabled\n ? CUSTOMER_DATA_BYTES_LIMIT\n : CUSTOMER_COMPRESSED_DATA_BYTES_LIMIT\n\n let bytesCount = initialBytesCount\n customerDataTrackers.forEach((tracker) => {\n bytesCount += tracker.getBytesCount()\n })\n\n if (bytesCount > bytesCountLimit) {\n displayCustomerDataLimitReachedWarning(bytesCountLimit)\n alreadyWarned = true\n }\n }\n\n return {\n /**\n * Creates a detached tracker. The manager will not store a reference to that tracker, and the\n * bytes count will be counted independently from other detached trackers.\n *\n * This is particularly useful when we don't know when the tracker will be unused, so we don't\n * leak memory (ex: when used in Logger instances).\n */\n createDetachedTracker: () => {\n const tracker = createCustomerDataTracker(() =>\n checkCustomerDataLimit(tracker.getBytesCount())\n )\n return tracker\n },\n\n /**\n * Creates a tracker if it doesn't exist, and returns it.\n */\n getOrCreateTracker: (type) => {\n if (!customerDataTrackers.has(type)) {\n customerDataTrackers.set(\n type,\n createCustomerDataTracker(checkCustomerDataLimit)\n )\n }\n return customerDataTrackers.get(type)\n },\n\n setCompressionStatus: (newCompressionStatus) => {\n if (compressionStatus === CustomerDataCompressionStatus.Unknown) {\n compressionStatus = newCompressionStatus\n checkCustomerDataLimit()\n }\n },\n\n getCompressionStatus: () => compressionStatus,\n\n stop: () => {\n customerDataTrackers.forEach((tracker) => tracker.stop())\n customerDataTrackers.clear()\n }\n }\n}\n\nexport function createCustomerDataTracker(checkCustomerDataLimit) {\n let bytesCountCache = 0\n\n // Throttle the bytes computation to minimize the impact on performance.\n // Especially useful if the user call context APIs synchronously multiple times in a row\n const {\n throttled: computeBytesCountThrottled,\n cancel: cancelComputeBytesCount\n } = throttle((context) => {\n bytesCountCache = computeBytesCount(jsonStringify(context))\n checkCustomerDataLimit()\n }, BYTES_COMPUTATION_THROTTLING_DELAY)\n\n const resetBytesCount = () => {\n cancelComputeBytesCount()\n bytesCountCache = 0\n }\n\n return {\n updateCustomerData: (context) => {\n if (isEmptyObject(context)) {\n resetBytesCount()\n } else {\n computeBytesCountThrottled(context)\n }\n },\n resetCustomerData: resetBytesCount,\n getBytesCount: () => bytesCountCache,\n stop: () => {\n cancelComputeBytesCount()\n }\n }\n}\n\nfunction displayCustomerDataLimitReachedWarning(bytesCountLimit) {\n display.warn(\n `Customer data exceeds the recommended ${\n bytesCountLimit / ONE_KIBI_BYTE\n }KiB threshold.`\n )\n}\n"],"mappings":"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","ignoreList":[]}
package/esm/index.js CHANGED
@@ -43,10 +43,11 @@ export { STORAGE_POLL_DELAY } from './session/sessionStore';
43
43
  export * from './transport';
44
44
  export * from './synthetics/syntheticsWorkerValues';
45
45
  export * from './helper/serialisation/contextManager';
46
- export * from './helper/serialisation/heavyCustomerDataWarning';
46
+ export * from './helper/serialisation/const';
47
47
  export * from './helper/serialisation/jsonStringify';
48
48
  export * from './helper/serialisation/rowData';
49
49
  export * from './helper/serialisation/storedContextManager';
50
+ export * from './helper/serialisation/customerDataTracker';
50
51
  export * from './helper/encoder';
51
52
  export * from './user';
52
53
  export * from './helper/polyfills';
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["startSessionManager","stopSessionManager","SESSION_TIME_OUT_DELAY","SESSION_STORE_KEY","STORAGE_POLL_DELAY"],"sources":["../src/index.js"],"sourcesContent":["export * from './helper/boundedBuffer'\nexport * from './helper/valueHistory'\nexport * from './helper/deviceInfo'\nexport * from './helper/enums'\nexport * from './helper/instrumentMethod'\nexport * from './helper/errorTools'\nexport * from './helper/byteUtils'\nexport * from './error/trackRuntimeError'\nexport * from './console/consoleObservable'\nexport * from './report/reportObservable'\nexport * from './helper/display'\nexport * from './helper/monitor'\nexport * from './helper/sanitize'\nexport * from './helper/eventEmitter'\nexport * from './helper/lifeCycle'\nexport * from './helper/limitModification'\nexport * from './helper/createEventRateLimiter'\nexport * from './helper/observable'\nexport * from './helper/tools'\nexport * from './helper/urlPolyfill'\nexport * from './helper/mobileUtil'\nexport * from './helper/getZoneJsOriginalValue'\nexport * from './helper/timer'\nexport * from './helper/readBytesFromStream'\nexport * from './helper/requestIdleCallback'\nexport * from './helper/taskQueue'\nexport * from './tracekit'\nexport * from './configuration/configuration'\nexport * from './configuration/transportConfiguration'\nexport * from './browser/cookie'\nexport * from './browser/fetchObservable'\nexport * from './browser/xhrObservable'\nexport * from './browser/pageExitObservable'\nexport * from './browser/htmlDomUtils'\nexport * from './browser/addEventListener'\nexport * from './browser/runOnReadyState'\nexport * from './browser/scroll'\n\nexport * from './dataMap'\nexport * from './init'\nexport {\n startSessionManager,\n stopSessionManager\n} from './session/sessionManagement'\nexport {\n SESSION_TIME_OUT_DELAY,\n SESSION_STORE_KEY\n} from './session/sessionConstants'\nexport { STORAGE_POLL_DELAY } from './session/sessionStore'\nexport * from './transport'\nexport * from './synthetics/syntheticsWorkerValues'\n\nexport * from './helper/serialisation/contextManager'\nexport * from './helper/serialisation/heavyCustomerDataWarning'\nexport * from './helper/serialisation/jsonStringify'\nexport * from './helper/serialisation/rowData'\nexport * from './helper/serialisation/storedContextManager'\nexport * from './helper/encoder'\nexport * from './user'\nexport * from './helper/polyfills'\nexport * from './telemetry/telemetry'\nexport * from './helper/catchUserErrors'\nexport * from './helper/connectivity'\nexport * from './helper/displayAlreadyInitializedError'\n"],"mappings":"AAAA,cAAc,wBAAwB;AACtC,cAAc,uBAAuB;AACrC,cAAc,qBAAqB;AACnC,cAAc,gBAAgB;AAC9B,cAAc,2BAA2B;AACzC,cAAc,qBAAqB;AACnC,cAAc,oBAAoB;AAClC,cAAc,2BAA2B;AACzC,cAAc,6BAA6B;AAC3C,cAAc,2BAA2B;AACzC,cAAc,kBAAkB;AAChC,cAAc,kBAAkB;AAChC,cAAc,mBAAmB;AACjC,cAAc,uBAAuB;AACrC,cAAc,oBAAoB;AAClC,cAAc,4BAA4B;AAC1C,cAAc,iCAAiC;AAC/C,cAAc,qBAAqB;AACnC,cAAc,gBAAgB;AAC9B,cAAc,sBAAsB;AACpC,cAAc,qBAAqB;AACnC,cAAc,iCAAiC;AAC/C,cAAc,gBAAgB;AAC9B,cAAc,8BAA8B;AAC5C,cAAc,8BAA8B;AAC5C,cAAc,oBAAoB;AAClC,cAAc,YAAY;AAC1B,cAAc,+BAA+B;AAC7C,cAAc,wCAAwC;AACtD,cAAc,kBAAkB;AAChC,cAAc,2BAA2B;AACzC,cAAc,yBAAyB;AACvC,cAAc,8BAA8B;AAC5C,cAAc,wBAAwB;AACtC,cAAc,4BAA4B;AAC1C,cAAc,2BAA2B;AACzC,cAAc,kBAAkB;AAEhC,cAAc,WAAW;AACzB,cAAc,QAAQ;AACtB,SACEA,mBAAmB,EACnBC,kBAAkB,QACb,6BAA6B;AACpC,SACEC,sBAAsB,EACtBC,iBAAiB,QACZ,4BAA4B;AACnC,SAASC,kBAAkB,QAAQ,wBAAwB;AAC3D,cAAc,aAAa;AAC3B,cAAc,qCAAqC;AAEnD,cAAc,uCAAuC;AACrD,cAAc,iDAAiD;AAC/D,cAAc,sCAAsC;AACpD,cAAc,gCAAgC;AAC9C,cAAc,6CAA6C;AAC3D,cAAc,kBAAkB;AAChC,cAAc,QAAQ;AACtB,cAAc,oBAAoB;AAClC,cAAc,uBAAuB;AACrC,cAAc,0BAA0B;AACxC,cAAc,uBAAuB;AACrC,cAAc,yCAAyC","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["startSessionManager","stopSessionManager","SESSION_TIME_OUT_DELAY","SESSION_STORE_KEY","STORAGE_POLL_DELAY"],"sources":["../src/index.js"],"sourcesContent":["export * from './helper/boundedBuffer'\nexport * from './helper/valueHistory'\nexport * from './helper/deviceInfo'\nexport * from './helper/enums'\nexport * from './helper/instrumentMethod'\nexport * from './helper/errorTools'\nexport * from './helper/byteUtils'\nexport * from './error/trackRuntimeError'\nexport * from './console/consoleObservable'\nexport * from './report/reportObservable'\nexport * from './helper/display'\nexport * from './helper/monitor'\nexport * from './helper/sanitize'\nexport * from './helper/eventEmitter'\nexport * from './helper/lifeCycle'\nexport * from './helper/limitModification'\nexport * from './helper/createEventRateLimiter'\nexport * from './helper/observable'\nexport * from './helper/tools'\nexport * from './helper/urlPolyfill'\nexport * from './helper/mobileUtil'\nexport * from './helper/getZoneJsOriginalValue'\nexport * from './helper/timer'\nexport * from './helper/readBytesFromStream'\nexport * from './helper/requestIdleCallback'\nexport * from './helper/taskQueue'\nexport * from './tracekit'\nexport * from './configuration/configuration'\nexport * from './configuration/transportConfiguration'\nexport * from './browser/cookie'\nexport * from './browser/fetchObservable'\nexport * from './browser/xhrObservable'\nexport * from './browser/pageExitObservable'\nexport * from './browser/htmlDomUtils'\nexport * from './browser/addEventListener'\nexport * from './browser/runOnReadyState'\nexport * from './browser/scroll'\n\nexport * from './dataMap'\nexport * from './init'\nexport {\n startSessionManager,\n stopSessionManager\n} from './session/sessionManagement'\nexport {\n SESSION_TIME_OUT_DELAY,\n SESSION_STORE_KEY\n} from './session/sessionConstants'\nexport { STORAGE_POLL_DELAY } from './session/sessionStore'\nexport * from './transport'\nexport * from './synthetics/syntheticsWorkerValues'\n\nexport * from './helper/serialisation/contextManager'\nexport * from './helper/serialisation/const'\nexport * from './helper/serialisation/jsonStringify'\nexport * from './helper/serialisation/rowData'\nexport * from './helper/serialisation/storedContextManager'\nexport * from './helper/serialisation/customerDataTracker'\nexport * from './helper/encoder'\nexport * from './user'\nexport * from './helper/polyfills'\nexport * from './telemetry/telemetry'\nexport * from './helper/catchUserErrors'\nexport * from './helper/connectivity'\nexport * from './helper/displayAlreadyInitializedError'\n"],"mappings":"AAAA,cAAc,wBAAwB;AACtC,cAAc,uBAAuB;AACrC,cAAc,qBAAqB;AACnC,cAAc,gBAAgB;AAC9B,cAAc,2BAA2B;AACzC,cAAc,qBAAqB;AACnC,cAAc,oBAAoB;AAClC,cAAc,2BAA2B;AACzC,cAAc,6BAA6B;AAC3C,cAAc,2BAA2B;AACzC,cAAc,kBAAkB;AAChC,cAAc,kBAAkB;AAChC,cAAc,mBAAmB;AACjC,cAAc,uBAAuB;AACrC,cAAc,oBAAoB;AAClC,cAAc,4BAA4B;AAC1C,cAAc,iCAAiC;AAC/C,cAAc,qBAAqB;AACnC,cAAc,gBAAgB;AAC9B,cAAc,sBAAsB;AACpC,cAAc,qBAAqB;AACnC,cAAc,iCAAiC;AAC/C,cAAc,gBAAgB;AAC9B,cAAc,8BAA8B;AAC5C,cAAc,8BAA8B;AAC5C,cAAc,oBAAoB;AAClC,cAAc,YAAY;AAC1B,cAAc,+BAA+B;AAC7C,cAAc,wCAAwC;AACtD,cAAc,kBAAkB;AAChC,cAAc,2BAA2B;AACzC,cAAc,yBAAyB;AACvC,cAAc,8BAA8B;AAC5C,cAAc,wBAAwB;AACtC,cAAc,4BAA4B;AAC1C,cAAc,2BAA2B;AACzC,cAAc,kBAAkB;AAEhC,cAAc,WAAW;AACzB,cAAc,QAAQ;AACtB,SACEA,mBAAmB,EACnBC,kBAAkB,QACb,6BAA6B;AACpC,SACEC,sBAAsB,EACtBC,iBAAiB,QACZ,4BAA4B;AACnC,SAASC,kBAAkB,QAAQ,wBAAwB;AAC3D,cAAc,aAAa;AAC3B,cAAc,qCAAqC;AAEnD,cAAc,uCAAuC;AACrD,cAAc,8BAA8B;AAC5C,cAAc,sCAAsC;AACpD,cAAc,gCAAgC;AAC9C,cAAc,6CAA6C;AAC3D,cAAc,4CAA4C;AAC1D,cAAc,kBAAkB;AAChC,cAAc,QAAQ;AACtB,cAAc,oBAAoB;AAClC,cAAc,uBAAuB;AACrC,cAAc,0BAA0B;AACxC,cAAc,uBAAuB;AACrC,cAAc,yCAAyC","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudcare/browser-core",
3
- "version": "3.2.13",
3
+ "version": "3.2.15",
4
4
  "main": "cjs/index.js",
5
5
  "module": "esm/index.js",
6
6
  "types": "types/index.d.ts",
@@ -22,5 +22,5 @@
22
22
  "author": "dataflux",
23
23
  "license": "MIT",
24
24
  "description": "DataFlux RUM Web 端数据指标监控",
25
- "gitHead": "495ab0c29f4a869e9ad76d8fa2622dd924f3d90d"
25
+ "gitHead": "3d694e63c364e9195b8a7f81dd184adf1f3ea2c0"
26
26
  }
package/src/dataMap.js CHANGED
@@ -28,7 +28,7 @@ export var commonTags = {
28
28
  view_url: 'view.url',
29
29
  view_host: 'view.host',
30
30
  view_path: 'view.path',
31
- view_name: 'view.path', // 冗余一个字段
31
+ view_name: 'view.name', // 冗余一个字段
32
32
  view_path_group: 'view.path_group'
33
33
  }
34
34
  export var commonFields = {
@@ -4,6 +4,7 @@ export var LifeCycleEventType = {
4
4
  BEFORE_VIEW_CREATED: 'BEFORE_VIEW_CREATED',
5
5
  VIEW_CREATED: 'VIEW_CREATED',
6
6
  VIEW_UPDATED: 'VIEW_UPDATED',
7
+ BEFORE_VIEW_UPDATED: 'BEFORE_VIEW_UPDATED',
7
8
  VIEW_ENDED: 'VIEW_ENDED',
8
9
  AFTER_VIEW_ENDED: 'AFTER_VIEW_ENDED',
9
10
  SESSION_RENEWED: 'SESSION_RENEWED',
@@ -1,65 +1,60 @@
1
- import { extend2Lev, each, objectEntries, getType, deepClone } from './tools'
1
+ import { objectEntries, getType, deepClone } from './tools'
2
2
  import { sanitize } from './sanitize'
3
3
 
4
- /**
5
- * Current limitation:
6
- * - field path do not support array, 'a.b.c' only
7
- */
8
4
  export function limitModification(object, modifiableFieldPaths, modifier) {
9
- var clone = deepClone(object)
10
- var result = modifier(clone)
11
- each(objectEntries(modifiableFieldPaths), function (filedPaths) {
12
- var fieldPath = filedPaths[0]
13
- var fieldType = filedPaths[1]
14
- var newValue = get(clone, fieldPath)
15
- var newType = getType(newValue)
16
- if (newType === fieldType) {
17
- set(object, fieldPath, sanitize(newValue))
18
- } else if (
19
- fieldType === 'object' &&
20
- (newType === 'undefined' || newType === 'null')
21
- ) {
22
- set(object, fieldPath, {})
23
- }
24
- })
5
+ const clone = deepClone(object)
6
+ const result = modifier(clone)
7
+
8
+ objectEntries(modifiableFieldPaths).forEach(([fieldPath, fieldType]) =>
9
+ // Traverse both object and clone simultaneously up to the path and apply the modification from the clone to the original object when the type is valid
10
+ setValueAtPath(object, clone, fieldPath.split(/\.|(?=\[\])/), fieldType)
11
+ )
25
12
 
26
13
  return result
27
14
  }
28
15
 
29
- function get(object, path) {
30
- var current = object
31
- for (var _i = 0, _a = path.split('.'); _i < _a.length; _i++) {
32
- var field = _a[_i]
33
- if (!isValidObjectContaining(current, field)) {
34
- return
16
+ function setValueAtPath(object, clone, pathSegments, fieldType) {
17
+ const [field, ...restPathSegments] = pathSegments
18
+
19
+ if (field === '[]') {
20
+ if (Array.isArray(object) && Array.isArray(clone)) {
21
+ object.forEach((item, i) =>
22
+ setValueAtPath(item, clone[i], restPathSegments, fieldType)
23
+ )
35
24
  }
36
- current = current[field]
25
+
26
+ return
27
+ }
28
+
29
+ if (!isValidObject(object) || !isValidObject(clone)) {
30
+ return
31
+ }
32
+
33
+ if (restPathSegments.length > 0) {
34
+ return setValueAtPath(
35
+ object[field],
36
+ clone[field],
37
+ restPathSegments,
38
+ fieldType
39
+ )
37
40
  }
38
- return current
41
+
42
+ setNestedValue(object, field, clone[field], fieldType)
39
43
  }
40
44
 
41
- function set(object, path, value) {
42
- var current = object
43
- var fields = path.split('.')
44
- for (var i = 0; i < fields.length; i += 1) {
45
- var field = fields[i]
46
- if (!isValidObject(current)) {
47
- return
48
- }
49
- if (i !== fields.length - 1) {
50
- current = current[field]
51
- } else {
52
- current[field] = value
53
- }
45
+ function setNestedValue(object, field, value, fieldType) {
46
+ const newType = getType(value)
47
+
48
+ if (newType === fieldType) {
49
+ object[field] = sanitize(value)
50
+ } else if (
51
+ fieldType === 'object' &&
52
+ (newType === 'undefined' || newType === 'null')
53
+ ) {
54
+ object[field] = {}
54
55
  }
55
56
  }
56
57
 
57
58
  function isValidObject(object) {
58
59
  return getType(object) === 'object'
59
60
  }
60
-
61
- function isValidObjectContaining(object, field) {
62
- return (
63
- isValidObject(object) && Object.prototype.hasOwnProperty.call(object, field)
64
- )
65
- }
@@ -0,0 +1,10 @@
1
+ // RUM and logs batch bytes limit is 16KB
2
+ // ensure that we leave room for other event attributes and maintain a decent amount of event per batch
3
+ // (3KB (customer data) + 1KB (other attributes)) * 4 (events per batch) = 16KB
4
+
5
+ export var CustomerDataType = {
6
+ FeatureFlag: 'feature flag evaluation',
7
+ User: 'user',
8
+ GlobalContext: 'global context',
9
+ View: 'view'
10
+ }
@@ -1,94 +1,71 @@
1
- import { computeBytesCount } from '../byteUtils'
2
- import { deepClone, throttle, getType } from '../tools'
1
+ import { deepClone, getType } from '../tools'
3
2
  import { sanitize } from '../sanitize'
4
- import { jsonStringify } from './jsonStringify'
5
3
  import { Observable } from '../observable'
6
- import { warnIfCustomerDataLimitReached } from './heavyCustomerDataWarning'
4
+ import { display } from '../display'
7
5
 
8
- export var BYTES_COMPUTATION_THROTTLING_DELAY = 200
6
+ function ensureProperties(context, propertiesConfig, name) {
7
+ const newContext = { ...context }
9
8
 
10
- export function createContextManager(customerDataType, computeBytesCountImpl) {
11
- if (typeof computeBytesCountImpl === 'undefined') {
12
- computeBytesCountImpl = computeBytesCount
13
- }
14
- var context = {}
15
- var bytesCountCache
16
- var alreadyWarned = false
17
- var changeObservable = new Observable()
18
- // Throttle the bytes computation to minimize the impact on performance.
19
- // Especially useful if the user call context APIs synchronously multiple times in a row
20
- var computeBytesCountThrottled = throttle(function (context) {
21
- bytesCountCache = computeBytesCountImpl(jsonStringify(context))
22
- if (!alreadyWarned) {
23
- alreadyWarned = warnIfCustomerDataLimitReached(
24
- bytesCountCache,
25
- customerDataType
26
- )
9
+ for (const [key, { required, type }] of Object.entries(propertiesConfig)) {
10
+ /**
11
+ * Ensure specified properties are strings as defined here:
12
+ */
13
+ if (type === 'string' && key in newContext) {
14
+ newContext[key] = String(newContext[key])
27
15
  }
28
- }, BYTES_COMPUTATION_THROTTLING_DELAY).throttled
29
-
30
- var contextManager = {
31
- getBytesCount: function () {
32
- return bytesCountCache
33
- },
34
- /** @deprecated use getContext instead */
35
- get: function () {
36
- return context
37
- },
38
16
 
39
- /** @deprecated use setContextProperty instead */
40
- add: function (key, value) {
41
- context[key] = value
42
- computeBytesCountThrottled(context)
43
- changeObservable.notify()
44
- },
17
+ if (required && !(key in context)) {
18
+ display.warn(
19
+ `The property ${key} of ${name} context is required; context will not be sent to the intake.`
20
+ )
21
+ }
22
+ }
45
23
 
46
- /** @deprecated renamed to removeContextProperty */
47
- remove: function (key) {
48
- delete context[key]
49
- computeBytesCountThrottled(context)
50
- changeObservable.notify()
51
- },
24
+ return newContext
25
+ }
52
26
 
53
- /** @deprecated use setContext instead */
54
- set: function (newContext) {
55
- context = newContext
56
- computeBytesCountThrottled(context)
57
- changeObservable.notify()
58
- },
27
+ export function createContextManager(
28
+ name = '',
29
+ { customerDataTracker, propertiesConfig = {} } = {}
30
+ ) {
31
+ let context = {}
32
+ const changeObservable = new Observable()
59
33
 
60
- getContext: function () {
61
- return deepClone(context)
62
- },
34
+ const contextManager = {
35
+ getContext: () => deepClone(context),
63
36
 
64
- setContext: function (newContext) {
37
+ setContext: (newContext) => {
65
38
  if (getType(newContext) === 'object') {
66
- context = sanitize(newContext)
67
- computeBytesCountThrottled(context)
39
+ context = sanitize(ensureProperties(newContext, propertiesConfig, name))
40
+ customerDataTracker?.updateCustomerData(context)
68
41
  } else {
69
42
  contextManager.clearContext()
70
43
  }
71
44
  changeObservable.notify()
72
45
  },
73
46
 
74
- setContextProperty: function (key, property) {
75
- context[key] = deepClone(property)
76
- computeBytesCountThrottled(context)
47
+ setContextProperty: (key, property) => {
48
+ context[key] = sanitize(
49
+ ensureProperties({ [key]: property }, propertiesConfig, name)[key]
50
+ )
51
+ customerDataTracker?.updateCustomerData(context)
77
52
  changeObservable.notify()
78
53
  },
79
54
 
80
- removeContextProperty: function (key) {
55
+ removeContextProperty: (key) => {
81
56
  delete context[key]
82
- computeBytesCountThrottled(context)
57
+ customerDataTracker?.updateCustomerData(context)
58
+ ensureProperties(context, propertiesConfig, name)
83
59
  changeObservable.notify()
84
60
  },
85
61
 
86
- clearContext: function () {
62
+ clearContext: () => {
87
63
  context = {}
88
- bytesCountCache = 0
64
+ customerDataTracker?.resetCustomerData()
89
65
  changeObservable.notify()
90
66
  },
91
- changeObservable: changeObservable
67
+
68
+ changeObservable
92
69
  }
93
70
  return contextManager
94
71
  }