@splitsoftware/splitio-commons 1.6.2-rc.7 → 1.6.2-rc.9
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 +2 -1
- package/cjs/consent/sdkUserConsent.js +2 -2
- package/cjs/evaluator/index.js +5 -5
- package/cjs/listeners/browser.js +1 -2
- package/cjs/logger/constants.js +1 -2
- package/cjs/sdkClient/client.js +19 -7
- package/cjs/sdkClient/sdkClient.js +1 -3
- package/cjs/sdkFactory/index.js +5 -26
- package/cjs/services/splitApi.js +4 -24
- package/cjs/storages/KeyBuilderSS.js +48 -15
- package/cjs/storages/inLocalStorage/index.js +1 -5
- package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -12
- package/cjs/storages/inMemory/InMemoryStorage.js +2 -6
- package/cjs/storages/inMemory/InMemoryStorageCS.js +2 -6
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +9 -6
- package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +100 -0
- package/cjs/storages/inRedis/constants.js +1 -4
- package/cjs/storages/inRedis/index.js +1 -15
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +126 -0
- package/cjs/storages/pluggable/index.js +19 -15
- package/cjs/sync/submitters/submitterManager.js +0 -3
- package/cjs/sync/submitters/telemetrySubmitter.js +7 -5
- package/cjs/trackers/impressionsTracker.js +41 -22
- package/cjs/utils/constants/index.js +2 -4
- package/cjs/utils/lang/maps.js +15 -7
- package/cjs/utils/settingsValidation/impressionsMode.js +2 -2
- package/cjs/utils/settingsValidation/index.js +0 -4
- package/esm/consent/sdkUserConsent.js +2 -2
- package/esm/evaluator/index.js +5 -5
- package/esm/listeners/browser.js +2 -3
- package/esm/logger/constants.js +0 -1
- package/esm/sdkClient/client.js +19 -7
- package/esm/sdkClient/sdkClient.js +1 -3
- package/esm/sdkFactory/index.js +5 -26
- package/esm/services/splitApi.js +4 -24
- package/esm/storages/KeyBuilderSS.js +44 -14
- package/esm/storages/inLocalStorage/index.js +2 -6
- package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -12
- package/esm/storages/inMemory/InMemoryStorage.js +4 -8
- package/esm/storages/inMemory/InMemoryStorageCS.js +3 -7
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +8 -6
- package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +100 -0
- package/esm/storages/inRedis/constants.js +0 -3
- package/esm/storages/inRedis/index.js +2 -16
- package/esm/storages/pluggable/TelemetryCachePluggable.js +126 -0
- package/esm/storages/pluggable/index.js +19 -15
- package/esm/sync/submitters/submitterManager.js +0 -3
- package/esm/sync/submitters/telemetrySubmitter.js +8 -6
- package/esm/trackers/impressionsTracker.js +41 -22
- package/esm/utils/constants/index.js +0 -2
- package/esm/utils/lang/maps.js +15 -7
- package/esm/utils/settingsValidation/impressionsMode.js +3 -3
- package/esm/utils/settingsValidation/index.js +0 -4
- package/package.json +2 -1
- package/src/consent/sdkUserConsent.ts +2 -2
- package/src/evaluator/index.ts +6 -6
- package/src/listeners/browser.ts +2 -3
- package/src/logger/.DS_Store +0 -0
- package/src/logger/constants.ts +0 -1
- package/src/sdkClient/client.ts +21 -8
- package/src/sdkClient/sdkClient.ts +1 -3
- package/src/sdkFactory/index.ts +5 -29
- package/src/sdkFactory/types.ts +4 -7
- package/src/services/splitApi.ts +4 -26
- package/src/services/types.ts +2 -8
- package/src/storages/KeyBuilderSS.ts +53 -17
- package/src/storages/inLocalStorage/index.ts +2 -5
- package/src/storages/inMemory/ImpressionCountsCacheInMemory.ts +1 -16
- package/src/storages/inMemory/InMemoryStorage.ts +4 -7
- package/src/storages/inMemory/InMemoryStorageCS.ts +3 -7
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +9 -7
- package/src/storages/inRedis/EventsCacheInRedis.ts +1 -1
- package/src/storages/inRedis/TelemetryCacheInRedis.ts +122 -2
- package/src/storages/inRedis/constants.ts +0 -3
- package/src/storages/inRedis/index.ts +3 -12
- package/src/storages/pluggable/TelemetryCachePluggable.ts +147 -2
- package/src/storages/pluggable/index.ts +20 -16
- package/src/storages/types.ts +13 -34
- package/src/sync/submitters/submitterManager.ts +0 -2
- package/src/sync/submitters/telemetrySubmitter.ts +14 -9
- package/src/sync/submitters/types.ts +40 -26
- package/src/trackers/impressionsTracker.ts +48 -27
- package/src/trackers/types.ts +0 -28
- package/src/types.ts +1 -5
- package/src/utils/constants/index.ts +0 -2
- package/src/utils/lang/maps.ts +20 -8
- package/src/utils/settingsValidation/impressionsMode.ts +3 -3
- package/src/utils/settingsValidation/index.ts +0 -5
- package/types/logger/constants.d.ts +0 -1
- package/types/sdkFactory/types.d.ts +2 -4
- package/types/services/types.d.ts +2 -6
- package/types/storages/KeyBuilderSS.d.ts +7 -4
- package/types/storages/inMemory/ImpressionCountsCacheInMemory.d.ts +1 -5
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +6 -3
- package/types/storages/inRedis/EventsCacheInRedis.d.ts +1 -1
- package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +16 -1
- package/types/storages/inRedis/constants.d.ts +0 -3
- package/types/storages/pluggable/TelemetryCachePluggable.d.ts +17 -1
- package/types/storages/types.d.ts +10 -21
- package/types/sync/submitters/telemetrySubmitter.d.ts +1 -1
- package/types/sync/submitters/types.d.ts +13 -24
- package/types/trackers/impressionsTracker.d.ts +6 -4
- package/types/trackers/types.d.ts +0 -23
- package/types/types.d.ts +1 -5
- package/types/utils/constants/index.d.ts +0 -2
- package/types/utils/lang/maps.d.ts +6 -2
- package/types/utils/settingsValidation/index.d.ts +0 -1
- package/cjs/storages/inMemory/uniqueKeysCacheInMemory.js +0 -73
- package/cjs/storages/inMemory/uniqueKeysCacheInMemoryCS.js +0 -78
- package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +0 -49
- package/cjs/storages/inRedis/uniqueKeysCacheInRedis.js +0 -56
- package/cjs/sync/submitters/uniqueKeysSubmitter.js +0 -26
- package/cjs/trackers/strategy/strategyDebug.js +0 -25
- package/cjs/trackers/strategy/strategyNone.js +0 -29
- package/cjs/trackers/strategy/strategyOptimized.js +0 -35
- package/cjs/trackers/uniqueKeysTracker.js +0 -38
- package/esm/storages/inMemory/uniqueKeysCacheInMemory.js +0 -70
- package/esm/storages/inMemory/uniqueKeysCacheInMemoryCS.js +0 -75
- package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +0 -46
- package/esm/storages/inRedis/uniqueKeysCacheInRedis.js +0 -53
- package/esm/sync/submitters/uniqueKeysSubmitter.js +0 -22
- package/esm/trackers/strategy/strategyDebug.js +0 -21
- package/esm/trackers/strategy/strategyNone.js +0 -25
- package/esm/trackers/strategy/strategyOptimized.js +0 -31
- package/esm/trackers/uniqueKeysTracker.js +0 -34
- package/src/storages/inMemory/uniqueKeysCacheInMemory.ts +0 -82
- package/src/storages/inMemory/uniqueKeysCacheInMemoryCS.ts +0 -88
- package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +0 -51
- package/src/storages/inRedis/uniqueKeysCacheInRedis.ts +0 -63
- package/src/sync/submitters/uniqueKeysSubmitter.ts +0 -35
- package/src/trackers/strategy/strategyDebug.ts +0 -28
- package/src/trackers/strategy/strategyNone.ts +0 -34
- package/src/trackers/strategy/strategyOptimized.ts +0 -42
- package/src/trackers/uniqueKeysTracker.ts +0 -48
- package/types/sdkClient/types.d.ts +0 -18
- package/types/storages/inMemory/CountsCacheInMemory.d.ts +0 -20
- package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +0 -20
- package/types/storages/inMemory/uniqueKeysCacheInMemory.d.ts +0 -35
- package/types/storages/inMemory/uniqueKeysCacheInMemoryCS.d.ts +0 -37
- package/types/storages/inRedis/CountsCacheInRedis.d.ts +0 -9
- package/types/storages/inRedis/ImpressionCountsCacheInRedis.d.ts +0 -14
- package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +0 -9
- package/types/storages/inRedis/uniqueKeysCacheInRedis.d.ts +0 -15
- package/types/sync/offline/LocalhostFromFile.d.ts +0 -2
- package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +0 -2
- package/types/sync/submitters/eventsSyncTask.d.ts +0 -8
- package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +0 -5
- package/types/sync/submitters/impressionCountsSyncTask.d.ts +0 -13
- package/types/sync/submitters/impressionsSyncTask.d.ts +0 -14
- package/types/sync/submitters/metricsSyncTask.d.ts +0 -12
- package/types/sync/submitters/submitterSyncTask.d.ts +0 -10
- package/types/sync/submitters/uniqueKeysSubmitter.d.ts +0 -5
- package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +0 -5
- package/types/sync/syncTaskComposite.d.ts +0 -5
- package/types/trackers/filter/bloomFilter.d.ts +0 -10
- package/types/trackers/filter/dictionaryFilter.d.ts +0 -8
- package/types/trackers/filter/types.d.ts +0 -5
- package/types/trackers/strategy/strategyDebug.d.ts +0 -9
- package/types/trackers/strategy/strategyNone.d.ts +0 -10
- package/types/trackers/strategy/strategyOptimized.d.ts +0 -11
- package/types/trackers/uniqueKeysTracker.d.ts +0 -13
- package/types/utils/timeTracker/index.d.ts +0 -70
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { setToArray, _Set } from '../../utils/lang/sets';
|
|
2
|
-
import { DEFAULT_CACHE_SIZE } from '../inRedis/constants';
|
|
3
|
-
var UniqueKeysCacheInMemoryCS = /** @class */ (function () {
|
|
4
|
-
/**
|
|
5
|
-
*
|
|
6
|
-
* @param impressionsQueueSize number of queued impressions to call onFullQueueCb.
|
|
7
|
-
* Default value is 0, that means no maximum value, in case we want to avoid this being triggered.
|
|
8
|
-
*/
|
|
9
|
-
function UniqueKeysCacheInMemoryCS(uniqueKeysQueueSize) {
|
|
10
|
-
if (uniqueKeysQueueSize === void 0) { uniqueKeysQueueSize = DEFAULT_CACHE_SIZE; }
|
|
11
|
-
this.uniqueTrackerSize = 0;
|
|
12
|
-
this.maxStorage = uniqueKeysQueueSize;
|
|
13
|
-
this.uniqueKeysTracker = {};
|
|
14
|
-
}
|
|
15
|
-
UniqueKeysCacheInMemoryCS.prototype.setOnFullQueueCb = function (cb) {
|
|
16
|
-
this.onFullQueue = cb;
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Store unique keys in sequential order
|
|
20
|
-
* key: string = key.
|
|
21
|
-
* value: HashSet<string> = set of split names.
|
|
22
|
-
*/
|
|
23
|
-
UniqueKeysCacheInMemoryCS.prototype.track = function (key, featureName) {
|
|
24
|
-
if (!this.uniqueKeysTracker[key])
|
|
25
|
-
this.uniqueKeysTracker[key] = new _Set();
|
|
26
|
-
var tracker = this.uniqueKeysTracker[key];
|
|
27
|
-
if (!tracker.has(featureName)) {
|
|
28
|
-
tracker.add(featureName);
|
|
29
|
-
this.uniqueTrackerSize++;
|
|
30
|
-
}
|
|
31
|
-
if (this.uniqueTrackerSize >= this.maxStorage && this.onFullQueue) {
|
|
32
|
-
this.uniqueTrackerSize = 0;
|
|
33
|
-
this.onFullQueue();
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Clear the data stored on the cache.
|
|
38
|
-
*/
|
|
39
|
-
UniqueKeysCacheInMemoryCS.prototype.clear = function () {
|
|
40
|
-
this.uniqueKeysTracker = {};
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Pop the collected data, used as payload for posting.
|
|
44
|
-
*/
|
|
45
|
-
UniqueKeysCacheInMemoryCS.prototype.pop = function () {
|
|
46
|
-
var data = this.uniqueKeysTracker;
|
|
47
|
-
this.uniqueKeysTracker = {};
|
|
48
|
-
return this.fromUniqueKeysCollector(data);
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* Check if the cache is empty.
|
|
52
|
-
*/
|
|
53
|
-
UniqueKeysCacheInMemoryCS.prototype.isEmpty = function () {
|
|
54
|
-
return Object.keys(this.uniqueKeysTracker).length === 0;
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Converts `uniqueKeys` data from cache into request payload.
|
|
58
|
-
*/
|
|
59
|
-
UniqueKeysCacheInMemoryCS.prototype.fromUniqueKeysCollector = function (uniqueKeys) {
|
|
60
|
-
var payload = [];
|
|
61
|
-
var featureKeys = Object.keys(uniqueKeys);
|
|
62
|
-
for (var k = 0; k < featureKeys.length; k++) {
|
|
63
|
-
var featureKey = featureKeys[k];
|
|
64
|
-
var featureNames = setToArray(uniqueKeys[featureKey]);
|
|
65
|
-
var uniqueKeysPayload = {
|
|
66
|
-
k: featureKey,
|
|
67
|
-
fs: featureNames
|
|
68
|
-
};
|
|
69
|
-
payload.push(uniqueKeysPayload);
|
|
70
|
-
}
|
|
71
|
-
return { keys: payload };
|
|
72
|
-
};
|
|
73
|
-
return UniqueKeysCacheInMemoryCS;
|
|
74
|
-
}());
|
|
75
|
-
export { UniqueKeysCacheInMemoryCS };
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { __extends } from "tslib";
|
|
2
|
-
import { ImpressionCountsCacheInMemory } from '../inMemory/ImpressionCountsCacheInMemory';
|
|
3
|
-
import { LOG_PREFIX, REFRESH_RATE, TTL_REFRESH } from './constants';
|
|
4
|
-
var ImpressionCountsCacheInRedis = /** @class */ (function (_super) {
|
|
5
|
-
__extends(ImpressionCountsCacheInRedis, _super);
|
|
6
|
-
function ImpressionCountsCacheInRedis(log, key, redis, impressionCountsCacheSize, refreshRate) {
|
|
7
|
-
if (refreshRate === void 0) { refreshRate = REFRESH_RATE; }
|
|
8
|
-
var _this = _super.call(this, impressionCountsCacheSize) || this;
|
|
9
|
-
_this.log = log;
|
|
10
|
-
_this.key = key;
|
|
11
|
-
_this.redis = redis;
|
|
12
|
-
_this.refreshRate = refreshRate;
|
|
13
|
-
_this.onFullQueue = function () { _this.postImpressionCountsInRedis(); };
|
|
14
|
-
return _this;
|
|
15
|
-
}
|
|
16
|
-
ImpressionCountsCacheInRedis.prototype.postImpressionCountsInRedis = function () {
|
|
17
|
-
var _this = this;
|
|
18
|
-
var counts = this.pop();
|
|
19
|
-
if (!counts)
|
|
20
|
-
return false;
|
|
21
|
-
var keys = Object.keys(counts);
|
|
22
|
-
var pipeline = this.redis.pipeline();
|
|
23
|
-
keys.forEach(function (key) {
|
|
24
|
-
pipeline.hincrby(_this.key, key, counts[key]);
|
|
25
|
-
});
|
|
26
|
-
return pipeline.exec()
|
|
27
|
-
.then(function (data) {
|
|
28
|
-
// If this is the creation of the key on Redis, set the expiration for it in 3600 seconds.
|
|
29
|
-
if (data.length && data.length === keys.length) {
|
|
30
|
-
return _this.redis.expire(_this.key, TTL_REFRESH);
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
.catch(function (err) {
|
|
34
|
-
_this.log.error(LOG_PREFIX + "Error in impression counts pipeline: " + err + ".");
|
|
35
|
-
return false;
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
ImpressionCountsCacheInRedis.prototype.start = function () {
|
|
39
|
-
this.intervalId = setInterval(this.postImpressionCountsInRedis.bind(this), this.refreshRate);
|
|
40
|
-
};
|
|
41
|
-
ImpressionCountsCacheInRedis.prototype.stop = function () {
|
|
42
|
-
clearInterval(this.intervalId);
|
|
43
|
-
};
|
|
44
|
-
return ImpressionCountsCacheInRedis;
|
|
45
|
-
}(ImpressionCountsCacheInMemory));
|
|
46
|
-
export { ImpressionCountsCacheInRedis };
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { __extends } from "tslib";
|
|
2
|
-
import { UniqueKeysCacheInMemory } from '../inMemory/uniqueKeysCacheInMemory';
|
|
3
|
-
import { setToArray } from '../../utils/lang/sets';
|
|
4
|
-
import { DEFAULT_CACHE_SIZE, REFRESH_RATE, TTL_REFRESH } from './constants';
|
|
5
|
-
import { LOG_PREFIX } from './constants';
|
|
6
|
-
var UniqueKeysCacheInRedis = /** @class */ (function (_super) {
|
|
7
|
-
__extends(UniqueKeysCacheInRedis, _super);
|
|
8
|
-
function UniqueKeysCacheInRedis(log, key, redis, uniqueKeysQueueSize, refreshRate) {
|
|
9
|
-
if (uniqueKeysQueueSize === void 0) { uniqueKeysQueueSize = DEFAULT_CACHE_SIZE; }
|
|
10
|
-
if (refreshRate === void 0) { refreshRate = REFRESH_RATE; }
|
|
11
|
-
var _this = _super.call(this, uniqueKeysQueueSize) || this;
|
|
12
|
-
_this.log = log;
|
|
13
|
-
_this.key = key;
|
|
14
|
-
_this.redis = redis;
|
|
15
|
-
_this.refreshRate = refreshRate;
|
|
16
|
-
_this.onFullQueue = function () { _this.postUniqueKeysInRedis(); };
|
|
17
|
-
return _this;
|
|
18
|
-
}
|
|
19
|
-
UniqueKeysCacheInRedis.prototype.postUniqueKeysInRedis = function () {
|
|
20
|
-
var _this = this;
|
|
21
|
-
var pipeline = this.redis.pipeline();
|
|
22
|
-
var featureNames = Object.keys(this.uniqueKeysTracker);
|
|
23
|
-
for (var i = 0; i < featureNames.length; i++) {
|
|
24
|
-
var featureName = featureNames[i];
|
|
25
|
-
var featureKeys = setToArray(this.uniqueKeysTracker[featureName]);
|
|
26
|
-
var uniqueKeysPayload = {
|
|
27
|
-
f: featureName,
|
|
28
|
-
ks: featureKeys
|
|
29
|
-
};
|
|
30
|
-
pipeline.rpush(this.key, JSON.stringify(uniqueKeysPayload));
|
|
31
|
-
}
|
|
32
|
-
this.clear();
|
|
33
|
-
return pipeline.exec()
|
|
34
|
-
.then(function (data) {
|
|
35
|
-
// If this is the creation of the key on Redis, set the expiration for it in 3600 seconds.
|
|
36
|
-
if (data.length && data.length === featureNames.length) {
|
|
37
|
-
return _this.redis.expire(_this.key, TTL_REFRESH);
|
|
38
|
-
}
|
|
39
|
-
})
|
|
40
|
-
.catch(function (err) {
|
|
41
|
-
_this.log.error(LOG_PREFIX + "Error in uniqueKeys pipeline: " + err + ".");
|
|
42
|
-
return false;
|
|
43
|
-
});
|
|
44
|
-
};
|
|
45
|
-
UniqueKeysCacheInRedis.prototype.start = function () {
|
|
46
|
-
this.intervalId = setInterval(this.postUniqueKeysInRedis.bind(this), this.refreshRate);
|
|
47
|
-
};
|
|
48
|
-
UniqueKeysCacheInRedis.prototype.stop = function () {
|
|
49
|
-
clearInterval(this.intervalId);
|
|
50
|
-
};
|
|
51
|
-
return UniqueKeysCacheInRedis;
|
|
52
|
-
}(UniqueKeysCacheInMemory));
|
|
53
|
-
export { UniqueKeysCacheInRedis };
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
|
|
2
|
-
import { submitterFactory } from './submitter';
|
|
3
|
-
var DATA_NAME = 'uniqueKeys';
|
|
4
|
-
/**
|
|
5
|
-
* Submitter that periodically posts impression counts
|
|
6
|
-
*/
|
|
7
|
-
export function uniqueKeysSubmitterFactory(params) {
|
|
8
|
-
var _a = params.settings, log = _a.log, uniqueKeysRefreshRate = _a.scheduler.uniqueKeysRefreshRate, key = _a.core.key, _b = params.splitApi, postUniqueKeysBulkCs = _b.postUniqueKeysBulkCs, postUniqueKeysBulkSs = _b.postUniqueKeysBulkSs, uniqueKeys = params.storage.uniqueKeys;
|
|
9
|
-
var isClientSide = key !== undefined;
|
|
10
|
-
var postUniqueKeysBulk = isClientSide ? postUniqueKeysBulkCs : postUniqueKeysBulkSs;
|
|
11
|
-
var syncTask = submitterFactory(log, postUniqueKeysBulk, uniqueKeys, uniqueKeysRefreshRate, 'unique keys');
|
|
12
|
-
// register unique keys submitter to be executed when uniqueKeys cache is full
|
|
13
|
-
uniqueKeys.setOnFullQueueCb(function () {
|
|
14
|
-
if (syncTask.isRunning()) {
|
|
15
|
-
log.info(SUBMITTERS_PUSH_FULL_QUEUE, [DATA_NAME]);
|
|
16
|
-
syncTask.execute();
|
|
17
|
-
}
|
|
18
|
-
// If submitter is stopped (e.g., user consent declined or unknown, or app state offline), we don't send the data.
|
|
19
|
-
// Data will be sent when submitter is resumed.
|
|
20
|
-
});
|
|
21
|
-
return syncTask;
|
|
22
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Debug strategy for impressions tracker. Wraps impressions to store and adds previousTime if it corresponds
|
|
3
|
-
*
|
|
4
|
-
* @param impressionsObserver impression observer. Previous time (pt property) is included in impression instances
|
|
5
|
-
* @returns IStrategyResult
|
|
6
|
-
*/
|
|
7
|
-
export function strategyDebugFactory(impressionsObserver) {
|
|
8
|
-
return {
|
|
9
|
-
process: function (impressions) {
|
|
10
|
-
impressions.forEach(function (impression) {
|
|
11
|
-
// Adds previous time if it is enabled
|
|
12
|
-
impression.pt = impressionsObserver.testAndSet(impression);
|
|
13
|
-
});
|
|
14
|
-
return {
|
|
15
|
-
impressionsToStore: impressions,
|
|
16
|
-
impressionsToListener: impressions,
|
|
17
|
-
deduped: 0
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* None strategy for impressions tracker.
|
|
3
|
-
*
|
|
4
|
-
* @param impressionsCounter cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
|
|
5
|
-
* @param uniqueKeysTracker unique keys tracker in charge of tracking the unique keys per split.
|
|
6
|
-
* @returns IStrategyResult
|
|
7
|
-
*/
|
|
8
|
-
export function strategyNoneFactory(impressionsCounter, uniqueKeysTracker) {
|
|
9
|
-
return {
|
|
10
|
-
process: function (impressions) {
|
|
11
|
-
impressions.forEach(function (impression) {
|
|
12
|
-
var now = Date.now();
|
|
13
|
-
// Increments impression counter per featureName
|
|
14
|
-
impressionsCounter.track(impression.feature, now, 1);
|
|
15
|
-
// Keep track by unique key
|
|
16
|
-
uniqueKeysTracker.track(impression.keyName, impression.feature);
|
|
17
|
-
});
|
|
18
|
-
return {
|
|
19
|
-
impressionsToStore: [],
|
|
20
|
-
impressionsToListener: impressions,
|
|
21
|
-
deduped: 0
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { truncateTimeFrame } from '../../utils/time';
|
|
2
|
-
/**
|
|
3
|
-
* Optimized strategy for impressions tracker. Wraps impressions to store and adds previousTime if it corresponds
|
|
4
|
-
*
|
|
5
|
-
* @param impressionsObserver impression observer. previous time (pt property) is included in impression instances
|
|
6
|
-
* @param impressionsCounter cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
|
|
7
|
-
* @returns IStrategyResult
|
|
8
|
-
*/
|
|
9
|
-
export function strategyOptimizedFactory(impressionsObserver, impressionsCounter) {
|
|
10
|
-
return {
|
|
11
|
-
process: function (impressions) {
|
|
12
|
-
var impressionsToStore = [];
|
|
13
|
-
impressions.forEach(function (impression) {
|
|
14
|
-
impression.pt = impressionsObserver.testAndSet(impression);
|
|
15
|
-
var now = Date.now();
|
|
16
|
-
// Increments impression counter per featureName
|
|
17
|
-
if (impression.pt)
|
|
18
|
-
impressionsCounter.track(impression.feature, now, 1);
|
|
19
|
-
// Checks if the impression should be added in queue to be sent
|
|
20
|
-
if (!impression.pt || impression.pt < truncateTimeFrame(now)) {
|
|
21
|
-
impressionsToStore.push(impression);
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
return {
|
|
25
|
-
impressionsToStore: impressionsToStore,
|
|
26
|
-
impressionsToListener: impressions,
|
|
27
|
-
deduped: impressions.length - impressionsToStore.length
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { LOG_PREFIX_UNIQUE_KEYS_TRACKER } from '../logger/constants';
|
|
2
|
-
var noopFilterAdapter = {
|
|
3
|
-
add: function () { return true; },
|
|
4
|
-
contains: function () { return true; },
|
|
5
|
-
clear: function () { }
|
|
6
|
-
};
|
|
7
|
-
/**
|
|
8
|
-
* Trackes uniques keys
|
|
9
|
-
* Unique Keys Tracker will be in charge of checking if the MTK was already sent to the BE in the last period
|
|
10
|
-
* or schedule to be sent; if not it will be added in an internal cache and sent in the next post.
|
|
11
|
-
*
|
|
12
|
-
* @param log Logger instance
|
|
13
|
-
* @param uniqueKeysCache cache to save unique keys
|
|
14
|
-
* @param filterAdapter filter adapter
|
|
15
|
-
*/
|
|
16
|
-
export function uniqueKeysTrackerFactory(log, uniqueKeysCache, filterAdapter) {
|
|
17
|
-
if (filterAdapter === void 0) { filterAdapter = noopFilterAdapter; }
|
|
18
|
-
var intervalId;
|
|
19
|
-
if (filterAdapter.refreshRate) {
|
|
20
|
-
intervalId = setInterval(filterAdapter.clear, filterAdapter.refreshRate);
|
|
21
|
-
}
|
|
22
|
-
return {
|
|
23
|
-
track: function (key, featureName) {
|
|
24
|
-
if (!filterAdapter.add(key, featureName)) {
|
|
25
|
-
log.debug(LOG_PREFIX_UNIQUE_KEYS_TRACKER + "The feature " + featureName + " and key " + key + " exist in the filter");
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
uniqueKeysCache.track(key, featureName);
|
|
29
|
-
},
|
|
30
|
-
stop: function () {
|
|
31
|
-
clearInterval(intervalId);
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { IUniqueKeysCacheBase } from '../types';
|
|
2
|
-
import { ISet, setToArray, _Set } from '../../utils/lang/sets';
|
|
3
|
-
import { UniqueKeysPayloadSs } from '../../sync/submitters/types';
|
|
4
|
-
import { DEFAULT_CACHE_SIZE } from '../inRedis/constants';
|
|
5
|
-
|
|
6
|
-
export class UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
|
|
7
|
-
|
|
8
|
-
protected onFullQueue?: () => void;
|
|
9
|
-
private readonly maxStorage: number;
|
|
10
|
-
private uniqueTrackerSize = 0;
|
|
11
|
-
protected uniqueKeysTracker: { [keys: string]: ISet<string> };
|
|
12
|
-
|
|
13
|
-
constructor(uniqueKeysQueueSize: number = DEFAULT_CACHE_SIZE) {
|
|
14
|
-
this.maxStorage = uniqueKeysQueueSize;
|
|
15
|
-
this.uniqueKeysTracker = {};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
setOnFullQueueCb(cb: () => void) {
|
|
19
|
-
this.onFullQueue = cb;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Store unique keys in sequential order
|
|
24
|
-
* key: string = feature name.
|
|
25
|
-
* value: Set<string> = set of unique keys.
|
|
26
|
-
*/
|
|
27
|
-
track(key: string, featureName: string) {
|
|
28
|
-
if (!this.uniqueKeysTracker[featureName]) this.uniqueKeysTracker[featureName] = new _Set();
|
|
29
|
-
const tracker = this.uniqueKeysTracker[featureName];
|
|
30
|
-
if (!tracker.has(key)) {
|
|
31
|
-
tracker.add(key);
|
|
32
|
-
this.uniqueTrackerSize++;
|
|
33
|
-
}
|
|
34
|
-
if (this.uniqueTrackerSize >= this.maxStorage && this.onFullQueue) {
|
|
35
|
-
this.uniqueTrackerSize = 0;
|
|
36
|
-
this.onFullQueue();
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Clear the data stored on the cache.
|
|
42
|
-
*/
|
|
43
|
-
clear() {
|
|
44
|
-
this.uniqueKeysTracker = {};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Pop the collected data, used as payload for posting.
|
|
49
|
-
*/
|
|
50
|
-
pop() {
|
|
51
|
-
const data = this.uniqueKeysTracker;
|
|
52
|
-
this.uniqueKeysTracker = {};
|
|
53
|
-
return this.fromUniqueKeysCollector(data);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Check if the cache is empty.
|
|
58
|
-
*/
|
|
59
|
-
isEmpty() {
|
|
60
|
-
return Object.keys(this.uniqueKeysTracker).length === 0;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Converts `uniqueKeys` data from cache into request payload for SS.
|
|
65
|
-
*/
|
|
66
|
-
private fromUniqueKeysCollector(uniqueKeys: { [featureName: string]: ISet<string> }): UniqueKeysPayloadSs {
|
|
67
|
-
const payload = [];
|
|
68
|
-
const featureNames = Object.keys(uniqueKeys);
|
|
69
|
-
for (let i = 0; i < featureNames.length; i++) {
|
|
70
|
-
const featureName = featureNames[i];
|
|
71
|
-
const featureKeys = setToArray(uniqueKeys[featureName]);
|
|
72
|
-
const uniqueKeysPayload = {
|
|
73
|
-
f: featureName,
|
|
74
|
-
ks: featureKeys
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
payload.push(uniqueKeysPayload);
|
|
78
|
-
}
|
|
79
|
-
return { keys: payload };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { IUniqueKeysCacheBase } from '../types';
|
|
2
|
-
import { ISet, setToArray, _Set } from '../../utils/lang/sets';
|
|
3
|
-
import { UniqueKeysPayloadCs } from '../../sync/submitters/types';
|
|
4
|
-
import { DEFAULT_CACHE_SIZE } from '../inRedis/constants';
|
|
5
|
-
|
|
6
|
-
export class UniqueKeysCacheInMemoryCS implements IUniqueKeysCacheBase {
|
|
7
|
-
|
|
8
|
-
private onFullQueue?: () => void;
|
|
9
|
-
private readonly maxStorage: number;
|
|
10
|
-
private uniqueTrackerSize = 0;
|
|
11
|
-
private uniqueKeysTracker: { [keys: string]: ISet<string> };
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
* @param impressionsQueueSize number of queued impressions to call onFullQueueCb.
|
|
16
|
-
* Default value is 0, that means no maximum value, in case we want to avoid this being triggered.
|
|
17
|
-
*/
|
|
18
|
-
constructor(uniqueKeysQueueSize: number = DEFAULT_CACHE_SIZE) {
|
|
19
|
-
this.maxStorage = uniqueKeysQueueSize;
|
|
20
|
-
this.uniqueKeysTracker = {};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
setOnFullQueueCb(cb: () => void) {
|
|
24
|
-
this.onFullQueue = cb;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Store unique keys in sequential order
|
|
29
|
-
* key: string = key.
|
|
30
|
-
* value: HashSet<string> = set of split names.
|
|
31
|
-
*/
|
|
32
|
-
track(key: string, featureName: string) {
|
|
33
|
-
|
|
34
|
-
if (!this.uniqueKeysTracker[key]) this.uniqueKeysTracker[key] = new _Set();
|
|
35
|
-
const tracker = this.uniqueKeysTracker[key];
|
|
36
|
-
if (!tracker.has(featureName)) {
|
|
37
|
-
tracker.add(featureName);
|
|
38
|
-
this.uniqueTrackerSize++;
|
|
39
|
-
}
|
|
40
|
-
if (this.uniqueTrackerSize >= this.maxStorage && this.onFullQueue) {
|
|
41
|
-
this.uniqueTrackerSize = 0;
|
|
42
|
-
this.onFullQueue();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Clear the data stored on the cache.
|
|
48
|
-
*/
|
|
49
|
-
clear() {
|
|
50
|
-
this.uniqueKeysTracker = {};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Pop the collected data, used as payload for posting.
|
|
55
|
-
*/
|
|
56
|
-
pop() {
|
|
57
|
-
const data = this.uniqueKeysTracker;
|
|
58
|
-
this.uniqueKeysTracker = {};
|
|
59
|
-
return this.fromUniqueKeysCollector(data);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Check if the cache is empty.
|
|
64
|
-
*/
|
|
65
|
-
isEmpty() {
|
|
66
|
-
return Object.keys(this.uniqueKeysTracker).length === 0;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Converts `uniqueKeys` data from cache into request payload.
|
|
71
|
-
*/
|
|
72
|
-
private fromUniqueKeysCollector(uniqueKeys: { [featureName: string]: ISet<string> }): UniqueKeysPayloadCs {
|
|
73
|
-
const payload = [];
|
|
74
|
-
const featureKeys = Object.keys(uniqueKeys);
|
|
75
|
-
for (let k = 0; k < featureKeys.length; k++) {
|
|
76
|
-
const featureKey = featureKeys[k];
|
|
77
|
-
const featureNames = setToArray(uniqueKeys[featureKey]);
|
|
78
|
-
const uniqueKeysPayload = {
|
|
79
|
-
k: featureKey,
|
|
80
|
-
fs: featureNames
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
payload.push(uniqueKeysPayload);
|
|
84
|
-
}
|
|
85
|
-
return { keys: payload };
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { Redis } from 'ioredis';
|
|
2
|
-
import { ILogger } from '../../logger/types';
|
|
3
|
-
import { ImpressionCountsCacheInMemory } from '../inMemory/ImpressionCountsCacheInMemory';
|
|
4
|
-
import { LOG_PREFIX, REFRESH_RATE, TTL_REFRESH } from './constants';
|
|
5
|
-
|
|
6
|
-
export class ImpressionCountsCacheInRedis extends ImpressionCountsCacheInMemory {
|
|
7
|
-
|
|
8
|
-
private readonly log: ILogger;
|
|
9
|
-
private readonly key: string;
|
|
10
|
-
private readonly redis: Redis;
|
|
11
|
-
private readonly refreshRate: number;
|
|
12
|
-
private intervalId: any;
|
|
13
|
-
|
|
14
|
-
constructor(log: ILogger, key: string, redis: Redis, impressionCountsCacheSize?: number, refreshRate: number = REFRESH_RATE) {
|
|
15
|
-
super(impressionCountsCacheSize);
|
|
16
|
-
this.log = log;
|
|
17
|
-
this.key = key;
|
|
18
|
-
this.redis = redis;
|
|
19
|
-
this.refreshRate = refreshRate;
|
|
20
|
-
this.onFullQueue = () => { this.postImpressionCountsInRedis(); };
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
postImpressionCountsInRedis(){
|
|
24
|
-
const counts = this.pop();
|
|
25
|
-
if (!counts) return false;
|
|
26
|
-
const keys = Object.keys(counts);
|
|
27
|
-
const pipeline = this.redis.pipeline();
|
|
28
|
-
keys.forEach(key => {
|
|
29
|
-
pipeline.hincrby(this.key, key, counts[key]);
|
|
30
|
-
});
|
|
31
|
-
return pipeline.exec()
|
|
32
|
-
.then(data => {
|
|
33
|
-
// If this is the creation of the key on Redis, set the expiration for it in 3600 seconds.
|
|
34
|
-
if (data.length && data.length === keys.length) {
|
|
35
|
-
return this.redis.expire(this.key, TTL_REFRESH);
|
|
36
|
-
}
|
|
37
|
-
})
|
|
38
|
-
.catch(err => {
|
|
39
|
-
this.log.error(`${LOG_PREFIX}Error in impression counts pipeline: ${err}.`);
|
|
40
|
-
return false;
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
start() {
|
|
45
|
-
this.intervalId = setInterval(this.postImpressionCountsInRedis.bind(this), this.refreshRate);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
stop() {
|
|
49
|
-
clearInterval(this.intervalId);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { IUniqueKeysCacheBase } from '../types';
|
|
2
|
-
import { Redis } from 'ioredis';
|
|
3
|
-
import { UniqueKeysCacheInMemory } from '../inMemory/uniqueKeysCacheInMemory';
|
|
4
|
-
import { setToArray } from '../../utils/lang/sets';
|
|
5
|
-
import { DEFAULT_CACHE_SIZE, REFRESH_RATE, TTL_REFRESH } from './constants';
|
|
6
|
-
import { LOG_PREFIX } from './constants';
|
|
7
|
-
import { ILogger } from '../../logger/types';
|
|
8
|
-
|
|
9
|
-
export class UniqueKeysCacheInRedis extends UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
|
|
10
|
-
|
|
11
|
-
private readonly log: ILogger;
|
|
12
|
-
private readonly key: string;
|
|
13
|
-
private readonly redis: Redis;
|
|
14
|
-
private readonly refreshRate: number;
|
|
15
|
-
private intervalId: any;
|
|
16
|
-
|
|
17
|
-
constructor(log: ILogger, key: string, redis: Redis, uniqueKeysQueueSize: number = DEFAULT_CACHE_SIZE, refreshRate: number = REFRESH_RATE) {
|
|
18
|
-
super(uniqueKeysQueueSize);
|
|
19
|
-
this.log = log;
|
|
20
|
-
this.key = key;
|
|
21
|
-
this.redis = redis;
|
|
22
|
-
this.refreshRate = refreshRate;
|
|
23
|
-
this.onFullQueue = () => {this.postUniqueKeysInRedis();};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
postUniqueKeysInRedis() {
|
|
27
|
-
const pipeline = this.redis.pipeline();
|
|
28
|
-
|
|
29
|
-
const featureNames = Object.keys(this.uniqueKeysTracker);
|
|
30
|
-
for (let i = 0; i < featureNames.length; i++) {
|
|
31
|
-
const featureName = featureNames[i];
|
|
32
|
-
const featureKeys = setToArray(this.uniqueKeysTracker[featureName]);
|
|
33
|
-
const uniqueKeysPayload = {
|
|
34
|
-
f: featureName,
|
|
35
|
-
ks: featureKeys
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
pipeline.rpush(this.key, JSON.stringify(uniqueKeysPayload));
|
|
39
|
-
}
|
|
40
|
-
this.clear();
|
|
41
|
-
return pipeline.exec()
|
|
42
|
-
.then(data => {
|
|
43
|
-
// If this is the creation of the key on Redis, set the expiration for it in 3600 seconds.
|
|
44
|
-
if (data.length && data.length === featureNames.length) {
|
|
45
|
-
return this.redis.expire(this.key, TTL_REFRESH);
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
.catch(err => {
|
|
49
|
-
this.log.error(`${LOG_PREFIX}Error in uniqueKeys pipeline: ${err}.`);
|
|
50
|
-
return false;
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
start() {
|
|
56
|
-
this.intervalId = setInterval(this.postUniqueKeysInRedis.bind(this), this.refreshRate);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
stop() {
|
|
60
|
-
clearInterval(this.intervalId);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
|
|
2
|
-
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
3
|
-
import { submitterFactory } from './submitter';
|
|
4
|
-
|
|
5
|
-
const DATA_NAME = 'uniqueKeys';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Submitter that periodically posts impression counts
|
|
9
|
-
*/
|
|
10
|
-
export function uniqueKeysSubmitterFactory(params: ISdkFactoryContextSync) {
|
|
11
|
-
|
|
12
|
-
const {
|
|
13
|
-
settings: { log, scheduler: { uniqueKeysRefreshRate }, core: {key}},
|
|
14
|
-
splitApi: { postUniqueKeysBulkCs, postUniqueKeysBulkSs },
|
|
15
|
-
storage: { uniqueKeys }
|
|
16
|
-
} = params;
|
|
17
|
-
|
|
18
|
-
const isClientSide = key !== undefined;
|
|
19
|
-
const postUniqueKeysBulk = isClientSide ? postUniqueKeysBulkCs : postUniqueKeysBulkSs;
|
|
20
|
-
|
|
21
|
-
const syncTask = submitterFactory(log, postUniqueKeysBulk, uniqueKeys!, uniqueKeysRefreshRate, 'unique keys');
|
|
22
|
-
|
|
23
|
-
// register unique keys submitter to be executed when uniqueKeys cache is full
|
|
24
|
-
uniqueKeys!.setOnFullQueueCb(() => {
|
|
25
|
-
if (syncTask.isRunning()) {
|
|
26
|
-
log.info(SUBMITTERS_PUSH_FULL_QUEUE, [DATA_NAME]);
|
|
27
|
-
syncTask.execute();
|
|
28
|
-
}
|
|
29
|
-
// If submitter is stopped (e.g., user consent declined or unknown, or app state offline), we don't send the data.
|
|
30
|
-
// Data will be sent when submitter is resumed.
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
return syncTask;
|
|
34
|
-
}
|
|
35
|
-
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { ImpressionDTO } from '../../types';
|
|
2
|
-
import { IImpressionObserver } from '../impressionObserver/types';
|
|
3
|
-
import { IStrategy } from '../types';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Debug strategy for impressions tracker. Wraps impressions to store and adds previousTime if it corresponds
|
|
7
|
-
*
|
|
8
|
-
* @param impressionsObserver impression observer. Previous time (pt property) is included in impression instances
|
|
9
|
-
* @returns IStrategyResult
|
|
10
|
-
*/
|
|
11
|
-
export function strategyDebugFactory(
|
|
12
|
-
impressionsObserver: IImpressionObserver
|
|
13
|
-
): IStrategy {
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
process(impressions: ImpressionDTO[]) {
|
|
17
|
-
impressions.forEach((impression) => {
|
|
18
|
-
// Adds previous time if it is enabled
|
|
19
|
-
impression.pt = impressionsObserver.testAndSet(impression);
|
|
20
|
-
});
|
|
21
|
-
return {
|
|
22
|
-
impressionsToStore: impressions,
|
|
23
|
-
impressionsToListener: impressions,
|
|
24
|
-
deduped: 0
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
}
|