@splitsoftware/splitio-commons 1.8.2-rc.1 → 1.8.2-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGES.txt CHANGED
@@ -1,42 +1,44 @@
1
- 1.8.2 (May 12, 2023)
2
- - Updated README file, code comments and log messages, to replace the terms "split" with "feature flag", "API Key" with "SDK Key" and "Split Web console" with "Split user interface", for improved clarity and consistency with industry terminology.
1
+ 1.8.2 (May 15, 2023)
2
+ - Updated terminology on the SDKs codebase to be more aligned with current standard without causing a breaking change. The core change is the term split for feature flag on things like logs and intensense comments.
3
+ - Updated split storage modules to optimize some operations when using Redis and pluggable storages.
4
+ - Updated some transitive dependencies for vulnerability fixes.
3
5
 
4
6
  1.8.1 (February 7, 2023)
5
- - Updated a module import to remove a trailing comma that can cause issues with some bundlers.
7
+ - Updated a module import to remove a trailing comma that can cause issues with some bundlers.
6
8
 
7
9
  1.8.0 (February 3, 2023)
8
- - Added flush data method to client
10
+ - Added flush data method to client.
9
11
 
10
12
  1.7.3 (December 16, 2022)
11
- - Updated unique keys cache for Redis and Pluggable storages to optimize the usage of the underlying storage.
12
- - Updated some transitive dependencies for vulnerability fixes.
13
- - Bugfixing - Updated events and impressions cache in localhost mode in order to avoid memory leaks (Related to issue https://github.com/splitio/javascript-commons/issues/181).
13
+ - Updated unique keys cache for Redis and Pluggable storages to optimize the usage of the underlying storage.
14
+ - Updated some transitive dependencies for vulnerability fixes.
15
+ - Bugfixing - Updated events and impressions cache in localhost mode in order to avoid memory leaks (Related to issue https://github.com/splitio/javascript-commons/issues/181).
14
16
 
15
17
  1.7.2 (October 14, 2022)
16
- - Bugfixing - Handle `Navigator.sendBeacon` API exceptions in the browser, and fallback to regular Fetch/XHR transport in case of error.
18
+ - Bugfixing - Handle `Navigator.sendBeacon` API exceptions in the browser, and fallback to regular Fetch/XHR transport in case of error.
17
19
 
18
20
  1.7.1 (October 5, 2022)
19
- - Updated default value of `scheduler.featuresRefreshRate` config parameter to 60 seconds.
21
+ - Updated default value of `scheduler.featuresRefreshRate` config parameter to 60 seconds.
20
22
 
21
23
  1.7.0 (October 4, 2022)
22
- - Added a new impressions mode for the SDK called NONE, to be used in factory when there is no desire to capture impressions on an SDK factory to feed Split's analytics engine. Running NONE mode, the SDK will only capture unique keys evaluated for a particular feature flag instead of full blown impressions.
23
- - Updated SDK telemetry to support pluggable storage, partial consumer mode, and synchronizer.
24
- - Updated storage implementations to improve the performance of feature flag evaluations (i.e., `getTreatment(s)` method calls) when using the default storage in memory.
25
- - Updated evaluation flow to avoid unnecessarily storage calls when the SDK is not ready.
24
+ - Added a new impressions mode for the SDK called NONE, to be used in factory when there is no desire to capture impressions on an SDK factory to feed Split's analytics engine. Running NONE mode, the SDK will only capture unique keys evaluated for a particular feature flag instead of full blown impressions.
25
+ - Updated SDK telemetry to support pluggable storage, partial consumer mode, and synchronizer.
26
+ - Updated storage implementations to improve the performance of feature flag evaluations (i.e., `getTreatment(s)` method calls) when using the default storage in memory.
27
+ - Updated evaluation flow to avoid unnecessarily storage calls when the SDK is not ready.
26
28
 
27
29
  1.6.1 (July 22, 2022)
28
- - Updated GoogleAnalyticsToSplit integration to validate `autoRequire` config parameter and avoid some wrong warning logs when mapping GA hit fields to Split event properties.
30
+ - Updated GoogleAnalyticsToSplit integration to validate `autoRequire` config parameter and avoid some wrong warning logs when mapping GA hit fields to Split event properties.
29
31
 
30
32
  1.6.0 (July 21, 2022)
31
- - Added `autoRequire` configuration option to the Google Analytics to Split integration, which takes care of requiring the splitTracker plugin on trackers dynamically created by Google tag managers (See https://help.split.io/hc/en-us/articles/360040838752#set-up-with-gtm-and-gtag.js).
32
- - Updated browser listener to push remaining impressions and events on 'visibilitychange' and 'pagehide' DOM events, instead of 'unload', which is not reliable in modern mobile and desktop Web browsers.
33
- - Updated the synchronization flow to be more reliable in the event of an edge case generating delay in cache purge propagation, keeping the SDK cache properly synced.
34
- - Bugfixing - Removed js-yaml dependency to avoid resolution to an incompatible version on certain npm versions when installing third-party dependencies that also define js-yaml as transitive dependency (Related to issue https://github.com/splitio/javascript-client/issues/662).
33
+ - Added `autoRequire` configuration option to the Google Analytics to Split integration, which takes care of requiring the splitTracker plugin on trackers dynamically created by Google tag managers (See https://help.split.io/hc/en-us/articles/360040838752#set-up-with-gtm-and-gtag.js).
34
+ - Updated browser listener to push remaining impressions and events on 'visibilitychange' and 'pagehide' DOM events, instead of 'unload', which is not reliable in modern mobile and desktop Web browsers.
35
+ - Updated the synchronization flow to be more reliable in the event of an edge case generating delay in cache purge propagation, keeping the SDK cache properly synced.
36
+ - Bugfixing - Removed js-yaml dependency to avoid resolution to an incompatible version on certain npm versions when installing third-party dependencies that also define js-yaml as transitive dependency (Related to issue https://github.com/splitio/javascript-client/issues/662).
35
37
 
36
38
  1.5.0 (June 29, 2022)
37
- - Added a new config option to control the tasks that listen or poll for updates on feature flags and segments, via the new config sync.enabled . Running online, Split SDK will always pull the most recent updates upon initialization, this only affects updates fetching on a running instance. Useful when a consistent session experience is a must or to save resources when updates are not being used.
38
- - Updated telemetry logic to track the anonymous config for user consent flag set to declined or unknown.
39
- - Updated submitters logic, to avoid duplicating the post of impressions to Split cloud when the SDK is destroyed while its periodic post of impressions is running.
39
+ - Added a new config option to control the tasks that listen or poll for updates on feature flags and segments, via the new config sync.enabled . Running online, Split SDK will always pull the most recent updates upon initialization, this only affects updates fetching on a running instance. Useful when a consistent session experience is a must or to save resources when updates are not being used.
40
+ - Updated telemetry logic to track the anonymous config for user consent flag set to declined or unknown.
41
+ - Updated submitters logic, to avoid duplicating the post of impressions to Split cloud when the SDK is destroyed while its periodic post of impressions is running.
40
42
 
41
43
  1.4.1 (June 13, 2022)
42
44
  - Bugfixing - Updated submitters logic, to avoid dropping impressions and events that are being tracked while POST request is pending.
@@ -20,6 +20,7 @@ function splitApiFactory(settings, platform, telemetryTracker) {
20
20
  var SplitSDKImpressionsMode = settings.sync.impressionsMode;
21
21
  var splitHttpClient = (0, splitHttpClient_1.splitHttpClientFactory)(settings, platform.getFetch, platform.getOptions);
22
22
  return {
23
+ // @TODO throw errors if health check requests fail, to log them in the Synchronizer
23
24
  getSdkAPIHealthCheck: function () {
24
25
  var url = urls.sdk + "/version";
25
26
  return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
@@ -37,10 +37,8 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
37
37
  SplitsCacheInLocal.prototype._decrementCounts = function (split) {
38
38
  try {
39
39
  if (split) {
40
- if (split.trafficTypeName) {
41
- var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
42
- this._decrementCount(ttKey);
43
- }
40
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
41
+ this._decrementCount(ttKey);
44
42
  if ((0, AbstractSplitsCacheSync_1.usesSegments)(split)) {
45
43
  var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
46
44
  this._decrementCount(segmentsCountKey);
@@ -54,11 +52,9 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
54
52
  SplitsCacheInLocal.prototype._incrementCounts = function (split) {
55
53
  try {
56
54
  if (split) {
57
- if (split.trafficTypeName) {
58
- var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
59
- // @ts-expect-error
60
- localStorage.setItem(ttKey, (0, lang_1.toNumber)(localStorage.getItem(ttKey)) + 1);
61
- }
55
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
56
+ // @ts-expect-error
57
+ localStorage.setItem(ttKey, (0, lang_1.toNumber)(localStorage.getItem(ttKey)) + 1);
62
58
  if ((0, AbstractSplitsCacheSync_1.usesSegments)(split)) {
63
59
  var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
64
60
  // @ts-expect-error
@@ -95,9 +91,9 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
95
91
  var splitKey = this.keys.buildSplitKey(name);
96
92
  var splitFromLocalStorage = localStorage.getItem(splitKey);
97
93
  var previousSplit = splitFromLocalStorage ? JSON.parse(splitFromLocalStorage) : null;
98
- this._decrementCounts(previousSplit);
99
94
  localStorage.setItem(splitKey, JSON.stringify(split));
100
95
  this._incrementCounts(split);
96
+ this._decrementCounts(previousSplit);
101
97
  return true;
102
98
  }
103
99
  catch (e) {
@@ -27,12 +27,10 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
27
27
  SplitsCacheInMemory.prototype.addSplit = function (name, split) {
28
28
  var previousSplit = this.getSplit(name);
29
29
  if (previousSplit) { // We had this Split already
30
- if (previousSplit.trafficTypeName) {
31
- var previousTtName = previousSplit.trafficTypeName;
32
- this.ttCache[previousTtName]--;
33
- if (!this.ttCache[previousTtName])
34
- delete this.ttCache[previousTtName];
35
- }
30
+ var previousTtName = previousSplit.trafficTypeName;
31
+ this.ttCache[previousTtName]--;
32
+ if (!this.ttCache[previousTtName])
33
+ delete this.ttCache[previousTtName];
36
34
  if ((0, AbstractSplitsCacheSync_1.usesSegments)(previousSplit)) { // Substract from segments count for the previous version of this Split.
37
35
  this.splitsWithSegmentsCount--;
38
36
  }
@@ -42,11 +40,7 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
42
40
  this.splitsCache[name] = split;
43
41
  // Update TT cache
44
42
  var ttName = split.trafficTypeName;
45
- if (ttName) { // safeguard
46
- if (!this.ttCache[ttName])
47
- this.ttCache[ttName] = 0;
48
- this.ttCache[ttName]++;
49
- }
43
+ this.ttCache[ttName] = (this.ttCache[ttName] || 0) + 1;
50
44
  // Add to segments count for the new version of the Split
51
45
  if ((0, AbstractSplitsCacheSync_1.usesSegments)(split))
52
46
  this.splitsWithSegmentsCount++;
@@ -62,11 +56,9 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
62
56
  // Delete the Split
63
57
  delete this.splitsCache[name];
64
58
  var ttName = split.trafficTypeName;
65
- if (ttName) { // safeguard
66
- this.ttCache[ttName]--; // Update tt cache
67
- if (!this.ttCache[ttName])
68
- delete this.ttCache[ttName];
69
- }
59
+ this.ttCache[ttName]--; // Update tt cache
60
+ if (!this.ttCache[ttName])
61
+ delete this.ttCache[ttName];
70
62
  // Update the segments count.
71
63
  if ((0, AbstractSplitsCacheSync_1.usesSegments)(split))
72
64
  this.splitsWithSegmentsCount--;
@@ -38,19 +38,15 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
38
38
  }
39
39
  SplitsCacheInRedis.prototype._decrementCounts = function (split) {
40
40
  var _this = this;
41
- if (split.trafficTypeName) {
42
- var ttKey_1 = this.keys.buildTrafficTypeKey(split.trafficTypeName);
43
- return this.redis.decr(ttKey_1).then(function (count) {
44
- if (count === 0)
45
- return _this.redis.del(ttKey_1);
46
- });
47
- }
41
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
42
+ return this.redis.decr(ttKey).then(function (count) {
43
+ if (count === 0)
44
+ return _this.redis.del(ttKey);
45
+ });
48
46
  };
49
47
  SplitsCacheInRedis.prototype._incrementCounts = function (split) {
50
- if (split.trafficTypeName) {
51
- var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
52
- return this.redis.incr(ttKey);
53
- }
48
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
49
+ return this.redis.incr(ttKey);
54
50
  };
55
51
  /**
56
52
  * Add a given split.
@@ -70,16 +66,17 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
70
66
  catch (e) {
71
67
  throw new Error('Error parsing feature flag definition: ' + e);
72
68
  }
73
- return Promise.all([
74
- _this.redis.set(splitKey, newStringifiedSplit),
75
- _this._incrementCounts(split),
76
- // If it's an update, we decrement the traffic type of the existing split,
77
- parsedPreviousSplit && _this._decrementCounts(parsedPreviousSplit)
78
- ]);
79
- }).then(function (_a) {
80
- var status = _a[0];
81
- return status === 'OK';
82
- });
69
+ return _this.redis.set(splitKey, newStringifiedSplit).then(function () {
70
+ // avoid unnecessary increment/decrement operations
71
+ if (parsedPreviousSplit && parsedPreviousSplit.trafficTypeName === split.trafficTypeName)
72
+ return;
73
+ // update traffic type counts
74
+ return _this._incrementCounts(split).then(function () {
75
+ if (parsedPreviousSplit)
76
+ return _this._decrementCounts(parsedPreviousSplit);
77
+ });
78
+ });
79
+ }).then(function () { return true; });
83
80
  };
84
81
  /**
85
82
  * Add a list of splits.
@@ -25,19 +25,15 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
25
25
  }
26
26
  SplitsCachePluggable.prototype._decrementCounts = function (split) {
27
27
  var _this = this;
28
- if (split.trafficTypeName) {
29
- var ttKey_1 = this.keys.buildTrafficTypeKey(split.trafficTypeName);
30
- return this.wrapper.decr(ttKey_1).then(function (count) {
31
- if (count === 0)
32
- return _this.wrapper.del(ttKey_1);
33
- });
34
- }
28
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
29
+ return this.wrapper.decr(ttKey).then(function (count) {
30
+ if (count === 0)
31
+ return _this.wrapper.del(ttKey);
32
+ });
35
33
  };
36
34
  SplitsCachePluggable.prototype._incrementCounts = function (split) {
37
- if (split.trafficTypeName) {
38
- var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
39
- return this.wrapper.incr(ttKey);
40
- }
35
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
36
+ return this.wrapper.incr(ttKey);
41
37
  };
42
38
  /**
43
39
  * Add a given split.
@@ -57,12 +53,16 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
57
53
  catch (e) {
58
54
  throw new Error('Error parsing feature flag definition: ' + e);
59
55
  }
60
- return Promise.all([
61
- _this.wrapper.set(splitKey, stringifiedNewSplit),
62
- _this._incrementCounts(split),
63
- // If it's an update, we decrement the traffic type and segment count of the existing split,
64
- parsedPreviousSplit && _this._decrementCounts(parsedPreviousSplit)
65
- ]);
56
+ return _this.wrapper.set(splitKey, stringifiedNewSplit).then(function () {
57
+ // avoid unnecessary increment/decrement operations
58
+ if (parsedPreviousSplit && parsedPreviousSplit.trafficTypeName === split.trafficTypeName)
59
+ return;
60
+ // update traffic type counts
61
+ return _this._incrementCounts(split).then(function () {
62
+ if (parsedPreviousSplit)
63
+ return _this._decrementCounts(parsedPreviousSplit);
64
+ });
65
+ });
66
66
  }).then(function () { return true; });
67
67
  };
68
68
  /**
@@ -17,6 +17,7 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
17
17
  var SplitSDKImpressionsMode = settings.sync.impressionsMode;
18
18
  var splitHttpClient = splitHttpClientFactory(settings, platform.getFetch, platform.getOptions);
19
19
  return {
20
+ // @TODO throw errors if health check requests fail, to log them in the Synchronizer
20
21
  getSdkAPIHealthCheck: function () {
21
22
  var url = urls.sdk + "/version";
22
23
  return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
@@ -34,10 +34,8 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
34
34
  SplitsCacheInLocal.prototype._decrementCounts = function (split) {
35
35
  try {
36
36
  if (split) {
37
- if (split.trafficTypeName) {
38
- var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
39
- this._decrementCount(ttKey);
40
- }
37
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
38
+ this._decrementCount(ttKey);
41
39
  if (usesSegments(split)) {
42
40
  var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
43
41
  this._decrementCount(segmentsCountKey);
@@ -51,11 +49,9 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
51
49
  SplitsCacheInLocal.prototype._incrementCounts = function (split) {
52
50
  try {
53
51
  if (split) {
54
- if (split.trafficTypeName) {
55
- var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
56
- // @ts-expect-error
57
- localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
58
- }
52
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
53
+ // @ts-expect-error
54
+ localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
59
55
  if (usesSegments(split)) {
60
56
  var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
61
57
  // @ts-expect-error
@@ -92,9 +88,9 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
92
88
  var splitKey = this.keys.buildSplitKey(name);
93
89
  var splitFromLocalStorage = localStorage.getItem(splitKey);
94
90
  var previousSplit = splitFromLocalStorage ? JSON.parse(splitFromLocalStorage) : null;
95
- this._decrementCounts(previousSplit);
96
91
  localStorage.setItem(splitKey, JSON.stringify(split));
97
92
  this._incrementCounts(split);
93
+ this._decrementCounts(previousSplit);
98
94
  return true;
99
95
  }
100
96
  catch (e) {
@@ -24,12 +24,10 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
24
24
  SplitsCacheInMemory.prototype.addSplit = function (name, split) {
25
25
  var previousSplit = this.getSplit(name);
26
26
  if (previousSplit) { // We had this Split already
27
- if (previousSplit.trafficTypeName) {
28
- var previousTtName = previousSplit.trafficTypeName;
29
- this.ttCache[previousTtName]--;
30
- if (!this.ttCache[previousTtName])
31
- delete this.ttCache[previousTtName];
32
- }
27
+ var previousTtName = previousSplit.trafficTypeName;
28
+ this.ttCache[previousTtName]--;
29
+ if (!this.ttCache[previousTtName])
30
+ delete this.ttCache[previousTtName];
33
31
  if (usesSegments(previousSplit)) { // Substract from segments count for the previous version of this Split.
34
32
  this.splitsWithSegmentsCount--;
35
33
  }
@@ -39,11 +37,7 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
39
37
  this.splitsCache[name] = split;
40
38
  // Update TT cache
41
39
  var ttName = split.trafficTypeName;
42
- if (ttName) { // safeguard
43
- if (!this.ttCache[ttName])
44
- this.ttCache[ttName] = 0;
45
- this.ttCache[ttName]++;
46
- }
40
+ this.ttCache[ttName] = (this.ttCache[ttName] || 0) + 1;
47
41
  // Add to segments count for the new version of the Split
48
42
  if (usesSegments(split))
49
43
  this.splitsWithSegmentsCount++;
@@ -59,11 +53,9 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
59
53
  // Delete the Split
60
54
  delete this.splitsCache[name];
61
55
  var ttName = split.trafficTypeName;
62
- if (ttName) { // safeguard
63
- this.ttCache[ttName]--; // Update tt cache
64
- if (!this.ttCache[ttName])
65
- delete this.ttCache[ttName];
66
- }
56
+ this.ttCache[ttName]--; // Update tt cache
57
+ if (!this.ttCache[ttName])
58
+ delete this.ttCache[ttName];
67
59
  // Update the segments count.
68
60
  if (usesSegments(split))
69
61
  this.splitsWithSegmentsCount--;
@@ -35,19 +35,15 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
35
35
  }
36
36
  SplitsCacheInRedis.prototype._decrementCounts = function (split) {
37
37
  var _this = this;
38
- if (split.trafficTypeName) {
39
- var ttKey_1 = this.keys.buildTrafficTypeKey(split.trafficTypeName);
40
- return this.redis.decr(ttKey_1).then(function (count) {
41
- if (count === 0)
42
- return _this.redis.del(ttKey_1);
43
- });
44
- }
38
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
39
+ return this.redis.decr(ttKey).then(function (count) {
40
+ if (count === 0)
41
+ return _this.redis.del(ttKey);
42
+ });
45
43
  };
46
44
  SplitsCacheInRedis.prototype._incrementCounts = function (split) {
47
- if (split.trafficTypeName) {
48
- var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
49
- return this.redis.incr(ttKey);
50
- }
45
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
46
+ return this.redis.incr(ttKey);
51
47
  };
52
48
  /**
53
49
  * Add a given split.
@@ -67,16 +63,17 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
67
63
  catch (e) {
68
64
  throw new Error('Error parsing feature flag definition: ' + e);
69
65
  }
70
- return Promise.all([
71
- _this.redis.set(splitKey, newStringifiedSplit),
72
- _this._incrementCounts(split),
73
- // If it's an update, we decrement the traffic type of the existing split,
74
- parsedPreviousSplit && _this._decrementCounts(parsedPreviousSplit)
75
- ]);
76
- }).then(function (_a) {
77
- var status = _a[0];
78
- return status === 'OK';
79
- });
66
+ return _this.redis.set(splitKey, newStringifiedSplit).then(function () {
67
+ // avoid unnecessary increment/decrement operations
68
+ if (parsedPreviousSplit && parsedPreviousSplit.trafficTypeName === split.trafficTypeName)
69
+ return;
70
+ // update traffic type counts
71
+ return _this._incrementCounts(split).then(function () {
72
+ if (parsedPreviousSplit)
73
+ return _this._decrementCounts(parsedPreviousSplit);
74
+ });
75
+ });
76
+ }).then(function () { return true; });
80
77
  };
81
78
  /**
82
79
  * Add a list of splits.
@@ -22,19 +22,15 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
22
22
  }
23
23
  SplitsCachePluggable.prototype._decrementCounts = function (split) {
24
24
  var _this = this;
25
- if (split.trafficTypeName) {
26
- var ttKey_1 = this.keys.buildTrafficTypeKey(split.trafficTypeName);
27
- return this.wrapper.decr(ttKey_1).then(function (count) {
28
- if (count === 0)
29
- return _this.wrapper.del(ttKey_1);
30
- });
31
- }
25
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
26
+ return this.wrapper.decr(ttKey).then(function (count) {
27
+ if (count === 0)
28
+ return _this.wrapper.del(ttKey);
29
+ });
32
30
  };
33
31
  SplitsCachePluggable.prototype._incrementCounts = function (split) {
34
- if (split.trafficTypeName) {
35
- var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
36
- return this.wrapper.incr(ttKey);
37
- }
32
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
33
+ return this.wrapper.incr(ttKey);
38
34
  };
39
35
  /**
40
36
  * Add a given split.
@@ -54,12 +50,16 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
54
50
  catch (e) {
55
51
  throw new Error('Error parsing feature flag definition: ' + e);
56
52
  }
57
- return Promise.all([
58
- _this.wrapper.set(splitKey, stringifiedNewSplit),
59
- _this._incrementCounts(split),
60
- // If it's an update, we decrement the traffic type and segment count of the existing split,
61
- parsedPreviousSplit && _this._decrementCounts(parsedPreviousSplit)
62
- ]);
53
+ return _this.wrapper.set(splitKey, stringifiedNewSplit).then(function () {
54
+ // avoid unnecessary increment/decrement operations
55
+ if (parsedPreviousSplit && parsedPreviousSplit.trafficTypeName === split.trafficTypeName)
56
+ return;
57
+ // update traffic type counts
58
+ return _this._incrementCounts(split).then(function () {
59
+ if (parsedPreviousSplit)
60
+ return _this._decrementCounts(parsedPreviousSplit);
61
+ });
62
+ });
63
63
  }).then(function () { return true; });
64
64
  };
65
65
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "1.8.2-rc.1",
3
+ "version": "1.8.2-rc.2",
4
4
  "description": "Split Javascript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
@@ -30,6 +30,7 @@ export function splitApiFactory(
30
30
  const splitHttpClient = splitHttpClientFactory(settings, platform.getFetch, platform.getOptions);
31
31
 
32
32
  return {
33
+ // @TODO throw errors if health check requests fail, to log them in the Synchronizer
33
34
  getSdkAPIHealthCheck() {
34
35
  const url = `${urls.sdk}/version`;
35
36
  return splitHttpClient(url).then(() => true).catch(() => false);
@@ -41,10 +41,8 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
41
41
  private _decrementCounts(split: ISplit | null) {
42
42
  try {
43
43
  if (split) {
44
- if (split.trafficTypeName) {
45
- const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
46
- this._decrementCount(ttKey);
47
- }
44
+ const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
45
+ this._decrementCount(ttKey);
48
46
 
49
47
  if (usesSegments(split)) {
50
48
  const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
@@ -59,11 +57,9 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
59
57
  private _incrementCounts(split: ISplit) {
60
58
  try {
61
59
  if (split) {
62
- if (split.trafficTypeName) {
63
- const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
64
- // @ts-expect-error
65
- localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
66
- }
60
+ const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
61
+ // @ts-expect-error
62
+ localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
67
63
 
68
64
  if (usesSegments(split)) {
69
65
  const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
@@ -104,11 +100,11 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
104
100
  const splitKey = this.keys.buildSplitKey(name);
105
101
  const splitFromLocalStorage = localStorage.getItem(splitKey);
106
102
  const previousSplit = splitFromLocalStorage ? JSON.parse(splitFromLocalStorage) : null;
107
- this._decrementCounts(previousSplit);
108
103
 
109
104
  localStorage.setItem(splitKey, JSON.stringify(split));
110
105
 
111
106
  this._incrementCounts(split);
107
+ this._decrementCounts(previousSplit);
112
108
 
113
109
  return true;
114
110
  } catch (e) {
@@ -24,11 +24,9 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
24
24
  const previousSplit = this.getSplit(name);
25
25
  if (previousSplit) { // We had this Split already
26
26
 
27
- if (previousSplit.trafficTypeName) {
28
- const previousTtName = previousSplit.trafficTypeName;
29
- this.ttCache[previousTtName]--;
30
- if (!this.ttCache[previousTtName]) delete this.ttCache[previousTtName];
31
- }
27
+ const previousTtName = previousSplit.trafficTypeName;
28
+ this.ttCache[previousTtName]--;
29
+ if (!this.ttCache[previousTtName]) delete this.ttCache[previousTtName];
32
30
 
33
31
  if (usesSegments(previousSplit)) { // Substract from segments count for the previous version of this Split.
34
32
  this.splitsWithSegmentsCount--;
@@ -40,10 +38,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
40
38
  this.splitsCache[name] = split;
41
39
  // Update TT cache
42
40
  const ttName = split.trafficTypeName;
43
- if (ttName) { // safeguard
44
- if (!this.ttCache[ttName]) this.ttCache[ttName] = 0;
45
- this.ttCache[ttName]++;
46
- }
41
+ this.ttCache[ttName] = (this.ttCache[ttName] || 0) + 1;
47
42
 
48
43
  // Add to segments count for the new version of the Split
49
44
  if (usesSegments(split)) this.splitsWithSegmentsCount++;
@@ -61,11 +56,8 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
61
56
  delete this.splitsCache[name];
62
57
 
63
58
  const ttName = split.trafficTypeName;
64
-
65
- if (ttName) { // safeguard
66
- this.ttCache[ttName]--; // Update tt cache
67
- if (!this.ttCache[ttName]) delete this.ttCache[ttName];
68
- }
59
+ this.ttCache[ttName]--; // Update tt cache
60
+ if (!this.ttCache[ttName]) delete this.ttCache[ttName];
69
61
 
70
62
  // Update the segments count.
71
63
  if (usesSegments(split)) this.splitsWithSegmentsCount--;
@@ -45,19 +45,15 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
45
45
  }
46
46
 
47
47
  private _decrementCounts(split: ISplit) {
48
- if (split.trafficTypeName) {
49
- const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
50
- return this.redis.decr(ttKey).then(count => {
51
- if (count === 0) return this.redis.del(ttKey);
52
- });
53
- }
48
+ const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
49
+ return this.redis.decr(ttKey).then(count => {
50
+ if (count === 0) return this.redis.del(ttKey);
51
+ });
54
52
  }
55
53
 
56
54
  private _incrementCounts(split: ISplit) {
57
- if (split.trafficTypeName) {
58
- const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
59
- return this.redis.incr(ttKey);
60
- }
55
+ const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
56
+ return this.redis.incr(ttKey);
61
57
  }
62
58
 
63
59
  /**
@@ -70,7 +66,7 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
70
66
  return this.redis.get(splitKey).then(splitFromStorage => {
71
67
 
72
68
  // handling parsing errors
73
- let parsedPreviousSplit, newStringifiedSplit;
69
+ let parsedPreviousSplit: ISplit, newStringifiedSplit;
74
70
  try {
75
71
  parsedPreviousSplit = splitFromStorage ? JSON.parse(splitFromStorage) : undefined;
76
72
  newStringifiedSplit = JSON.stringify(split);
@@ -78,13 +74,16 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
78
74
  throw new Error('Error parsing feature flag definition: ' + e);
79
75
  }
80
76
 
81
- return Promise.all([
82
- this.redis.set(splitKey, newStringifiedSplit),
83
- this._incrementCounts(split),
84
- // If it's an update, we decrement the traffic type of the existing split,
85
- parsedPreviousSplit && this._decrementCounts(parsedPreviousSplit)
86
- ]);
87
- }).then(([status]) => status === 'OK');
77
+ return this.redis.set(splitKey, newStringifiedSplit).then(() => {
78
+ // avoid unnecessary increment/decrement operations
79
+ if (parsedPreviousSplit && parsedPreviousSplit.trafficTypeName === split.trafficTypeName) return;
80
+
81
+ // update traffic type counts
82
+ return this._incrementCounts(split).then(() => {
83
+ if (parsedPreviousSplit) return this._decrementCounts(parsedPreviousSplit);
84
+ });
85
+ });
86
+ }).then(() => true);
88
87
  }
89
88
 
90
89
  /**
@@ -29,19 +29,15 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
29
29
  }
30
30
 
31
31
  private _decrementCounts(split: ISplit) {
32
- if (split.trafficTypeName) {
33
- const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
34
- return this.wrapper.decr(ttKey).then(count => {
35
- if (count === 0) return this.wrapper.del(ttKey);
36
- });
37
- }
32
+ const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
33
+ return this.wrapper.decr(ttKey).then(count => {
34
+ if (count === 0) return this.wrapper.del(ttKey);
35
+ });
38
36
  }
39
37
 
40
38
  private _incrementCounts(split: ISplit) {
41
- if (split.trafficTypeName) {
42
- const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
43
- return this.wrapper.incr(ttKey);
44
- }
39
+ const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
40
+ return this.wrapper.incr(ttKey);
45
41
  }
46
42
 
47
43
  /**
@@ -54,7 +50,7 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
54
50
  return this.wrapper.get(splitKey).then(splitFromStorage => {
55
51
 
56
52
  // handling parsing error
57
- let parsedPreviousSplit, stringifiedNewSplit;
53
+ let parsedPreviousSplit: ISplit, stringifiedNewSplit;
58
54
  try {
59
55
  parsedPreviousSplit = splitFromStorage ? JSON.parse(splitFromStorage) : undefined;
60
56
  stringifiedNewSplit = JSON.stringify(split);
@@ -62,12 +58,15 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
62
58
  throw new Error('Error parsing feature flag definition: ' + e);
63
59
  }
64
60
 
65
- return Promise.all([
66
- this.wrapper.set(splitKey, stringifiedNewSplit),
67
- this._incrementCounts(split),
68
- // If it's an update, we decrement the traffic type and segment count of the existing split,
69
- parsedPreviousSplit && this._decrementCounts(parsedPreviousSplit)
70
- ]);
61
+ return this.wrapper.set(splitKey, stringifiedNewSplit).then(() => {
62
+ // avoid unnecessary increment/decrement operations
63
+ if (parsedPreviousSplit && parsedPreviousSplit.trafficTypeName === split.trafficTypeName) return;
64
+
65
+ // update traffic type counts
66
+ return this._incrementCounts(split).then(() => {
67
+ if (parsedPreviousSplit) return this._decrementCounts(parsedPreviousSplit);
68
+ });
69
+ });
71
70
  }).then(() => true);
72
71
  }
73
72