@splitsoftware/splitio-commons 1.6.2-rc.12 → 1.6.2-rc.14

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 (95) hide show
  1. package/cjs/listeners/browser.js +9 -11
  2. package/cjs/sdkFactory/index.js +7 -24
  3. package/cjs/storages/KeyBuilderSS.js +4 -43
  4. package/cjs/storages/inLocalStorage/index.js +14 -10
  5. package/cjs/storages/inMemory/InMemoryStorage.js +10 -7
  6. package/cjs/storages/inMemory/InMemoryStorageCS.js +10 -7
  7. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +57 -34
  8. package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +3 -3
  9. package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +2 -19
  10. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +4 -4
  11. package/cjs/storages/inRedis/index.js +4 -2
  12. package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +3 -3
  13. package/cjs/storages/pluggable/ImpressionsCachePluggable.js +2 -19
  14. package/cjs/storages/pluggable/TelemetryCachePluggable.js +4 -4
  15. package/cjs/storages/pluggable/inMemoryWrapper.js +8 -6
  16. package/cjs/storages/pluggable/index.js +4 -2
  17. package/cjs/storages/utils.js +73 -0
  18. package/cjs/sync/submitters/submitterManager.js +1 -1
  19. package/cjs/sync/submitters/telemetrySubmitter.js +4 -40
  20. package/cjs/trackers/impressionObserver/utils.js +1 -17
  21. package/cjs/trackers/uniqueKeysTracker.js +1 -1
  22. package/cjs/utils/settingsValidation/index.js +7 -1
  23. package/esm/listeners/browser.js +9 -11
  24. package/esm/sdkFactory/index.js +7 -24
  25. package/esm/storages/KeyBuilderSS.js +1 -37
  26. package/esm/storages/inLocalStorage/index.js +15 -11
  27. package/esm/storages/inMemory/InMemoryStorage.js +10 -7
  28. package/esm/storages/inMemory/InMemoryStorageCS.js +10 -7
  29. package/esm/storages/inMemory/TelemetryCacheInMemory.js +58 -35
  30. package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +3 -3
  31. package/esm/storages/inRedis/ImpressionsCacheInRedis.js +2 -19
  32. package/esm/storages/inRedis/TelemetryCacheInRedis.js +1 -1
  33. package/esm/storages/inRedis/index.js +4 -2
  34. package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +3 -3
  35. package/esm/storages/pluggable/ImpressionsCachePluggable.js +2 -19
  36. package/esm/storages/pluggable/TelemetryCachePluggable.js +1 -1
  37. package/esm/storages/pluggable/inMemoryWrapper.js +8 -6
  38. package/esm/storages/pluggable/index.js +4 -2
  39. package/esm/storages/utils.js +65 -0
  40. package/esm/sync/submitters/submitterManager.js +1 -1
  41. package/esm/sync/submitters/telemetrySubmitter.js +4 -39
  42. package/esm/trackers/impressionObserver/utils.js +1 -15
  43. package/esm/trackers/uniqueKeysTracker.js +1 -1
  44. package/esm/utils/settingsValidation/index.js +7 -1
  45. package/package.json +2 -1
  46. package/src/listeners/browser.ts +9 -13
  47. package/src/sdkClient/sdkClient.ts +1 -1
  48. package/src/sdkFactory/index.ts +7 -29
  49. package/src/sdkFactory/types.ts +2 -2
  50. package/src/services/splitApi.ts +2 -2
  51. package/src/storages/KeyBuilderSS.ts +2 -44
  52. package/src/storages/inLocalStorage/index.ts +16 -11
  53. package/src/storages/inMemory/AttributesCacheInMemory.ts +7 -7
  54. package/src/storages/inMemory/InMemoryStorage.ts +11 -7
  55. package/src/storages/inMemory/InMemoryStorageCS.ts +11 -7
  56. package/src/storages/inMemory/TelemetryCacheInMemory.ts +66 -33
  57. package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +3 -3
  58. package/src/storages/inRedis/ImpressionsCacheInRedis.ts +2 -22
  59. package/src/storages/inRedis/TelemetryCacheInRedis.ts +3 -2
  60. package/src/storages/inRedis/index.ts +4 -1
  61. package/src/storages/pluggable/ImpressionCountsCachePluggable.ts +3 -3
  62. package/src/storages/pluggable/ImpressionsCachePluggable.ts +3 -23
  63. package/src/storages/pluggable/TelemetryCachePluggable.ts +3 -2
  64. package/src/storages/pluggable/inMemoryWrapper.ts +6 -6
  65. package/src/storages/pluggable/index.ts +4 -2
  66. package/src/storages/types.ts +45 -64
  67. package/src/storages/utils.ts +78 -0
  68. package/src/sync/submitters/submitter.ts +2 -2
  69. package/src/sync/submitters/submitterManager.ts +1 -1
  70. package/src/sync/submitters/telemetrySubmitter.ts +5 -41
  71. package/src/sync/submitters/types.ts +7 -5
  72. package/src/trackers/impressionObserver/utils.ts +1 -16
  73. package/src/trackers/impressionsTracker.ts +2 -2
  74. package/src/trackers/strategy/strategyDebug.ts +4 -4
  75. package/src/trackers/strategy/strategyNone.ts +9 -9
  76. package/src/trackers/strategy/strategyOptimized.ts +9 -9
  77. package/src/trackers/uniqueKeysTracker.ts +6 -6
  78. package/src/utils/redis/RedisMock.ts +5 -5
  79. package/src/utils/settingsValidation/index.ts +5 -1
  80. package/types/storages/KeyBuilderSS.d.ts +1 -3
  81. package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +19 -8
  82. package/types/storages/inRedis/ImpressionsCacheInRedis.d.ts +0 -1
  83. package/types/storages/pluggable/ImpressionsCachePluggable.d.ts +1 -2
  84. package/types/storages/types.d.ts +35 -45
  85. package/types/storages/utils.d.ts +8 -0
  86. package/types/sync/submitters/submitter.d.ts +2 -2
  87. package/types/sync/submitters/telemetrySubmitter.d.ts +2 -10
  88. package/types/sync/submitters/types.d.ts +8 -6
  89. package/types/trackers/impressionObserver/utils.d.ts +0 -8
  90. package/types/trackers/strategy/strategyNone.d.ts +2 -2
  91. package/types/trackers/strategy/strategyOptimized.d.ts +2 -2
  92. package/types/trackers/uniqueKeysTracker.d.ts +1 -1
  93. package/cjs/storages/metadataBuilder.js +0 -12
  94. package/esm/storages/metadataBuilder.js +0 -8
  95. package/src/storages/metadataBuilder.ts +0 -11
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ImpressionsCachePluggable = void 0;
4
+ var utils_1 = require("../utils");
4
5
  var ImpressionsCachePluggable = /** @class */ (function () {
5
6
  function ImpressionsCachePluggable(log, key, wrapper, metadata) {
6
7
  this.log = log;
@@ -15,25 +16,7 @@ var ImpressionsCachePluggable = /** @class */ (function () {
15
16
  * or rejected if the wrapper operation fails.
16
17
  */
17
18
  ImpressionsCachePluggable.prototype.track = function (impressions) {
18
- return this.wrapper.pushItems(this.key, this._toJSON(impressions));
19
- };
20
- ImpressionsCachePluggable.prototype._toJSON = function (impressions) {
21
- var _this = this;
22
- return impressions.map(function (impression) {
23
- var keyName = impression.keyName, bucketingKey = impression.bucketingKey, feature = impression.feature, treatment = impression.treatment, label = impression.label, time = impression.time, changeNumber = impression.changeNumber;
24
- return JSON.stringify({
25
- m: _this.metadata,
26
- i: {
27
- k: keyName,
28
- b: bucketingKey,
29
- f: feature,
30
- t: treatment,
31
- r: label,
32
- c: changeNumber,
33
- m: time
34
- }
35
- });
36
- });
19
+ return this.wrapper.pushItems(this.key, (0, utils_1.impressionsToJSON)(impressions, this.metadata));
37
20
  };
38
21
  /**
39
22
  * Returns a promise that resolves with the count of stored impressions, or 0 if there was some error.
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TelemetryCachePluggable = void 0;
4
- var KeyBuilderSS_1 = require("../KeyBuilderSS");
5
4
  var findLatencyIndex_1 = require("../findLatencyIndex");
6
5
  var telemetrySubmitter_1 = require("../../sync/submitters/telemetrySubmitter");
7
6
  var constants_1 = require("../../utils/constants");
8
7
  var lang_1 = require("../../utils/lang");
9
8
  var maps_1 = require("../../utils/lang/maps");
10
9
  var TelemetryCacheInMemory_1 = require("../inMemory/TelemetryCacheInMemory");
10
+ var utils_1 = require("../utils");
11
11
  var TelemetryCachePluggable = /** @class */ (function () {
12
12
  /**
13
13
  * Create a Telemetry cache that uses a storage wrapper.
@@ -44,7 +44,7 @@ var TelemetryCachePluggable = /** @class */ (function () {
44
44
  var result = new maps_1._Map();
45
45
  for (var i = 0; i < latencyKeys.length; i++) {
46
46
  var field = latencyKeys[i].split('::')[1];
47
- var parsedField = (0, KeyBuilderSS_1.parseLatencyField)(field);
47
+ var parsedField = (0, utils_1.parseLatencyField)(field);
48
48
  if ((0, lang_1.isString)(parsedField)) {
49
49
  _this.log.error("Ignoring invalid latency field: " + field + ": " + parsedField);
50
50
  continue;
@@ -88,7 +88,7 @@ var TelemetryCachePluggable = /** @class */ (function () {
88
88
  var result = new maps_1._Map();
89
89
  for (var i = 0; i < exceptionKeys.length; i++) {
90
90
  var field = exceptionKeys[i].split('::')[1];
91
- var parsedField = (0, KeyBuilderSS_1.parseExceptionField)(field);
91
+ var parsedField = (0, utils_1.parseExceptionField)(field);
92
92
  if ((0, lang_1.isString)(parsedField)) {
93
93
  _this.log.error("Ignoring invalid exception field: " + field + ": " + parsedField);
94
94
  continue;
@@ -128,7 +128,7 @@ var TelemetryCachePluggable = /** @class */ (function () {
128
128
  var result = new maps_1._Map();
129
129
  for (var i = 0; i < configKeys.length; i++) {
130
130
  var field = configKeys[i].split('::')[1];
131
- var parsedField = (0, KeyBuilderSS_1.parseMetadata)(field);
131
+ var parsedField = (0, utils_1.parseMetadata)(field);
132
132
  if ((0, lang_1.isString)(parsedField)) {
133
133
  _this.log.error("Ignoring invalid config field: " + field + ": " + parsedField);
134
134
  continue;
@@ -37,29 +37,31 @@ function inMemoryWrapperFactory(connDelay) {
37
37
  getKeysByPrefix: function (prefix) {
38
38
  return Promise.resolve(Object.keys(_cache).filter(function (key) { return (0, lang_1.startsWith)(key, prefix); }));
39
39
  },
40
- incr: function (key) {
40
+ incr: function (key, increment) {
41
+ if (increment === void 0) { increment = 1; }
41
42
  if (key in _cache) {
42
- var count = (0, lang_1.toNumber)(_cache[key]) + 1;
43
+ var count = (0, lang_1.toNumber)(_cache[key]) + increment;
43
44
  if (isNaN(count))
44
45
  return Promise.reject('Given key is not a number');
45
46
  _cache[key] = count + '';
46
47
  return Promise.resolve(count);
47
48
  }
48
49
  else {
49
- _cache[key] = '1';
50
+ _cache[key] = '' + increment;
50
51
  return Promise.resolve(1);
51
52
  }
52
53
  },
53
- decr: function (key) {
54
+ decr: function (key, decrement) {
55
+ if (decrement === void 0) { decrement = 1; }
54
56
  if (key in _cache) {
55
- var count = (0, lang_1.toNumber)(_cache[key]) - 1;
57
+ var count = (0, lang_1.toNumber)(_cache[key]) - decrement;
56
58
  if (isNaN(count))
57
59
  return Promise.reject('Given key is not a number');
58
60
  _cache[key] = count + '';
59
61
  return Promise.resolve(count);
60
62
  }
61
63
  else {
62
- _cache[key] = '-1';
64
+ _cache[key] = '-' + decrement;
63
65
  return Promise.resolve(-1);
64
66
  }
65
67
  },
@@ -20,6 +20,7 @@ var ImpressionCountsCachePluggable_1 = require("./ImpressionCountsCachePluggable
20
20
  var UniqueKeysCachePluggable_1 = require("./UniqueKeysCachePluggable");
21
21
  var UniqueKeysCacheInMemory_1 = require("../inMemory/UniqueKeysCacheInMemory");
22
22
  var UniqueKeysCacheInMemoryCS_1 = require("../inMemory/UniqueKeysCacheInMemoryCS");
23
+ var utils_1 = require("../utils");
23
24
  var NO_VALID_WRAPPER = 'Expecting pluggable storage `wrapper` in options, but no valid wrapper instance was provided.';
24
25
  var NO_VALID_WRAPPER_INTERFACE = 'The provided wrapper instance doesn’t follow the expected interface. Check our docs.';
25
26
  /**
@@ -52,7 +53,8 @@ function PluggableStorage(options) {
52
53
  validatePluggableStorageOptions(options);
53
54
  var prefix = (0, KeyBuilder_1.validatePrefix)(options.prefix);
54
55
  function PluggableStorageFactory(params) {
55
- var log = params.log, metadata = params.metadata, onReadyCb = params.onReadyCb, mode = params.mode, eventsQueueSize = params.eventsQueueSize, impressionsQueueSize = params.impressionsQueueSize, impressionsMode = params.impressionsMode, matchingKey = params.matchingKey;
56
+ var onReadyCb = params.onReadyCb, settings = params.settings, _a = params.settings, log = _a.log, mode = _a.mode, impressionsMode = _a.sync.impressionsMode, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize;
57
+ var metadata = (0, utils_1.metadataBuilder)(settings);
56
58
  var keys = new KeyBuilderSS_1.KeyBuilderSS(prefix, metadata);
57
59
  var wrapper = (0, wrapperAdapter_1.wrapperAdapter)(log, options.wrapper);
58
60
  var isSyncronizer = mode === undefined; // If mode is not defined, the synchronizer is running
@@ -69,7 +71,7 @@ function PluggableStorage(options) {
69
71
  undefined;
70
72
  var uniqueKeysCache = impressionsMode === constants_1.NONE || isSyncronizer ?
71
73
  isPartialConsumer ?
72
- matchingKey === undefined ? new UniqueKeysCacheInMemory_1.UniqueKeysCacheInMemory() : new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS() :
74
+ settings.core.key === undefined ? new UniqueKeysCacheInMemory_1.UniqueKeysCacheInMemory() : new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS() :
73
75
  new UniqueKeysCachePluggable_1.UniqueKeysCachePluggable(log, keys.buildUniqueKeysKey(), wrapper) :
74
76
  undefined;
75
77
  // Connects to wrapper and emits SDK_READY event on main client
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ // Shared utils for Redis and Pluggable storage
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.parseLatencyField = exports.parseExceptionField = exports.parseMetadata = exports.impressionsToJSON = exports.metadataBuilder = void 0;
5
+ var constants_1 = require("../utils/constants");
6
+ var TelemetryCacheInMemory_1 = require("./inMemory/TelemetryCacheInMemory");
7
+ var KeyBuilderSS_1 = require("./KeyBuilderSS");
8
+ function metadataBuilder(settings) {
9
+ return {
10
+ s: settings.version,
11
+ i: settings.runtime.ip || constants_1.UNKNOWN,
12
+ n: settings.runtime.hostname || constants_1.UNKNOWN,
13
+ };
14
+ }
15
+ exports.metadataBuilder = metadataBuilder;
16
+ // Converts impressions to be stored in Redis or pluggable storage.
17
+ function impressionsToJSON(impressions, metadata) {
18
+ return impressions.map(function (impression) {
19
+ var impressionWithMetadata = {
20
+ m: metadata,
21
+ i: {
22
+ k: impression.keyName,
23
+ b: impression.bucketingKey,
24
+ f: impression.feature,
25
+ t: impression.treatment,
26
+ r: impression.label,
27
+ c: impression.changeNumber,
28
+ m: impression.time,
29
+ pt: impression.pt,
30
+ }
31
+ };
32
+ return JSON.stringify(impressionWithMetadata);
33
+ });
34
+ }
35
+ exports.impressionsToJSON = impressionsToJSON;
36
+ // Utilities used by TelemetryCacheInRedis and TelemetryCachePluggable
37
+ var REVERSE_METHOD_NAMES = Object.keys(KeyBuilderSS_1.METHOD_NAMES).reduce(function (acc, key) {
38
+ acc[KeyBuilderSS_1.METHOD_NAMES[key]] = key;
39
+ return acc;
40
+ }, {});
41
+ function parseMetadata(field) {
42
+ var parts = field.split('/');
43
+ if (parts.length !== 3)
44
+ return "invalid subsection count. Expected 3, got: " + parts.length;
45
+ var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */;
46
+ return [JSON.stringify({ s: s, n: n, i: i })];
47
+ }
48
+ exports.parseMetadata = parseMetadata;
49
+ function parseExceptionField(field) {
50
+ var parts = field.split('/');
51
+ if (parts.length !== 4)
52
+ return "invalid subsection count. Expected 4, got: " + parts.length;
53
+ var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */, m = parts[3];
54
+ var method = REVERSE_METHOD_NAMES[m];
55
+ if (!method)
56
+ return "unknown method '" + m + "'";
57
+ return [JSON.stringify({ s: s, n: n, i: i }), method];
58
+ }
59
+ exports.parseExceptionField = parseExceptionField;
60
+ function parseLatencyField(field) {
61
+ var parts = field.split('/');
62
+ if (parts.length !== 5)
63
+ return "invalid subsection count. Expected 5, got: " + parts.length;
64
+ var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */, m = parts[3], b = parts[4];
65
+ var method = REVERSE_METHOD_NAMES[m];
66
+ if (!method)
67
+ return "unknown method '" + m + "'";
68
+ var bucket = parseInt(b);
69
+ if (isNaN(bucket) || bucket >= TelemetryCacheInMemory_1.MAX_LATENCY_BUCKET_COUNT)
70
+ return "invalid bucket. Expected a number between 0 and " + (TelemetryCacheInMemory_1.MAX_LATENCY_BUCKET_COUNT - 1) + ", got: " + b;
71
+ return [JSON.stringify({ s: s, n: n, i: i }), method, bucket];
72
+ }
73
+ exports.parseLatencyField = parseLatencyField;
@@ -15,7 +15,7 @@ function submitterManagerFactory(params) {
15
15
  if (impressionCountsSubmitter)
16
16
  submitters.push(impressionCountsSubmitter);
17
17
  var telemetrySubmitter = (0, telemetrySubmitter_1.telemetrySubmitterFactory)(params);
18
- if (params.uniqueKeysTracker)
18
+ if (params.storage.uniqueKeys)
19
19
  submitters.push((0, uniqueKeysSubmitter_1.uniqueKeysSubmitterFactory)(params));
20
20
  return {
21
21
  // `onlyTelemetry` true if SDK is created with userConsent not GRANTED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a, _b, _c;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.telemetrySubmitterFactory = exports.telemetryCacheConfigAdapter = exports.getTelemetryConfigStats = exports.telemetryCacheStatsAdapter = void 0;
4
+ exports.telemetrySubmitterFactory = exports.telemetryCacheConfigAdapter = exports.getTelemetryConfigStats = void 0;
5
5
  var submitter_1 = require("./submitter");
6
6
  var constants_1 = require("../../utils/constants");
7
7
  var constants_2 = require("../../readiness/constants");
@@ -9,40 +9,6 @@ var settingsValidation_1 = require("../../utils/settingsValidation");
9
9
  var apiKey_1 = require("../../utils/inputValidation/apiKey");
10
10
  var timer_1 = require("../../utils/timeTracker/timer");
11
11
  var objectAssign_1 = require("../../utils/lang/objectAssign");
12
- var utils_1 = require("../../trackers/impressionObserver/utils");
13
- /**
14
- * Converts data from telemetry cache into /metrics/usage request payload.
15
- */
16
- function telemetryCacheStatsAdapter(telemetry, splits, segments) {
17
- return {
18
- isEmpty: function () { return false; },
19
- clear: function () { },
20
- // @TODO consider moving inside telemetry cache for code size reduction
21
- pop: function () {
22
- return {
23
- lS: telemetry.getLastSynchronization(),
24
- mL: telemetry.popLatencies(),
25
- mE: telemetry.popExceptions(),
26
- hE: telemetry.popHttpErrors(),
27
- hL: telemetry.popHttpLatencies(),
28
- tR: telemetry.popTokenRefreshes(),
29
- aR: telemetry.popAuthRejections(),
30
- iQ: telemetry.getImpressionStats(constants_1.QUEUED),
31
- iDe: telemetry.getImpressionStats(constants_1.DEDUPED),
32
- iDr: telemetry.getImpressionStats(constants_1.DROPPED),
33
- spC: splits && splits.getSplitNames().length,
34
- seC: segments && segments.getRegisteredSegments().length,
35
- skC: segments && segments.getKeysCount(),
36
- sL: telemetry.getSessionLength(),
37
- eQ: telemetry.getEventStats(constants_1.QUEUED),
38
- eD: telemetry.getEventStats(constants_1.DROPPED),
39
- sE: telemetry.popStreamingEvents(),
40
- t: telemetry.popTags(),
41
- };
42
- }
43
- };
44
- }
45
- exports.telemetryCacheStatsAdapter = telemetryCacheStatsAdapter;
46
12
  var OPERATION_MODE_MAP = (_a = {},
47
13
  _a[constants_1.STANDALONE_MODE] = constants_1.STANDALONE_ENUM,
48
14
  _a[constants_1.CONSUMER_MODE] = constants_1.CONSUMER_ENUM,
@@ -122,14 +88,12 @@ exports.telemetryCacheConfigAdapter = telemetryCacheConfigAdapter;
122
88
  * Submitter that periodically posts telemetry data
123
89
  */
124
90
  function telemetrySubmitterFactory(params) {
125
- var _a = params.storage, splits = _a.splits, segments = _a.segments, telemetry = _a.telemetry, now = params.platform.now;
91
+ var telemetry = params.storage.telemetry, now = params.platform.now;
126
92
  if (!telemetry || !now)
127
93
  return; // No submitter created if telemetry cache is not defined
128
- var settings = params.settings, _b = params.settings, log = _b.log, telemetryRefreshRate = _b.scheduler.telemetryRefreshRate, splitApi = params.splitApi, readiness = params.readiness, sdkReadinessManager = params.sdkReadinessManager;
94
+ var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate, splitApi = params.splitApi, readiness = params.readiness, sdkReadinessManager = params.sdkReadinessManager;
129
95
  var startTime = (0, timer_1.timer)(now);
130
- var submitter = (0, submitter_1.firstPushWindowDecorator)((0, submitter_1.submitterFactory)(log, splitApi.postMetricsUsage,
131
- // @TODO cannot provide splits and segments cache if they are async, because `submitterFactory` expects a sync storage source
132
- (0, utils_1.isStorageSync)(params.settings) ? telemetryCacheStatsAdapter(telemetry, splits, segments) : telemetryCacheStatsAdapter(telemetry), telemetryRefreshRate, 'telemetry stats', undefined, 0, true), telemetryRefreshRate);
96
+ var submitter = (0, submitter_1.firstPushWindowDecorator)((0, submitter_1.submitterFactory)(log, splitApi.postMetricsUsage, telemetry, telemetryRefreshRate, 'telemetry stats', undefined, 0, true), telemetryRefreshRate);
133
97
  readiness.gate.once(constants_2.SDK_READY_FROM_CACHE, function () {
134
98
  telemetry.recordTimeUntilReadyFromCache(startTime());
135
99
  });
@@ -1,23 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isStorageSync = exports.shouldBeOptimized = exports.shouldAddPt = void 0;
3
+ exports.isStorageSync = void 0;
4
4
  var constants_1 = require("../../utils/constants");
5
- /**
6
- * Checks if impressions previous time should be added or not.
7
- */
8
- function shouldAddPt(settings) {
9
- return [constants_1.PRODUCER_MODE, constants_1.STANDALONE_MODE, constants_1.CONSUMER_PARTIAL_MODE].indexOf(settings.mode) > -1 ? true : false;
10
- }
11
- exports.shouldAddPt = shouldAddPt;
12
- /**
13
- * Checks if it should dedupe impressions or not.
14
- */
15
- function shouldBeOptimized(settings) {
16
- if (!shouldAddPt(settings))
17
- return false;
18
- return settings.sync.impressionsMode === constants_1.OPTIMIZED ? true : false;
19
- }
20
- exports.shouldBeOptimized = shouldBeOptimized;
21
5
  /**
22
6
  * Storage is async if mode is consumer or partial consumer
23
7
  */
@@ -10,7 +10,7 @@ var noopFilterAdapter = {
10
10
  /**
11
11
  * Trackes uniques keys
12
12
  * Unique Keys Tracker will be in charge of checking if the MTK was already sent to the BE in the last period
13
- * or schedule to be sent; if not it will be added in an internal cache and sent in the next post.
13
+ * or schedule to be sent; if not it will be added in an internal cache and sent in the next post.
14
14
  *
15
15
  * @param log Logger instance
16
16
  * @param uniqueKeysCache cache to save unique keys
@@ -132,8 +132,8 @@ function settingsValidation(config, validationParams) {
132
132
  if (storage)
133
133
  withDefaults.storage = storage(withDefaults);
134
134
  // Validate key and TT (for client-side)
135
+ var maybeKey = withDefaults.core.key;
135
136
  if (validationParams.acceptKey) {
136
- var maybeKey = withDefaults.core.key;
137
137
  // Although `key` is required in client-side, it can be omitted in LOCALHOST mode. In that case, the value `localhost_key` is used.
138
138
  if (withDefaults.mode === constants_1.LOCALHOST_MODE && maybeKey === undefined) {
139
139
  withDefaults.core.key = 'localhost_key';
@@ -151,6 +151,12 @@ function settingsValidation(config, validationParams) {
151
151
  }
152
152
  }
153
153
  }
154
+ else {
155
+ // On server-side, key is undefined and used to distinguish from client-side
156
+ if (maybeKey !== undefined)
157
+ log.warn('Provided `key` is ignored in server-side SDK.'); // @ts-ignore
158
+ withDefaults.core.key = undefined;
159
+ }
154
160
  // Current ip/hostname information
155
161
  // @ts-ignore, modify readonly prop
156
162
  withDefaults.runtime = runtime(withDefaults);
@@ -4,7 +4,6 @@ import { OPTIMIZED, DEBUG, NONE } from '../utils/constants';
4
4
  import { objectAssign } from '../utils/lang/objectAssign';
5
5
  import { CLEANUP_REGISTERING, CLEANUP_DEREGISTERING } from '../logger/constants';
6
6
  import { isConsentGranted } from '../consent';
7
- import { telemetryCacheStatsAdapter } from '../sync/submitters/telemetrySubmitter';
8
7
  var VISIBILITYCHANGE_EVENT = 'visibilitychange';
9
8
  var PAGEHIDE_EVENT = 'pagehide';
10
9
  var UNLOAD_EVENT = 'unload';
@@ -68,25 +67,25 @@ var BrowserSignalListener = /** @class */ (function () {
68
67
  BrowserSignalListener.prototype.flushData = function () {
69
68
  if (!this.syncManager)
70
69
  return; // In consumer mode there is not sync manager and data to flush
70
+ var _a = this.settings.urls, events = _a.events, telemetry = _a.telemetry;
71
71
  // Flush impressions & events data if there is user consent
72
72
  if (isConsentGranted(this.settings)) {
73
- var eventsUrl = this.settings.urls.events;
74
73
  var sim = this.settings.sync.impressionsMode;
75
74
  var extraMetadata = {
76
75
  // sim stands for Sync/Split Impressions Mode
77
76
  sim: sim === OPTIMIZED ? OPTIMIZED : sim === DEBUG ? DEBUG : NONE
78
77
  };
79
- this._flushData(eventsUrl + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
80
- this._flushData(eventsUrl + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
78
+ this._flushData(events + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
79
+ this._flushData(events + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
81
80
  if (this.storage.impressionCounts)
82
- this._flushData(eventsUrl + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, fromImpressionCountsCollector);
81
+ this._flushData(events + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, fromImpressionCountsCollector);
82
+ // @ts-ignore
83
+ if (this.storage.uniqueKeys)
84
+ this._flushData(telemetry + '/v1/keys/cs/beacon', this.storage.uniqueKeys, this.serviceApi.postUniqueKeysBulkCs);
83
85
  }
84
86
  // Flush telemetry data
85
- if (this.storage.telemetry) {
86
- var telemetryUrl = this.settings.urls.telemetry;
87
- var telemetryCacheAdapter = telemetryCacheStatsAdapter(this.storage.telemetry, this.storage.splits, this.storage.segments);
88
- this._flushData(telemetryUrl + '/v1/metrics/usage/beacon', telemetryCacheAdapter, this.serviceApi.postMetricsUsage);
89
- }
87
+ if (this.storage.telemetry)
88
+ this._flushData(telemetry + '/v1/metrics/usage/beacon', this.storage.telemetry, this.serviceApi.postMetricsUsage);
90
89
  };
91
90
  BrowserSignalListener.prototype.flushDataIfHidden = function () {
92
91
  // Precondition: document defined
@@ -100,7 +99,6 @@ var BrowserSignalListener = /** @class */ (function () {
100
99
  if (!this._sendBeacon(url, dataPayload, extraMetadata)) {
101
100
  postService(JSON.stringify(dataPayload)).catch(function () { }); // no-op just to catch a possible exception
102
101
  }
103
- cache.clear();
104
102
  }
105
103
  };
106
104
  /**
@@ -2,12 +2,9 @@ import { sdkReadinessManagerFactory } from '../readiness/sdkReadinessManager';
2
2
  import { impressionsTrackerFactory } from '../trackers/impressionsTracker';
3
3
  import { eventTrackerFactory } from '../trackers/eventTracker';
4
4
  import { telemetryTrackerFactory } from '../trackers/telemetryTracker';
5
- import { getMatching } from '../utils/key';
6
- import { shouldBeOptimized } from '../trackers/impressionObserver/utils';
7
5
  import { validateAndTrackApiKey } from '../utils/inputValidation/apiKey';
8
6
  import { createLoggerAPI } from '../logger/sdkLogger';
9
7
  import { NEW_FACTORY, RETRIEVE_MANAGER } from '../logger/constants';
10
- import { metadataBuilder } from '../storages/metadataBuilder';
11
8
  import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
12
9
  import { objectAssign } from '../utils/lang/objectAssign';
13
10
  import { strategyDebugFactory } from '../trackers/strategy/strategyDebug';
@@ -20,43 +17,29 @@ import { NONE, OPTIMIZED } from '../utils/constants';
20
17
  */
21
18
  export function sdkFactory(params) {
22
19
  var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, SignalListener = params.SignalListener, impressionsObserverFactory = params.impressionsObserverFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, filterAdapterFactory = params.filterAdapterFactory;
23
- var log = settings.log;
20
+ var log = settings.log, impressionsMode = settings.sync.impressionsMode;
24
21
  // @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid API Key, etc.
25
22
  // On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
26
23
  // We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
27
24
  validateAndTrackApiKey(log, settings.core.authorizationKey);
28
25
  var sdkReadinessManager = sdkReadinessManagerFactory(log, platform.EventEmitter, settings.startup.readyTimeout);
29
26
  var readiness = sdkReadinessManager.readinessManager;
30
- // @TODO consider passing the settings object, so that each storage access only what it needs
31
- var storageFactoryParams = {
32
- impressionsQueueSize: settings.scheduler.impressionsQueueSize,
33
- eventsQueueSize: settings.scheduler.eventsQueueSize,
34
- optimize: shouldBeOptimized(settings),
35
- // ATM, only used by InLocalStorage
36
- matchingKey: getMatching(settings.core.key),
37
- splitFiltersValidation: settings.sync.__splitFiltersValidation,
38
- // ATM, only used by PluggableStorage
39
- mode: settings.mode,
40
- impressionsMode: settings.sync.impressionsMode,
41
- // Callback used to emit SDK_READY in consumer mode, where `syncManagerFactory` is undefined,
42
- // or partial consumer mode, where it only has submitters, and therefore it doesn't emit readiness events.
27
+ var storage = storageFactory({
28
+ settings: settings,
43
29
  onReadyCb: function (error) {
44
30
  if (error)
45
31
  return; // Don't emit SDK_READY if storage failed to connect. Error message is logged by wrapperAdapter
46
32
  readiness.splits.emit(SDK_SPLITS_ARRIVED);
47
33
  readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
48
34
  },
49
- metadata: metadataBuilder(settings),
50
- log: log
51
- };
52
- var storage = storageFactory(storageFactoryParams);
35
+ });
53
36
  // @TODO add support for dataloader: `if (params.dataLoader) params.dataLoader(storage);`
54
37
  var telemetryTracker = telemetryTrackerFactory(storage.telemetry, platform.now);
55
38
  var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
56
39
  var observer = impressionsObserverFactory();
57
- var uniqueKeysTracker = storageFactoryParams.impressionsMode === NONE ? uniqueKeysTrackerFactory(log, storage.uniqueKeys, filterAdapterFactory && filterAdapterFactory()) : undefined;
40
+ var uniqueKeysTracker = impressionsMode === NONE ? uniqueKeysTrackerFactory(log, storage.uniqueKeys, filterAdapterFactory && filterAdapterFactory()) : undefined;
58
41
  var strategy;
59
- switch (storageFactoryParams.impressionsMode) {
42
+ switch (impressionsMode) {
60
43
  case OPTIMIZED:
61
44
  strategy = strategyOptimizedFactory(observer, storage.impressionCounts);
62
45
  break;
@@ -91,7 +74,7 @@ export function sdkFactory(params) {
91
74
  return managerInstance;
92
75
  },
93
76
  // Logger wrapper API
94
- Logger: createLoggerAPI(settings.log),
77
+ Logger: createLoggerAPI(log),
95
78
  settings: settings,
96
79
  }, extraProps && extraProps(ctx));
97
80
  }
@@ -1,7 +1,6 @@
1
1
  import { __extends } from "tslib";
2
2
  import { KeyBuilder } from './KeyBuilder';
3
- import { MAX_LATENCY_BUCKET_COUNT } from './inMemory/TelemetryCacheInMemory';
4
- var METHOD_NAMES = {
3
+ export var METHOD_NAMES = {
5
4
  t: 'treatment',
6
5
  ts: 'treatments',
7
6
  tc: 'treatmentWithConfig',
@@ -49,38 +48,3 @@ var KeyBuilderSS = /** @class */ (function (_super) {
49
48
  return KeyBuilderSS;
50
49
  }(KeyBuilder));
51
50
  export { KeyBuilderSS };
52
- // Used by consumer methods of TelemetryCacheInRedis and TelemetryCachePluggable
53
- var REVERSE_METHOD_NAMES = Object.keys(METHOD_NAMES).reduce(function (acc, key) {
54
- acc[METHOD_NAMES[key]] = key;
55
- return acc;
56
- }, {});
57
- export function parseMetadata(field) {
58
- var parts = field.split('/');
59
- if (parts.length !== 3)
60
- return "invalid subsection count. Expected 3, got: " + parts.length;
61
- var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */;
62
- return [JSON.stringify({ s: s, n: n, i: i })];
63
- }
64
- export function parseExceptionField(field) {
65
- var parts = field.split('/');
66
- if (parts.length !== 4)
67
- return "invalid subsection count. Expected 4, got: " + parts.length;
68
- var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */, m = parts[3];
69
- var method = REVERSE_METHOD_NAMES[m];
70
- if (!method)
71
- return "unknown method '" + m + "'";
72
- return [JSON.stringify({ s: s, n: n, i: i }), method];
73
- }
74
- export function parseLatencyField(field) {
75
- var parts = field.split('/');
76
- if (parts.length !== 5)
77
- return "invalid subsection count. Expected 5, got: " + parts.length;
78
- var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */, m = parts[3], b = parts[4];
79
- var method = REVERSE_METHOD_NAMES[m];
80
- if (!method)
81
- return "unknown method '" + m + "'";
82
- var bucket = parseInt(b);
83
- if (isNaN(bucket) || bucket >= MAX_LATENCY_BUCKET_COUNT)
84
- return "invalid bucket. Expected a number between 0 and " + (MAX_LATENCY_BUCKET_COUNT - 1) + ", got: " + b;
85
- return [JSON.stringify({ s: s, n: n, i: i }), method, bucket];
86
- }
@@ -11,9 +11,10 @@ import { SplitsCacheInMemory } from '../inMemory/SplitsCacheInMemory';
11
11
  import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../../utils/constants/browser';
12
12
  import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
13
13
  import { LOG_PREFIX } from './constants';
14
- import { NONE, STORAGE_LOCALSTORAGE } from '../../utils/constants';
14
+ import { DEBUG, NONE, STORAGE_LOCALSTORAGE } from '../../utils/constants';
15
15
  import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
16
16
  import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
17
+ import { getMatching } from '../../utils/key';
17
18
  /**
18
19
  * InLocal storage factory for standalone client-side SplitFactory
19
20
  */
@@ -23,20 +24,23 @@ export function InLocalStorage(options) {
23
24
  function InLocalStorageCSFactory(params) {
24
25
  // Fallback to InMemoryStorage if LocalStorage API is not available
25
26
  if (!isLocalStorageAvailable()) {
26
- params.log.warn(LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
27
+ params.settings.log.warn(LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
27
28
  return InMemoryStorageCSFactory(params);
28
29
  }
29
- var log = params.log;
30
- var keys = new KeyBuilderCS(prefix, params.matchingKey);
30
+ var settings = params.settings, _a = params.settings, log = _a.log, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, _c = _a.sync, impressionsMode = _c.impressionsMode, __splitFiltersValidation = _c.__splitFiltersValidation;
31
+ var matchingKey = getMatching(settings.core.key);
32
+ var keys = new KeyBuilderCS(prefix, matchingKey);
31
33
  var expirationTimestamp = Date.now() - DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
34
+ var splits = new SplitsCacheInLocal(log, keys, expirationTimestamp, __splitFiltersValidation);
35
+ var segments = new MySegmentsCacheInLocal(log, keys);
32
36
  return {
33
- splits: new SplitsCacheInLocal(log, keys, expirationTimestamp, params.splitFiltersValidation),
34
- segments: new MySegmentsCacheInLocal(log, keys),
35
- impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
36
- impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
37
- events: new EventsCacheInMemory(params.eventsQueueSize),
38
- telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory() : undefined,
39
- uniqueKeys: params.impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
37
+ splits: splits,
38
+ segments: segments,
39
+ impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
40
+ impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
41
+ events: new EventsCacheInMemory(eventsQueueSize),
42
+ telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
43
+ uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
40
44
  destroy: function () {
41
45
  var _a;
42
46
  this.splits = new SplitsCacheInMemory();
@@ -12,14 +12,17 @@ import { UniqueKeysCacheInMemory } from './UniqueKeysCacheInMemory';
12
12
  * @param params parameters required by EventsCacheSync
13
13
  */
14
14
  export function InMemoryStorageFactory(params) {
15
+ var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, impressionsMode = _a.sync.impressionsMode;
16
+ var splits = new SplitsCacheInMemory();
17
+ var segments = new SegmentsCacheInMemory();
15
18
  return {
16
- splits: new SplitsCacheInMemory(),
17
- segments: new SegmentsCacheInMemory(),
18
- impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
19
- impressionCounts: params.impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
20
- events: new EventsCacheInMemory(params.eventsQueueSize),
21
- telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory() : undefined,
22
- uniqueKeys: params.impressionsMode === NONE ? new UniqueKeysCacheInMemory() : undefined,
19
+ splits: splits,
20
+ segments: segments,
21
+ impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
22
+ impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
23
+ events: new EventsCacheInMemory(eventsQueueSize),
24
+ telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
25
+ uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemory() : undefined,
23
26
  // When using MEMORY we should clean all the caches to leave them empty
24
27
  destroy: function () {
25
28
  var _a;
@@ -12,14 +12,17 @@ import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
12
12
  * @param params parameters required by EventsCacheSync
13
13
  */
14
14
  export function InMemoryStorageCSFactory(params) {
15
+ var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, impressionsMode = _a.sync.impressionsMode;
16
+ var splits = new SplitsCacheInMemory();
17
+ var segments = new MySegmentsCacheInMemory();
15
18
  return {
16
- splits: new SplitsCacheInMemory(),
17
- segments: new MySegmentsCacheInMemory(),
18
- impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
19
- impressionCounts: params.impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
20
- events: new EventsCacheInMemory(params.eventsQueueSize),
21
- telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory() : undefined,
22
- uniqueKeys: params.impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
19
+ splits: splits,
20
+ segments: segments,
21
+ impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
22
+ impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
23
+ events: new EventsCacheInMemory(eventsQueueSize),
24
+ telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
25
+ uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
23
26
  // When using MEMORY we should clean all the caches to leave them empty
24
27
  destroy: function () {
25
28
  var _a;