@splitsoftware/splitio-commons 1.6.2-rc.13 → 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 (50) hide show
  1. package/cjs/storages/KeyBuilderSS.js +4 -43
  2. package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +3 -3
  3. package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +2 -19
  4. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +4 -4
  5. package/cjs/storages/inRedis/index.js +2 -2
  6. package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +3 -3
  7. package/cjs/storages/pluggable/ImpressionsCachePluggable.js +2 -19
  8. package/cjs/storages/pluggable/TelemetryCachePluggable.js +4 -4
  9. package/cjs/storages/pluggable/inMemoryWrapper.js +8 -6
  10. package/cjs/storages/pluggable/index.js +2 -2
  11. package/cjs/storages/utils.js +73 -0
  12. package/esm/storages/KeyBuilderSS.js +1 -37
  13. package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +3 -3
  14. package/esm/storages/inRedis/ImpressionsCacheInRedis.js +2 -19
  15. package/esm/storages/inRedis/TelemetryCacheInRedis.js +1 -1
  16. package/esm/storages/inRedis/index.js +1 -1
  17. package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +3 -3
  18. package/esm/storages/pluggable/ImpressionsCachePluggable.js +2 -19
  19. package/esm/storages/pluggable/TelemetryCachePluggable.js +1 -1
  20. package/esm/storages/pluggable/inMemoryWrapper.js +8 -6
  21. package/esm/storages/pluggable/index.js +1 -1
  22. package/esm/storages/utils.js +65 -0
  23. package/package.json +1 -1
  24. package/src/services/splitApi.ts +2 -2
  25. package/src/storages/KeyBuilderSS.ts +2 -44
  26. package/src/storages/inMemory/AttributesCacheInMemory.ts +7 -7
  27. package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +3 -3
  28. package/src/storages/inRedis/ImpressionsCacheInRedis.ts +2 -22
  29. package/src/storages/inRedis/TelemetryCacheInRedis.ts +2 -1
  30. package/src/storages/inRedis/index.ts +1 -1
  31. package/src/storages/pluggable/ImpressionCountsCachePluggable.ts +3 -3
  32. package/src/storages/pluggable/ImpressionsCachePluggable.ts +3 -23
  33. package/src/storages/pluggable/TelemetryCachePluggable.ts +2 -1
  34. package/src/storages/pluggable/inMemoryWrapper.ts +6 -6
  35. package/src/storages/pluggable/index.ts +1 -1
  36. package/src/storages/types.ts +4 -4
  37. package/src/storages/utils.ts +78 -0
  38. package/src/sync/submitters/types.ts +2 -0
  39. package/src/trackers/impressionsTracker.ts +2 -2
  40. package/src/trackers/strategy/strategyDebug.ts +4 -4
  41. package/src/utils/redis/RedisMock.ts +5 -5
  42. package/types/storages/KeyBuilderSS.d.ts +1 -3
  43. package/types/storages/inRedis/ImpressionsCacheInRedis.d.ts +0 -1
  44. package/types/storages/pluggable/ImpressionsCachePluggable.d.ts +1 -2
  45. package/types/storages/types.d.ts +4 -4
  46. package/types/storages/utils.d.ts +8 -0
  47. package/types/sync/submitters/types.d.ts +2 -0
  48. package/cjs/storages/metadataBuilder.js +0 -12
  49. package/esm/storages/metadataBuilder.js +0 -8
  50. package/src/storages/metadataBuilder.ts +0 -11
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseLatencyField = exports.parseExceptionField = exports.parseMetadata = exports.KeyBuilderSS = void 0;
3
+ exports.KeyBuilderSS = exports.METHOD_NAMES = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var KeyBuilder_1 = require("./KeyBuilder");
6
- var TelemetryCacheInMemory_1 = require("./inMemory/TelemetryCacheInMemory");
7
- var METHOD_NAMES = {
6
+ exports.METHOD_NAMES = {
8
7
  t: 'treatment',
9
8
  ts: 'treatments',
10
9
  tc: 'treatmentWithConfig',
@@ -41,10 +40,10 @@ var KeyBuilderSS = /** @class */ (function (_super) {
41
40
  };
42
41
  /* Telemetry keys */
43
42
  KeyBuilderSS.prototype.buildLatencyKey = function (method, bucket) {
44
- return this.latencyPrefix + "::" + this.versionablePrefix + "/" + METHOD_NAMES[method] + "/" + bucket;
43
+ return this.latencyPrefix + "::" + this.versionablePrefix + "/" + exports.METHOD_NAMES[method] + "/" + bucket;
45
44
  };
46
45
  KeyBuilderSS.prototype.buildExceptionKey = function (method) {
47
- return this.exceptionPrefix + "::" + this.versionablePrefix + "/" + METHOD_NAMES[method];
46
+ return this.exceptionPrefix + "::" + this.versionablePrefix + "/" + exports.METHOD_NAMES[method];
48
47
  };
49
48
  KeyBuilderSS.prototype.buildInitKey = function () {
50
49
  return this.initPrefix + "::" + this.versionablePrefix;
@@ -52,41 +51,3 @@ var KeyBuilderSS = /** @class */ (function (_super) {
52
51
  return KeyBuilderSS;
53
52
  }(KeyBuilder_1.KeyBuilder));
54
53
  exports.KeyBuilderSS = KeyBuilderSS;
55
- // Used by consumer methods of TelemetryCacheInRedis and TelemetryCachePluggable
56
- var REVERSE_METHOD_NAMES = Object.keys(METHOD_NAMES).reduce(function (acc, key) {
57
- acc[METHOD_NAMES[key]] = key;
58
- return acc;
59
- }, {});
60
- function parseMetadata(field) {
61
- var parts = field.split('/');
62
- if (parts.length !== 3)
63
- return "invalid subsection count. Expected 3, got: " + parts.length;
64
- var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */;
65
- return [JSON.stringify({ s: s, n: n, i: i })];
66
- }
67
- exports.parseMetadata = parseMetadata;
68
- function parseExceptionField(field) {
69
- var parts = field.split('/');
70
- if (parts.length !== 4)
71
- return "invalid subsection count. Expected 4, got: " + parts.length;
72
- var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */, m = parts[3];
73
- var method = REVERSE_METHOD_NAMES[m];
74
- if (!method)
75
- return "unknown method '" + m + "'";
76
- return [JSON.stringify({ s: s, n: n, i: i }), method];
77
- }
78
- exports.parseExceptionField = parseExceptionField;
79
- function parseLatencyField(field) {
80
- var parts = field.split('/');
81
- if (parts.length !== 5)
82
- return "invalid subsection count. Expected 5, got: " + parts.length;
83
- var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */, m = parts[3], b = parts[4];
84
- var method = REVERSE_METHOD_NAMES[m];
85
- if (!method)
86
- return "unknown method '" + m + "'";
87
- var bucket = parseInt(b);
88
- if (isNaN(bucket) || bucket >= TelemetryCacheInMemory_1.MAX_LATENCY_BUCKET_COUNT)
89
- return "invalid bucket. Expected a number between 0 and " + (TelemetryCacheInMemory_1.MAX_LATENCY_BUCKET_COUNT - 1) + ", got: " + b;
90
- return [JSON.stringify({ s: s, n: n, i: i }), method, bucket];
91
- }
92
- exports.parseLatencyField = parseLatencyField;
@@ -54,7 +54,7 @@ var ImpressionCountsCacheInRedis = /** @class */ (function (_super) {
54
54
  if (!Object.keys(counts).length)
55
55
  return undefined;
56
56
  _this.redis.del(_this.key).catch(function () { });
57
- var impressionsCount = { pf: [] };
57
+ var pf = [];
58
58
  (0, lang_1.forOwn)(counts, function (count, key) {
59
59
  var nameAndTime = key.split('::');
60
60
  if (nameAndTime.length !== 2) {
@@ -71,13 +71,13 @@ var ImpressionCountsCacheInRedis = /** @class */ (function (_super) {
71
71
  _this.log.error(constants_1.LOG_PREFIX + "Error parsing raw count " + count);
72
72
  return;
73
73
  }
74
- impressionsCount.pf.push({
74
+ pf.push({
75
75
  f: nameAndTime[0],
76
76
  m: timeFrame,
77
77
  rc: rawCount,
78
78
  });
79
79
  });
80
- return impressionsCount;
80
+ return { pf: pf };
81
81
  });
82
82
  };
83
83
  return ImpressionCountsCacheInRedis;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ImpressionsCacheInRedis = void 0;
4
+ var utils_1 = require("../utils");
4
5
  var IMPRESSIONS_TTL_REFRESH = 3600; // 1 hr
5
6
  var ImpressionsCacheInRedis = /** @class */ (function () {
6
7
  function ImpressionsCacheInRedis(log, key, redis, metadata) {
@@ -11,31 +12,13 @@ var ImpressionsCacheInRedis = /** @class */ (function () {
11
12
  }
12
13
  ImpressionsCacheInRedis.prototype.track = function (impressions) {
13
14
  var _this = this;
14
- return this.redis.rpush(this.key, this._toJSON(impressions)).then(function (queuedCount) {
15
+ return this.redis.rpush(this.key, (0, utils_1.impressionsToJSON)(impressions, this.metadata)).then(function (queuedCount) {
15
16
  // If this is the creation of the key on Redis, set the expiration for it in 1hr.
16
17
  if (queuedCount === impressions.length) {
17
18
  return _this.redis.expire(_this.key, IMPRESSIONS_TTL_REFRESH);
18
19
  }
19
20
  });
20
21
  };
21
- ImpressionsCacheInRedis.prototype._toJSON = function (impressions) {
22
- var _this = this;
23
- return impressions.map(function (impression) {
24
- var keyName = impression.keyName, bucketingKey = impression.bucketingKey, feature = impression.feature, treatment = impression.treatment, label = impression.label, time = impression.time, changeNumber = impression.changeNumber;
25
- return JSON.stringify({
26
- m: _this.metadata,
27
- i: {
28
- k: keyName,
29
- b: bucketingKey,
30
- f: feature,
31
- t: treatment,
32
- r: label,
33
- c: changeNumber,
34
- m: time
35
- }
36
- });
37
- });
38
- };
39
22
  ImpressionsCacheInRedis.prototype.count = function () {
40
23
  return this.redis.llen(this.key).catch(function () { return 0; });
41
24
  };
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TelemetryCacheInRedis = 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 TelemetryCacheInRedis = /** @class */ (function () {
12
12
  /**
13
13
  * Create a Telemetry cache that uses Redis as storage.
@@ -44,7 +44,7 @@ var TelemetryCacheInRedis = /** @class */ (function () {
44
44
  return this.redis.hgetall(this.keys.latencyPrefix).then(function (latencies) {
45
45
  var result = new maps_1._Map();
46
46
  Object.keys(latencies).forEach(function (field) {
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
  return;
@@ -81,7 +81,7 @@ var TelemetryCacheInRedis = /** @class */ (function () {
81
81
  return this.redis.hgetall(this.keys.exceptionPrefix).then(function (exceptions) {
82
82
  var result = new maps_1._Map();
83
83
  Object.keys(exceptions).forEach(function (field) {
84
- var parsedField = (0, KeyBuilderSS_1.parseExceptionField)(field);
84
+ var parsedField = (0, utils_1.parseExceptionField)(field);
85
85
  if ((0, lang_1.isString)(parsedField)) {
86
86
  _this.log.error("Ignoring invalid exception field: " + field + ": " + parsedField);
87
87
  return;
@@ -114,7 +114,7 @@ var TelemetryCacheInRedis = /** @class */ (function () {
114
114
  return this.redis.hgetall(this.keys.initPrefix).then(function (configs) {
115
115
  var result = new maps_1._Map();
116
116
  Object.keys(configs).forEach(function (field) {
117
- var parsedField = (0, KeyBuilderSS_1.parseMetadata)(field);
117
+ var parsedField = (0, utils_1.parseMetadata)(field);
118
118
  if ((0, lang_1.isString)(parsedField)) {
119
119
  _this.log.error("Ignoring invalid config field: " + field + ": " + parsedField);
120
120
  return;
@@ -12,7 +12,7 @@ var constants_1 = require("../../utils/constants");
12
12
  var TelemetryCacheInRedis_1 = require("./TelemetryCacheInRedis");
13
13
  var UniqueKeysCacheInRedis_1 = require("./UniqueKeysCacheInRedis");
14
14
  var ImpressionCountsCacheInRedis_1 = require("./ImpressionCountsCacheInRedis");
15
- var metadataBuilder_1 = require("../metadataBuilder");
15
+ var utils_1 = require("../utils");
16
16
  /**
17
17
  * InRedis storage factory for consumer server-side SplitFactory, that uses `Ioredis` Redis client for Node.
18
18
  * @see {@link https://www.npmjs.com/package/ioredis}
@@ -22,7 +22,7 @@ function InRedisStorage(options) {
22
22
  var prefix = (0, KeyBuilder_1.validatePrefix)(options.prefix);
23
23
  function InRedisStorageFactory(params) {
24
24
  var onReadyCb = params.onReadyCb, settings = params.settings, _a = params.settings, log = _a.log, impressionsMode = _a.sync.impressionsMode;
25
- var metadata = (0, metadataBuilder_1.metadataBuilder)(settings);
25
+ var metadata = (0, utils_1.metadataBuilder)(settings);
26
26
  var keys = new KeyBuilderSS_1.KeyBuilderSS(prefix, metadata);
27
27
  var redisClient = new RedisAdapter_1.RedisAdapter(log, options.options || {});
28
28
  var telemetry = new TelemetryCacheInRedis_1.TelemetryCacheInRedis(log, keys, redisClient);
@@ -46,7 +46,7 @@ var ImpressionCountsCachePluggable = /** @class */ (function (_super) {
46
46
  return keys.length ? Promise.all(keys.map(function (key) { return _this.wrapper.get(key); }))
47
47
  .then(function (counts) {
48
48
  keys.forEach(function (key) { return _this.wrapper.del(key).catch(function () { }); });
49
- var impressionsCount = { pf: [] };
49
+ var pf = [];
50
50
  for (var i = 0; i < keys.length; i++) {
51
51
  var key = keys[i];
52
52
  var count = counts[i];
@@ -66,13 +66,13 @@ var ImpressionCountsCachePluggable = /** @class */ (function (_super) {
66
66
  _this.log.error(constants_2.LOG_PREFIX + "Error parsing raw count " + count);
67
67
  continue;
68
68
  }
69
- impressionsCount.pf.push({
69
+ pf.push({
70
70
  f: keyFeatureNameAndTime[1],
71
71
  m: timeFrame,
72
72
  rc: rawCount,
73
73
  });
74
74
  }
75
- return impressionsCount;
75
+ return { pf: pf };
76
76
  }) : undefined;
77
77
  });
78
78
  };
@@ -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,7 +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 metadataBuilder_1 = require("../metadataBuilder");
23
+ var utils_1 = require("../utils");
24
24
  var NO_VALID_WRAPPER = 'Expecting pluggable storage `wrapper` in options, but no valid wrapper instance was provided.';
25
25
  var NO_VALID_WRAPPER_INTERFACE = 'The provided wrapper instance doesn’t follow the expected interface. Check our docs.';
26
26
  /**
@@ -54,7 +54,7 @@ function PluggableStorage(options) {
54
54
  var prefix = (0, KeyBuilder_1.validatePrefix)(options.prefix);
55
55
  function PluggableStorageFactory(params) {
56
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, metadataBuilder_1.metadataBuilder)(settings);
57
+ var metadata = (0, utils_1.metadataBuilder)(settings);
58
58
  var keys = new KeyBuilderSS_1.KeyBuilderSS(prefix, metadata);
59
59
  var wrapper = (0, wrapperAdapter_1.wrapperAdapter)(log, options.wrapper);
60
60
  var isSyncronizer = mode === undefined; // If mode is not defined, the synchronizer is running
@@ -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;
@@ -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
- }
@@ -51,7 +51,7 @@ var ImpressionCountsCacheInRedis = /** @class */ (function (_super) {
51
51
  if (!Object.keys(counts).length)
52
52
  return undefined;
53
53
  _this.redis.del(_this.key).catch(function () { });
54
- var impressionsCount = { pf: [] };
54
+ var pf = [];
55
55
  forOwn(counts, function (count, key) {
56
56
  var nameAndTime = key.split('::');
57
57
  if (nameAndTime.length !== 2) {
@@ -68,13 +68,13 @@ var ImpressionCountsCacheInRedis = /** @class */ (function (_super) {
68
68
  _this.log.error(LOG_PREFIX + "Error parsing raw count " + count);
69
69
  return;
70
70
  }
71
- impressionsCount.pf.push({
71
+ pf.push({
72
72
  f: nameAndTime[0],
73
73
  m: timeFrame,
74
74
  rc: rawCount,
75
75
  });
76
76
  });
77
- return impressionsCount;
77
+ return { pf: pf };
78
78
  });
79
79
  };
80
80
  return ImpressionCountsCacheInRedis;
@@ -1,3 +1,4 @@
1
+ import { impressionsToJSON } from '../utils';
1
2
  var IMPRESSIONS_TTL_REFRESH = 3600; // 1 hr
2
3
  var ImpressionsCacheInRedis = /** @class */ (function () {
3
4
  function ImpressionsCacheInRedis(log, key, redis, metadata) {
@@ -8,31 +9,13 @@ var ImpressionsCacheInRedis = /** @class */ (function () {
8
9
  }
9
10
  ImpressionsCacheInRedis.prototype.track = function (impressions) {
10
11
  var _this = this;
11
- return this.redis.rpush(this.key, this._toJSON(impressions)).then(function (queuedCount) {
12
+ return this.redis.rpush(this.key, impressionsToJSON(impressions, this.metadata)).then(function (queuedCount) {
12
13
  // If this is the creation of the key on Redis, set the expiration for it in 1hr.
13
14
  if (queuedCount === impressions.length) {
14
15
  return _this.redis.expire(_this.key, IMPRESSIONS_TTL_REFRESH);
15
16
  }
16
17
  });
17
18
  };
18
- ImpressionsCacheInRedis.prototype._toJSON = function (impressions) {
19
- var _this = this;
20
- return impressions.map(function (impression) {
21
- var keyName = impression.keyName, bucketingKey = impression.bucketingKey, feature = impression.feature, treatment = impression.treatment, label = impression.label, time = impression.time, changeNumber = impression.changeNumber;
22
- return JSON.stringify({
23
- m: _this.metadata,
24
- i: {
25
- k: keyName,
26
- b: bucketingKey,
27
- f: feature,
28
- t: treatment,
29
- r: label,
30
- c: changeNumber,
31
- m: time
32
- }
33
- });
34
- });
35
- };
36
19
  ImpressionsCacheInRedis.prototype.count = function () {
37
20
  return this.redis.llen(this.key).catch(function () { return 0; });
38
21
  };
@@ -1,10 +1,10 @@
1
- import { parseExceptionField, parseLatencyField, parseMetadata } from '../KeyBuilderSS';
2
1
  import { findLatencyIndex } from '../findLatencyIndex';
3
2
  import { getTelemetryConfigStats } from '../../sync/submitters/telemetrySubmitter';
4
3
  import { CONSUMER_MODE, STORAGE_REDIS } from '../../utils/constants';
5
4
  import { isNaNNumber, isString } from '../../utils/lang';
6
5
  import { _Map } from '../../utils/lang/maps';
7
6
  import { MAX_LATENCY_BUCKET_COUNT, newBuckets } from '../inMemory/TelemetryCacheInMemory';
7
+ import { parseLatencyField, parseExceptionField, parseMetadata } from '../utils';
8
8
  var TelemetryCacheInRedis = /** @class */ (function () {
9
9
  /**
10
10
  * Create a Telemetry cache that uses Redis as storage.
@@ -9,7 +9,7 @@ import { DEBUG, NONE, STORAGE_REDIS } from '../../utils/constants';
9
9
  import { TelemetryCacheInRedis } from './TelemetryCacheInRedis';
10
10
  import { UniqueKeysCacheInRedis } from './UniqueKeysCacheInRedis';
11
11
  import { ImpressionCountsCacheInRedis } from './ImpressionCountsCacheInRedis';
12
- import { metadataBuilder } from '../metadataBuilder';
12
+ import { metadataBuilder } from '../utils';
13
13
  /**
14
14
  * InRedis storage factory for consumer server-side SplitFactory, that uses `Ioredis` Redis client for Node.
15
15
  * @see {@link https://www.npmjs.com/package/ioredis}
@@ -43,7 +43,7 @@ var ImpressionCountsCachePluggable = /** @class */ (function (_super) {
43
43
  return keys.length ? Promise.all(keys.map(function (key) { return _this.wrapper.get(key); }))
44
44
  .then(function (counts) {
45
45
  keys.forEach(function (key) { return _this.wrapper.del(key).catch(function () { }); });
46
- var impressionsCount = { pf: [] };
46
+ var pf = [];
47
47
  for (var i = 0; i < keys.length; i++) {
48
48
  var key = keys[i];
49
49
  var count = counts[i];
@@ -63,13 +63,13 @@ var ImpressionCountsCachePluggable = /** @class */ (function (_super) {
63
63
  _this.log.error(LOG_PREFIX + "Error parsing raw count " + count);
64
64
  continue;
65
65
  }
66
- impressionsCount.pf.push({
66
+ pf.push({
67
67
  f: keyFeatureNameAndTime[1],
68
68
  m: timeFrame,
69
69
  rc: rawCount,
70
70
  });
71
71
  }
72
- return impressionsCount;
72
+ return { pf: pf };
73
73
  }) : undefined;
74
74
  });
75
75
  };
@@ -1,3 +1,4 @@
1
+ import { impressionsToJSON } from '../utils';
1
2
  var ImpressionsCachePluggable = /** @class */ (function () {
2
3
  function ImpressionsCachePluggable(log, key, wrapper, metadata) {
3
4
  this.log = log;
@@ -12,25 +13,7 @@ var ImpressionsCachePluggable = /** @class */ (function () {
12
13
  * or rejected if the wrapper operation fails.
13
14
  */
14
15
  ImpressionsCachePluggable.prototype.track = function (impressions) {
15
- return this.wrapper.pushItems(this.key, this._toJSON(impressions));
16
- };
17
- ImpressionsCachePluggable.prototype._toJSON = function (impressions) {
18
- var _this = this;
19
- return impressions.map(function (impression) {
20
- var keyName = impression.keyName, bucketingKey = impression.bucketingKey, feature = impression.feature, treatment = impression.treatment, label = impression.label, time = impression.time, changeNumber = impression.changeNumber;
21
- return JSON.stringify({
22
- m: _this.metadata,
23
- i: {
24
- k: keyName,
25
- b: bucketingKey,
26
- f: feature,
27
- t: treatment,
28
- r: label,
29
- c: changeNumber,
30
- m: time
31
- }
32
- });
33
- });
16
+ return this.wrapper.pushItems(this.key, impressionsToJSON(impressions, this.metadata));
34
17
  };
35
18
  /**
36
19
  * Returns a promise that resolves with the count of stored impressions, or 0 if there was some error.
@@ -1,10 +1,10 @@
1
- import { parseExceptionField, parseLatencyField, parseMetadata } from '../KeyBuilderSS';
2
1
  import { findLatencyIndex } from '../findLatencyIndex';
3
2
  import { getTelemetryConfigStats } from '../../sync/submitters/telemetrySubmitter';
4
3
  import { CONSUMER_MODE, STORAGE_PLUGGABLE } from '../../utils/constants';
5
4
  import { isString, isNaNNumber } from '../../utils/lang';
6
5
  import { _Map } from '../../utils/lang/maps';
7
6
  import { MAX_LATENCY_BUCKET_COUNT, newBuckets } from '../inMemory/TelemetryCacheInMemory';
7
+ import { parseLatencyField, parseExceptionField, parseMetadata } from '../utils';
8
8
  var TelemetryCachePluggable = /** @class */ (function () {
9
9
  /**
10
10
  * Create a Telemetry cache that uses a storage wrapper.