@splitsoftware/splitio-commons 0.1.1-canary.9 → 0.1.1-rc.18
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/cjs/evaluator/matchers/matcherTypes.js +4 -4
- package/cjs/evaluator/matchersTransform/index.js +11 -11
- package/cjs/evaluator/value/sanitize.js +6 -6
- package/cjs/listeners/browser.js +1 -2
- package/cjs/listeners/node.js +0 -3
- package/cjs/logger/constants.js +3 -1
- package/cjs/logger/messages/error.js +3 -2
- package/cjs/logger/messages/info.js +2 -2
- package/cjs/logger/messages/warn.js +2 -1
- package/cjs/readiness/readinessManager.js +10 -7
- package/cjs/sdkFactory/index.js +1 -4
- package/cjs/services/splitApi.js +1 -1
- package/cjs/services/splitHttpClient.js +5 -4
- package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
- package/cjs/storages/inLocalStorage/index.js +5 -2
- package/cjs/storages/inMemory/InMemoryStorage.js +2 -0
- package/cjs/storages/inMemory/InMemoryStorageCS.js +2 -0
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +6 -2
- package/cjs/storages/inRedis/index.js +5 -2
- package/cjs/storages/pluggable/SplitsCachePluggable.js +6 -2
- package/cjs/storages/pluggable/inMemoryWrapper.js +6 -7
- package/cjs/storages/pluggable/index.js +5 -2
- package/cjs/storages/pluggable/wrapperAdapter.js +0 -1
- package/cjs/sync/offline/splitsParser/splitsParserFromFile.js +92 -89
- package/cjs/sync/offline/splitsParser/splitsParserFromSettings.js +45 -42
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +14 -4
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +30 -10
- package/cjs/sync/streaming/SSEClient/index.js +0 -11
- package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
- package/cjs/sync/streaming/SSEHandler/NotificationParser.js +4 -1
- package/cjs/sync/streaming/SSEHandler/index.js +8 -9
- package/cjs/sync/streaming/SSEHandler/types.js +14 -0
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
- package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
- package/cjs/sync/streaming/constants.js +3 -1
- package/cjs/sync/streaming/mySegmentsV2utils.js +75 -0
- package/cjs/sync/streaming/pushManager.js +141 -40
- package/cjs/sync/submitters/metricsSyncTask.js +1 -1
- package/cjs/sync/submitters/submitterSyncTask.js +2 -2
- package/cjs/sync/syncManagerFromFile.js +15 -0
- package/cjs/sync/syncManagerFromObject.js +14 -0
- package/cjs/sync/syncManagerOffline.js +3 -3
- package/cjs/sync/syncManagerOnline.js +5 -3
- package/cjs/trackers/impressionObserver/ImpressionObserver.js +0 -2
- package/cjs/trackers/impressionObserver/buildKey.js +3 -9
- package/cjs/trackers/impressionObserver/impressionObserverCS.js +2 -2
- package/cjs/trackers/impressionObserver/impressionObserverSS.js +3 -3
- package/cjs/utils/constants/index.js +4 -1
- package/cjs/utils/decompress/index.js +427 -0
- package/cjs/utils/murmur3/{commons.js → common.js} +2 -6
- package/cjs/utils/murmur3/murmur3.js +11 -12
- package/cjs/utils/murmur3/murmur3_128.js +7 -142
- package/cjs/utils/murmur3/murmur3_128_x86.js +154 -0
- package/cjs/utils/murmur3/murmur3_64.js +36 -0
- package/cjs/utils/murmur3/utfx.js +100 -106
- package/cjs/utils/promise/wrapper.js +14 -11
- package/cjs/utils/settingsValidation/index.js +5 -2
- package/cjs/utils/settingsValidation/localhost/index.js +20 -0
- package/cjs/utils/settingsValidation/splitFilters.js +0 -1
- package/cjs/utils/settingsValidation/storage/storageCS.js +18 -8
- package/cjs/utils/settingsValidation/url.js +1 -1
- package/esm/evaluator/matchers/matcherTypes.js +2 -2
- package/esm/evaluator/matchersTransform/index.js +12 -12
- package/esm/evaluator/value/sanitize.js +7 -7
- package/esm/listeners/browser.js +1 -2
- package/esm/listeners/node.js +0 -3
- package/esm/logger/constants.js +2 -0
- package/esm/logger/messages/error.js +3 -2
- package/esm/logger/messages/info.js +2 -2
- package/esm/logger/messages/warn.js +2 -1
- package/esm/readiness/readinessManager.js +10 -7
- package/esm/sdkFactory/index.js +1 -4
- package/esm/services/splitApi.js +1 -1
- package/esm/services/splitHttpClient.js +5 -4
- package/esm/storages/AbstractSplitsCacheSync.js +1 -1
- package/esm/storages/inLocalStorage/index.js +5 -2
- package/esm/storages/inMemory/InMemoryStorage.js +2 -0
- package/esm/storages/inMemory/InMemoryStorageCS.js +2 -0
- package/esm/storages/inRedis/SplitsCacheInRedis.js +6 -2
- package/esm/storages/inRedis/index.js +5 -2
- package/esm/storages/pluggable/SplitsCachePluggable.js +6 -2
- package/esm/storages/pluggable/inMemoryWrapper.js +6 -7
- package/esm/storages/pluggable/index.js +5 -2
- package/esm/storages/pluggable/wrapperAdapter.js +0 -1
- package/esm/sync/offline/splitsParser/splitsParserFromFile.js +90 -88
- package/esm/sync/offline/splitsParser/splitsParserFromSettings.js +43 -41
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +15 -5
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +30 -10
- package/esm/sync/streaming/SSEClient/index.js +0 -11
- package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
- package/esm/sync/streaming/SSEHandler/NotificationParser.js +4 -1
- package/esm/sync/streaming/SSEHandler/index.js +9 -10
- package/esm/sync/streaming/SSEHandler/types.js +13 -1
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
- package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
- package/esm/sync/streaming/constants.js +2 -0
- package/esm/sync/streaming/mySegmentsV2utils.js +69 -0
- package/esm/sync/streaming/pushManager.js +143 -42
- package/esm/sync/submitters/metricsSyncTask.js +1 -1
- package/esm/sync/submitters/submitterSyncTask.js +2 -2
- package/esm/sync/syncManagerFromFile.js +11 -0
- package/esm/sync/syncManagerFromObject.js +10 -0
- package/esm/sync/syncManagerOffline.js +3 -3
- package/esm/sync/syncManagerOnline.js +5 -3
- package/esm/trackers/impressionObserver/ImpressionObserver.js +0 -2
- package/esm/trackers/impressionObserver/buildKey.js +2 -9
- package/esm/trackers/impressionObserver/impressionObserverCS.js +2 -2
- package/esm/trackers/impressionObserver/impressionObserverSS.js +3 -3
- package/esm/utils/constants/index.js +3 -0
- package/esm/utils/decompress/index.js +424 -0
- package/esm/utils/murmur3/{commons.js → common.js} +1 -4
- package/esm/utils/murmur3/murmur3.js +1 -2
- package/esm/utils/murmur3/murmur3_128.js +7 -142
- package/esm/utils/murmur3/murmur3_128_x86.js +150 -0
- package/esm/utils/murmur3/murmur3_64.js +32 -0
- package/esm/utils/murmur3/utfx.js +96 -106
- package/esm/utils/promise/wrapper.js +14 -11
- package/esm/utils/settingsValidation/index.js +5 -2
- package/esm/utils/settingsValidation/localhost/index.js +16 -0
- package/esm/utils/settingsValidation/splitFilters.js +0 -1
- package/esm/utils/settingsValidation/storage/storageCS.js +16 -7
- package/esm/utils/settingsValidation/url.js +1 -1
- package/package.json +5 -5
- package/src/evaluator/matchers/matcherTypes.ts +2 -2
- package/src/evaluator/matchersTransform/index.ts +12 -12
- package/src/evaluator/value/sanitize.ts +7 -7
- package/src/listeners/browser.ts +1 -1
- package/src/listeners/node.ts +1 -2
- package/src/logger/constants.ts +2 -0
- package/src/logger/messages/error.ts +3 -2
- package/src/logger/messages/info.ts +2 -2
- package/src/logger/messages/warn.ts +3 -1
- package/src/readiness/readinessManager.ts +9 -7
- package/src/sdkFactory/index.ts +1 -3
- package/src/sdkFactory/types.ts +3 -3
- package/src/services/splitApi.ts +2 -3
- package/src/services/splitHttpClient.ts +6 -5
- package/src/services/types.ts +5 -5
- package/src/storages/AbstractSplitsCacheSync.ts +1 -1
- package/src/storages/inLocalStorage/index.ts +8 -4
- package/src/storages/inMemory/InMemoryStorage.ts +3 -0
- package/src/storages/inMemory/InMemoryStorageCS.ts +3 -0
- package/src/storages/inRedis/SplitsCacheInRedis.ts +3 -1
- package/src/storages/inRedis/index.ts +8 -4
- package/src/storages/pluggable/SplitsCachePluggable.ts +3 -1
- package/src/storages/pluggable/inMemoryWrapper.ts +6 -7
- package/src/storages/pluggable/index.ts +8 -4
- package/src/storages/pluggable/wrapperAdapter.ts +0 -1
- package/src/storages/types.ts +18 -15
- package/src/sync/offline/splitsParser/splitsParserFromFile.ts +110 -105
- package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +45 -41
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +15 -5
- package/src/sync/polling/types.ts +2 -1
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +28 -10
- package/src/sync/streaming/AuthClient/types.ts +3 -0
- package/src/sync/streaming/SSEClient/index.ts +1 -15
- package/src/sync/streaming/SSEClient/types.ts +0 -1
- package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +8 -0
- package/src/sync/streaming/SSEHandler/NotificationParser.ts +4 -2
- package/src/sync/streaming/SSEHandler/index.ts +11 -20
- package/src/sync/streaming/SSEHandler/types.ts +37 -3
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +7 -6
- package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +2 -1
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +4 -3
- package/src/sync/streaming/UpdateWorkers/types.ts +1 -1
- package/src/sync/streaming/constants.ts +2 -0
- package/src/sync/streaming/mySegmentsV2utils.ts +77 -0
- package/src/sync/streaming/pushManager.ts +139 -42
- package/src/sync/streaming/types.ts +14 -22
- package/src/sync/submitters/metricsSyncTask.ts +1 -1
- package/src/sync/submitters/submitterSyncTask.ts +2 -1
- package/src/sync/syncManagerFromFile.ts +13 -0
- package/src/sync/syncManagerFromObject.ts +12 -0
- package/src/sync/syncManagerOffline.ts +3 -3
- package/src/sync/syncManagerOnline.ts +6 -3
- package/src/trackers/impressionObserver/ImpressionObserver.ts +4 -6
- package/src/trackers/impressionObserver/buildKey.ts +2 -16
- package/src/trackers/impressionObserver/impressionObserverCS.ts +2 -2
- package/src/trackers/impressionObserver/impressionObserverSS.ts +3 -3
- package/src/types.ts +16 -2
- package/src/utils/constants/index.ts +6 -1
- package/src/utils/decompress/index.ts +429 -0
- package/src/utils/murmur3/{commons.ts → common.ts} +1 -5
- package/src/utils/murmur3/murmur3.ts +5 -5
- package/src/utils/murmur3/murmur3_128.ts +7 -180
- package/src/utils/murmur3/murmur3_128_x86.ts +188 -0
- package/src/utils/murmur3/murmur3_64.ts +36 -0
- package/src/utils/murmur3/utfx.ts +92 -110
- package/src/utils/promise/wrapper.ts +12 -9
- package/src/utils/settingsValidation/index.ts +8 -4
- package/src/utils/settingsValidation/localhost/index.ts +19 -0
- package/src/utils/settingsValidation/splitFilters.ts +0 -1
- package/src/utils/settingsValidation/storage/storageCS.ts +21 -8
- package/src/utils/settingsValidation/types.ts +2 -11
- package/src/utils/settingsValidation/url.ts +1 -1
- package/types/evaluator/matchers/matcherTypes.d.ts +2 -2
- package/types/listeners/browser.d.ts +1 -0
- package/types/listeners/node.d.ts +0 -1
- package/types/logger/constants.d.ts +2 -0
- package/types/sdkFactory/types.d.ts +3 -3
- package/types/services/types.d.ts +1 -0
- package/types/storages/inLocalStorage/index.d.ts +2 -2
- package/types/storages/inMemory/InMemoryStorage.d.ts +3 -0
- package/types/storages/inMemory/InMemoryStorageCS.d.ts +3 -0
- package/types/storages/inRedis/index.d.ts +2 -2
- package/types/storages/pluggable/index.d.ts +2 -2
- package/types/storages/types.d.ts +15 -15
- package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -7
- package/types/sync/offline/splitsParser/splitsParserFromSettings.d.ts +1 -5
- package/types/sync/polling/types.d.ts +2 -1
- package/types/sync/streaming/AuthClient/indexV1.d.ts +12 -0
- package/types/sync/streaming/AuthClient/indexV2.d.ts +8 -0
- package/types/sync/streaming/AuthClient/types.d.ts +2 -0
- package/types/sync/streaming/SSEClient/index.d.ts +1 -9
- package/types/sync/streaming/SSEClient/types.d.ts +0 -1
- package/types/sync/streaming/SSEHandler/NotificationParser.d.ts +3 -2
- package/types/sync/streaming/SSEHandler/types.d.ts +30 -2
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +4 -3
- package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +2 -1
- package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +3 -2
- package/types/sync/streaming/UpdateWorkers/types.d.ts +1 -1
- package/types/sync/streaming/constants.d.ts +3 -1
- package/types/sync/streaming/mySegmentsV2utils.d.ts +27 -0
- package/types/sync/streaming/pushManagerNoUsers.d.ts +13 -0
- package/types/sync/streaming/types.d.ts +9 -5
- package/types/sync/submitters/submitterSyncTask.d.ts +1 -1
- package/types/sync/syncManagerFromFile.d.ts +2 -0
- package/types/sync/syncManagerFromObject.d.ts +2 -0
- package/types/sync/syncManagerOffline.d.ts +1 -1
- package/types/trackers/impressionObserver/ImpressionObserver.d.ts +2 -2
- package/types/trackers/impressionObserver/buildKey.d.ts +1 -1
- package/types/trackers/impressionObserver/impressionObserverCS.d.ts +2 -2
- package/types/trackers/impressionObserver/impressionObserverSS.d.ts +2 -2
- package/types/types.d.ts +16 -2
- package/types/utils/constants/index.d.ts +5 -1
- package/types/utils/decompress/index.d.ts +16 -0
- package/types/utils/murmur3/common.d.ts +12 -0
- package/types/utils/murmur3/murmur3.d.ts +2 -2
- package/types/utils/murmur3/murmur3_128.d.ts +5 -0
- package/types/utils/murmur3/murmur3_128_x86.d.ts +7 -0
- package/types/utils/murmur3/murmur3_64.d.ts +10 -0
- package/types/utils/murmur3/utfx.d.ts +24 -6
- package/types/utils/settingsValidation/index.d.ts +3 -2
- package/types/utils/settingsValidation/localhost/index.d.ts +9 -0
- package/types/utils/settingsValidation/storage/storageCS.d.ts +7 -1
- package/types/utils/settingsValidation/types.d.ts +2 -10
- package/cjs/sync/streaming/pushManagerCS.js +0 -179
- package/cjs/sync/streaming/pushManagerSS.js +0 -128
- package/esm/sync/streaming/pushManagerCS.js +0 -175
- package/esm/sync/streaming/pushManagerSS.js +0 -124
- package/src/sync/streaming/pushManagerCS.ts +0 -238
- package/src/sync/streaming/pushManagerSS.ts +0 -177
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { findIndex } from '../../utils/lang';
|
|
2
|
-
import { matcherTypes,
|
|
2
|
+
import { matcherTypes, matcherTypesMapper, matcherDataTypes } from '../matchers/matcherTypes';
|
|
3
3
|
import segmentTransform from './segment';
|
|
4
4
|
import whitelistTransform from './whitelist';
|
|
5
5
|
import setTransform from './set';
|
|
@@ -28,9 +28,9 @@ export default function matchersTransform(matchers: ISplitMatcher[]): IMatcherDt
|
|
|
28
28
|
} = matcher;
|
|
29
29
|
|
|
30
30
|
let attribute = keySelector && keySelector.attribute;
|
|
31
|
-
let type =
|
|
31
|
+
let type = matcherTypesMapper(matcherType);
|
|
32
32
|
// As default input data type we use string (even for ALL_KEYS)
|
|
33
|
-
let dataType =
|
|
33
|
+
let dataType = matcherDataTypes.STRING;
|
|
34
34
|
let value = undefined;
|
|
35
35
|
|
|
36
36
|
if (type === matcherTypes.IN_SEGMENT) {
|
|
@@ -39,29 +39,29 @@ export default function matchersTransform(matchers: ISplitMatcher[]): IMatcherDt
|
|
|
39
39
|
value = whitelistTransform(whitelistObject as IWhitelistMatcherData);
|
|
40
40
|
} else if (type === matcherTypes.EQUAL_TO) {
|
|
41
41
|
value = numericTransform(unaryNumericObject as IUnaryNumericMatcherData);
|
|
42
|
-
dataType =
|
|
42
|
+
dataType = matcherDataTypes.NUMBER;
|
|
43
43
|
|
|
44
44
|
if ((unaryNumericObject as IUnaryNumericMatcherData).dataType === 'DATETIME') {
|
|
45
45
|
value = zeroSinceHH(value);
|
|
46
|
-
dataType =
|
|
46
|
+
dataType = matcherDataTypes.DATETIME;
|
|
47
47
|
}
|
|
48
48
|
} else if (type === matcherTypes.GREATER_THAN_OR_EQUAL_TO ||
|
|
49
49
|
type === matcherTypes.LESS_THAN_OR_EQUAL_TO) {
|
|
50
50
|
value = numericTransform(unaryNumericObject as IUnaryNumericMatcherData);
|
|
51
|
-
dataType =
|
|
51
|
+
dataType = matcherDataTypes.NUMBER;
|
|
52
52
|
|
|
53
53
|
if ((unaryNumericObject as IUnaryNumericMatcherData).dataType === 'DATETIME') {
|
|
54
54
|
value = zeroSinceSS(value);
|
|
55
|
-
dataType =
|
|
55
|
+
dataType = matcherDataTypes.DATETIME;
|
|
56
56
|
}
|
|
57
57
|
} else if (type === matcherTypes.BETWEEN) {
|
|
58
58
|
value = betweenObject as IBetweenMatcherData;
|
|
59
|
-
dataType =
|
|
59
|
+
dataType = matcherDataTypes.NUMBER;
|
|
60
60
|
|
|
61
61
|
if (value.dataType === 'DATETIME') {
|
|
62
62
|
value.start = zeroSinceSS(value.start);
|
|
63
63
|
value.end = zeroSinceSS(value.end);
|
|
64
|
-
dataType =
|
|
64
|
+
dataType = matcherDataTypes.DATETIME;
|
|
65
65
|
}
|
|
66
66
|
} else if (
|
|
67
67
|
type === matcherTypes.EQUAL_TO_SET ||
|
|
@@ -70,7 +70,7 @@ export default function matchersTransform(matchers: ISplitMatcher[]): IMatcherDt
|
|
|
70
70
|
type === matcherTypes.PART_OF_SET
|
|
71
71
|
) {
|
|
72
72
|
value = setTransform(whitelistObject as IWhitelistMatcherData);
|
|
73
|
-
dataType =
|
|
73
|
+
dataType = matcherDataTypes.SET;
|
|
74
74
|
} else if (
|
|
75
75
|
type === matcherTypes.STARTS_WITH ||
|
|
76
76
|
type === matcherTypes.ENDS_WITH ||
|
|
@@ -79,9 +79,9 @@ export default function matchersTransform(matchers: ISplitMatcher[]): IMatcherDt
|
|
|
79
79
|
value = setTransform(whitelistObject as IWhitelistMatcherData);
|
|
80
80
|
} else if (type === matcherTypes.IN_SPLIT_TREATMENT) {
|
|
81
81
|
value = dependencyObject;
|
|
82
|
-
dataType =
|
|
82
|
+
dataType = matcherDataTypes.NOT_SPECIFIED;
|
|
83
83
|
} else if (type === matcherTypes.EQUAL_TO_BOOLEAN) {
|
|
84
|
-
dataType =
|
|
84
|
+
dataType = matcherDataTypes.BOOLEAN;
|
|
85
85
|
value = booleanMatcherData;
|
|
86
86
|
} else if (type === matcherTypes.MATCHES_STRING) {
|
|
87
87
|
value = stringMatcherData;
|
|
@@ -3,7 +3,7 @@ import { IDependencyMatcherValue } from '../types';
|
|
|
3
3
|
import { ILogger } from '../../logger/types';
|
|
4
4
|
import { isObject, uniq, toString, toNumber } from '../../utils/lang';
|
|
5
5
|
import { zeroSinceHH, zeroSinceSS } from '../convertions';
|
|
6
|
-
import { matcherTypes,
|
|
6
|
+
import { matcherTypes, matcherDataTypes } from '../matchers/matcherTypes';
|
|
7
7
|
import { ENGINE_SANITIZE } from '../../logger/constants';
|
|
8
8
|
|
|
9
9
|
function sanitizeNumber(val: any): number | undefined {
|
|
@@ -74,20 +74,20 @@ export default function sanitize(log: ILogger, matcherTypeID: number, value: str
|
|
|
74
74
|
let sanitizedValue: string | number | boolean | Array<string | number> | IDependencyMatcherValue | undefined;
|
|
75
75
|
|
|
76
76
|
switch (dataType) {
|
|
77
|
-
case
|
|
78
|
-
case
|
|
77
|
+
case matcherDataTypes.NUMBER:
|
|
78
|
+
case matcherDataTypes.DATETIME:
|
|
79
79
|
sanitizedValue = sanitizeNumber(value);
|
|
80
80
|
break;
|
|
81
|
-
case
|
|
81
|
+
case matcherDataTypes.STRING:
|
|
82
82
|
sanitizedValue = sanitizeString(value);
|
|
83
83
|
break;
|
|
84
|
-
case
|
|
84
|
+
case matcherDataTypes.SET:
|
|
85
85
|
sanitizedValue = sanitizeArray(value);
|
|
86
86
|
break;
|
|
87
|
-
case
|
|
87
|
+
case matcherDataTypes.BOOLEAN:
|
|
88
88
|
sanitizedValue = sanitizeBoolean(value);
|
|
89
89
|
break;
|
|
90
|
-
case
|
|
90
|
+
case matcherDataTypes.NOT_SPECIFIED:
|
|
91
91
|
sanitizedValue = value;
|
|
92
92
|
break;
|
|
93
93
|
default:
|
package/src/listeners/browser.ts
CHANGED
|
@@ -39,7 +39,6 @@ export default class BrowserSignalListener implements ISignalListener {
|
|
|
39
39
|
* We add a handler on unload events. The handler flushes remaining impressions and events to the backend.
|
|
40
40
|
*/
|
|
41
41
|
start() {
|
|
42
|
-
this.syncManager?.start();
|
|
43
42
|
if (typeof window !== 'undefined' && window.addEventListener) {
|
|
44
43
|
this.settings.log.debug(CLEANUP_REGISTERING, [EVENT_NAME]);
|
|
45
44
|
window.addEventListener(UNLOAD_DOM_EVENT, this.flushData);
|
|
@@ -49,6 +48,7 @@ export default class BrowserSignalListener implements ISignalListener {
|
|
|
49
48
|
/**
|
|
50
49
|
* stop method.
|
|
51
50
|
* Called when client is destroyed.
|
|
51
|
+
* We need to remove the handler for unload events, since it can break if called when Split context was destroyed.
|
|
52
52
|
*/
|
|
53
53
|
stop() {
|
|
54
54
|
if (typeof window !== 'undefined' && window.removeEventListener) {
|
package/src/listeners/node.ts
CHANGED
|
@@ -22,7 +22,7 @@ export default class NodeSignalListener implements ISignalListener {
|
|
|
22
22
|
private settings: ISettings;
|
|
23
23
|
|
|
24
24
|
constructor(
|
|
25
|
-
|
|
25
|
+
syncManager: ISyncManager | undefined, // private handler: () => MaybeThenable<void>,
|
|
26
26
|
settings: ISettings
|
|
27
27
|
) {
|
|
28
28
|
// @TODO review handler logic when implementing Node SDK
|
|
@@ -37,7 +37,6 @@ export default class NodeSignalListener implements ISignalListener {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
start() {
|
|
40
|
-
this.syncManager?.start();
|
|
41
40
|
this.settings.log.debug(CLEANUP_REGISTERING, [EVENT_NAME]);
|
|
42
41
|
// eslint-disable-next-line no-undef
|
|
43
42
|
process.on(SIGTERM, this._sigtermHandler);
|
package/src/logger/constants.ts
CHANGED
|
@@ -93,6 +93,7 @@ export const WARN_SPLITS_FILTER_INVALID = 220;
|
|
|
93
93
|
export const WARN_SPLITS_FILTER_EMPTY = 221;
|
|
94
94
|
export const WARN_STORAGE_INVALID = 222;
|
|
95
95
|
export const WARN_API_KEY = 223;
|
|
96
|
+
export const STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = 224;
|
|
96
97
|
|
|
97
98
|
export const ERROR_ENGINE_COMBINER_IFELSEIF = 300;
|
|
98
99
|
export const ERROR_LOGLEVEL_INVALID = 301;
|
|
@@ -117,6 +118,7 @@ export const ERROR_EMPTY = 319;
|
|
|
117
118
|
export const ERROR_EMPTY_ARRAY = 320;
|
|
118
119
|
export const ERROR_INVALID_IMPRESSIONS_MODE = 321;
|
|
119
120
|
export const ERROR_HTTP = 322;
|
|
121
|
+
export const ERROR_LOCALHOST_MODULE_REQUIRED = 323;
|
|
120
122
|
|
|
121
123
|
// Log prefixes (a.k.a. tags or categories)
|
|
122
124
|
export const LOG_PREFIX_SETTINGS = 'settings';
|
|
@@ -11,8 +11,8 @@ export const codesError: [number, string][] = [
|
|
|
11
11
|
[c.ERROR_EVENTS_TRACKER, c.LOG_PREFIX_EVENTS_TRACKER + 'Failed to queue %s'],
|
|
12
12
|
// synchronizer
|
|
13
13
|
[c.ERROR_SYNC_OFFLINE_LOADING, c.LOG_PREFIX_SYNC_OFFLINE + 'There was an issue loading the mock Splits data, no changes will be applied to the current cache. %s'],
|
|
14
|
-
[c.ERROR_STREAMING_SSE, c.LOG_PREFIX_SYNC_STREAMING + '
|
|
15
|
-
[c.ERROR_STREAMING_AUTH, c.LOG_PREFIX_SYNC_STREAMING + 'Failed to authenticate for streaming. Error:
|
|
14
|
+
[c.ERROR_STREAMING_SSE, c.LOG_PREFIX_SYNC_STREAMING + 'Failed to connect or error on streaming connection, with error message: %s'],
|
|
15
|
+
[c.ERROR_STREAMING_AUTH, c.LOG_PREFIX_SYNC_STREAMING + 'Failed to authenticate for streaming. Error: %s.'],
|
|
16
16
|
[c.ERROR_HTTP, ' Response status is not OK. Status: %s. URL: %s. Message: %s'],
|
|
17
17
|
// client status
|
|
18
18
|
[c.ERROR_CLIENT_LISTENER, 'A listener was added for %s on the SDK, which has already fired and won\'t be emitted again. The callback won\'t be executed.'],
|
|
@@ -30,4 +30,5 @@ export const codesError: [number, string][] = [
|
|
|
30
30
|
[c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
|
|
31
31
|
// initialization / settings validation
|
|
32
32
|
[c.ERROR_INVALID_IMPRESSIONS_MODE, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "impressionsMode". It should be one of the following values: %s. Defaulting to "%s" mode.'],
|
|
33
|
+
[c.ERROR_LOCALHOST_MODULE_REQUIRED, c.LOG_PREFIX_SETTINGS + ': you didn\'t pass a valid "sync.localhostMode". It should be defined for using the SDK in localhost mode']
|
|
33
34
|
];
|
|
@@ -22,9 +22,9 @@ export const codesInfo: [number, string][] = codesWarn.concat([
|
|
|
22
22
|
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of splits #%s. Reason: %s'],
|
|
23
23
|
[c.SUBMITTERS_PUSH_FULL_EVENTS_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full events queue and reseting timer.'],
|
|
24
24
|
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s %s.'],
|
|
25
|
-
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds.'],
|
|
25
|
+
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
|
|
26
26
|
[c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect in %s seconds.'],
|
|
27
|
-
[c.STREAMING_CONNECTING, c.LOG_PREFIX_SYNC_STREAMING + '
|
|
27
|
+
[c.STREAMING_CONNECTING, c.LOG_PREFIX_SYNC_STREAMING + '%sConnecting to streaming.'],
|
|
28
28
|
[c.STREAMING_DISABLED, c.LOG_PREFIX_SYNC_STREAMING + 'Streaming is disabled for given Api key. Switching to polling mode.'],
|
|
29
29
|
[c.STREAMING_DISCONNECTING, c.LOG_PREFIX_SYNC_STREAMING + 'Disconnecting from streaming.'],
|
|
30
30
|
[c.SYNC_START_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming not available. Starting polling.'],
|
|
@@ -30,5 +30,7 @@ export const codesWarn: [number, string][] = codesError.concat([
|
|
|
30
30
|
[c.WARN_SPLITS_FILTER_INVALID, c.LOG_PREFIX_SETTINGS+': split filter at position %s is invalid. It must be an object with a valid filter type ("byName" or "byPrefix") and a list of "values".'],
|
|
31
31
|
[c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS+': splitFilters configuration must be a non-empty array of filter objects.'],
|
|
32
32
|
[c.WARN_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS+': The provided storage is invalid. Fallbacking into default MEMORY storage'],
|
|
33
|
-
[c.WARN_API_KEY, c.LOG_PREFIX_SETTINGS+': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application']
|
|
33
|
+
[c.WARN_API_KEY, c.LOG_PREFIX_SETTINGS+': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application'],
|
|
34
|
+
|
|
35
|
+
[c.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching MySegments due to an error processing %s notification: %s'],
|
|
34
36
|
]);
|
|
@@ -41,7 +41,7 @@ export function readinessManagerFactory(
|
|
|
41
41
|
|
|
42
42
|
// emit SDK_READY_FROM_CACHE
|
|
43
43
|
let isReadyFromCache = false;
|
|
44
|
-
if (splits.splitsCacheLoaded)
|
|
44
|
+
if (splits.splitsCacheLoaded) isReadyFromCache = true; // ready from cache, but doesn't emit SDK_READY_FROM_CACHE
|
|
45
45
|
else splits.once(SDK_SPLITS_CACHE_LOADED, checkIsReadyFromCache);
|
|
46
46
|
|
|
47
47
|
// emit SDK_READY_TIMED_OUT
|
|
@@ -62,13 +62,15 @@ export function readinessManagerFactory(
|
|
|
62
62
|
let isDestroyed = false;
|
|
63
63
|
|
|
64
64
|
function checkIsReadyFromCache() {
|
|
65
|
-
|
|
66
|
-
if
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
isReadyFromCache = true;
|
|
65
|
+
isReadyFromCache = true;
|
|
66
|
+
// Don't emit SDK_READY_FROM_CACHE if SDK_READY has been emitted
|
|
67
|
+
if (!isReady) {
|
|
68
|
+
try {
|
|
70
69
|
gate.emit(SDK_READY_FROM_CACHE);
|
|
71
|
-
}
|
|
70
|
+
} catch (e) {
|
|
71
|
+
// throws user callback exceptions in next tick
|
|
72
|
+
setTimeout(() => { throw e; }, 0);
|
|
73
|
+
}
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
|
package/src/sdkFactory/index.ts
CHANGED
|
@@ -78,9 +78,7 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
78
78
|
const clientMethod = sdkClientMethodFactory({ eventTracker, impressionsTracker, sdkReadinessManager, settings, storage, syncManager, signalListener });
|
|
79
79
|
const managerInstance = sdkManagerFactory(log, storage.splits, sdkReadinessManager);
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
// It is required for RN to consider the app state when the SDK is instantiated (foreground/background).
|
|
83
|
-
if (syncManager && !signalListener) syncManager.start();
|
|
81
|
+
syncManager && syncManager.start();
|
|
84
82
|
signalListener && signalListener.start();
|
|
85
83
|
|
|
86
84
|
log.info(NEW_FACTORY);
|
package/src/sdkFactory/types.ts
CHANGED
|
@@ -8,10 +8,10 @@ import { IStorageAsync, IStorageSync, ISplitsCacheSync, ISplitsCacheAsync, IStor
|
|
|
8
8
|
import { ISyncManager, ISyncManagerFactoryParams } from '../sync/types';
|
|
9
9
|
import { IImpressionObserver } from '../trackers/impressionObserver/types';
|
|
10
10
|
import { SplitIO, ISettings, IEventEmitter } from '../types';
|
|
11
|
-
import { ISettingsInternal } from '../utils/settingsValidation/types';
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
|
-
* Environment related dependencies
|
|
13
|
+
* Environment related dependencies.
|
|
14
|
+
* These getters are called a fixed number of times per factory instantiation.
|
|
15
15
|
*/
|
|
16
16
|
export interface IPlatform {
|
|
17
17
|
getOptions?: () => object
|
|
@@ -26,7 +26,7 @@ export interface IPlatform {
|
|
|
26
26
|
export interface ISdkFactoryParams {
|
|
27
27
|
|
|
28
28
|
// The settings must be already validated
|
|
29
|
-
settings:
|
|
29
|
+
settings: ISettings,
|
|
30
30
|
|
|
31
31
|
// Platform dependencies
|
|
32
32
|
platform: IPlatform,
|
package/src/services/splitApi.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { IPlatform } from '../sdkFactory/types';
|
|
|
2
2
|
import { ISettings } from '../types';
|
|
3
3
|
import { splitHttpClientFactory } from './splitHttpClient';
|
|
4
4
|
import { ISplitApi } from './types';
|
|
5
|
-
import { ISettingsInternal } from '../utils/settingsValidation/types';
|
|
6
5
|
import objectAssign from 'object-assign';
|
|
7
6
|
|
|
8
7
|
const noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
@@ -20,7 +19,7 @@ function userKeyToQueryParam(userKey: string) {
|
|
|
20
19
|
export function splitApiFactory(settings: ISettings, platform: Pick<IPlatform, 'getFetch' | 'getOptions'>): ISplitApi {
|
|
21
20
|
|
|
22
21
|
const urls = settings.urls;
|
|
23
|
-
const filterQueryString =
|
|
22
|
+
const filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
|
|
24
23
|
const SplitSDKImpressionsMode = settings.sync.impressionsMode;
|
|
25
24
|
const splitHttpClient = splitHttpClientFactory(settings, platform.getFetch, platform.getOptions);
|
|
26
25
|
|
|
@@ -36,7 +35,7 @@ export function splitApiFactory(settings: ISettings, platform: Pick<IPlatform, '
|
|
|
36
35
|
},
|
|
37
36
|
|
|
38
37
|
fetchAuth(userMatchingKeys?: string[]) {
|
|
39
|
-
let url = `${urls.auth}/auth`;
|
|
38
|
+
let url = `${urls.auth}/v2/auth`;
|
|
40
39
|
if (userMatchingKeys) { // accounting the possibility that `userMatchingKeys` is undefined (server-side API)
|
|
41
40
|
const queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
|
|
42
41
|
if (queryParams) // accounting the possibility that `userKeys` and thus `queryParams` are empty
|
|
@@ -43,8 +43,8 @@ export function splitHttpClientFactory(settings: Pick<ISettings, 'log' | 'versio
|
|
|
43
43
|
return fetch ? fetch(url, request)
|
|
44
44
|
// https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful
|
|
45
45
|
.then(response => {
|
|
46
|
-
if (!response.ok) {
|
|
47
|
-
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
return response.text().then(message => Promise.reject({ response, message }));
|
|
48
48
|
}
|
|
49
49
|
return response;
|
|
50
50
|
})
|
|
@@ -56,18 +56,19 @@ export function splitHttpClientFactory(settings: Pick<ISettings, 'log' | 'versio
|
|
|
56
56
|
switch (resp.status) {
|
|
57
57
|
case 404: msg = 'Invalid API key or resource not found.';
|
|
58
58
|
break;
|
|
59
|
-
|
|
59
|
+
// Don't use resp.statusText since reason phrase is removed in HTTP/2
|
|
60
|
+
default: msg = error.message;
|
|
60
61
|
break;
|
|
61
62
|
}
|
|
62
63
|
} else { // Something else, either an error making the request or a Network error.
|
|
63
|
-
msg = error.message;
|
|
64
|
+
msg = error.message || 'Network Error';
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
if (!resp || resp.status !== 403) { // 403's log we'll be handled somewhere else.
|
|
67
68
|
log[logErrorsAsInfo ? 'info' : 'error'](ERROR_HTTP, [resp ? resp.status : 'NO_STATUS', url, msg]);
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
const networkError: Error & {statusCode?: number} = new Error(msg);
|
|
71
|
+
const networkError: Error & { statusCode?: number } = new Error(msg);
|
|
71
72
|
// passes `undefined` as statusCode if not an HTTP error (resp === undefined)
|
|
72
73
|
networkError.statusCode = resp && resp.status;
|
|
73
74
|
throw networkError;
|
package/src/services/types.ts
CHANGED
|
@@ -7,12 +7,12 @@ export type IRequestOptions = {
|
|
|
7
7
|
export type IResponse = {
|
|
8
8
|
ok: boolean,
|
|
9
9
|
status: number,
|
|
10
|
-
json: () => Promise<any>,
|
|
10
|
+
json: () => Promise<any>, // Used to parse OK response body. Promise rejects if body cannot be parsed
|
|
11
|
+
text: () => Promise<string>, // Used to read Not OK response body. Promise never rejects
|
|
11
12
|
|
|
12
13
|
/** Other available properties when using Unfetch */
|
|
13
|
-
// statusText: string,
|
|
14
|
+
// statusText: string, // `undefined` in Web fetch since HTTP/2 doesn't have reason phrases anymore. `node-fetch` overwrites it depending on the status code
|
|
14
15
|
// url: string,
|
|
15
|
-
// text: () => Promise<string>,
|
|
16
16
|
// blob: () => Promise<Blob>,
|
|
17
17
|
// clone: () => IResponse,
|
|
18
18
|
// headers: {
|
|
@@ -50,8 +50,8 @@ export type IPostMetricsCounters = (body: string) => Promise<IResponse>
|
|
|
50
50
|
export type IPostMetricsTimes = (body: string) => Promise<IResponse>
|
|
51
51
|
|
|
52
52
|
export interface ISplitApi {
|
|
53
|
-
getSdkAPIHealthCheck: IHealthCheckAPI
|
|
54
|
-
getEventsAPIHealthCheck: IHealthCheckAPI
|
|
53
|
+
getSdkAPIHealthCheck: IHealthCheckAPI
|
|
54
|
+
getEventsAPIHealthCheck: IHealthCheckAPI
|
|
55
55
|
fetchAuth: IFetchAuth
|
|
56
56
|
fetchSplitChanges: IFetchSplitChanges
|
|
57
57
|
fetchSegmentChanges: IFetchSegmentChanges
|
|
@@ -50,7 +50,7 @@ export default abstract class AbstractSplitsCacheSync implements ISplitsCacheSyn
|
|
|
50
50
|
* It is used as condition to emit SDK_SPLITS_CACHE_LOADED, and then SDK_READY_FROM_CACHE.
|
|
51
51
|
*/
|
|
52
52
|
checkCache(): boolean {
|
|
53
|
-
return
|
|
53
|
+
return false;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ImpressionsCacheInMemory from '../inMemory/ImpressionsCacheInMemory';
|
|
2
2
|
import ImpressionCountsCacheInMemory from '../inMemory/ImpressionCountsCacheInMemory';
|
|
3
3
|
import EventsCacheInMemory from '../inMemory/EventsCacheInMemory';
|
|
4
|
-
import { IStorageFactoryParams, IStorageSyncCS } from '../types';
|
|
4
|
+
import { IStorageFactoryParams, IStorageSyncCS, IStorageSyncFactory } from '../types';
|
|
5
5
|
import { validatePrefix } from '../KeyBuilder';
|
|
6
6
|
import KeyBuilderCS from '../KeyBuilderCS';
|
|
7
7
|
import { isLocalStorageAvailable } from '../../utils/env/isLocalStorageAvailable';
|
|
@@ -12,6 +12,7 @@ import SplitsCacheInMemory from '../inMemory/SplitsCacheInMemory';
|
|
|
12
12
|
import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../../utils/constants/browser';
|
|
13
13
|
import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
|
|
14
14
|
import { LOG_PREFIX } from './constants';
|
|
15
|
+
import { STORAGE_LOCALSTORAGE } from '../../utils/constants';
|
|
15
16
|
|
|
16
17
|
export interface InLocalStorageOptions {
|
|
17
18
|
prefix?: string
|
|
@@ -20,11 +21,11 @@ export interface InLocalStorageOptions {
|
|
|
20
21
|
/**
|
|
21
22
|
* InLocal storage factory for standalone client-side SplitFactory
|
|
22
23
|
*/
|
|
23
|
-
export function InLocalStorage(options: InLocalStorageOptions = {}) {
|
|
24
|
+
export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyncFactory {
|
|
24
25
|
|
|
25
26
|
const prefix = validatePrefix(options.prefix);
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
function InLocalStorageCSFactory(params: IStorageFactoryParams): IStorageSyncCS {
|
|
28
29
|
|
|
29
30
|
// Fallback to InMemoryStorage if LocalStorage API is not available
|
|
30
31
|
if (!isLocalStorageAvailable()) {
|
|
@@ -69,5 +70,8 @@ export function InLocalStorage(options: InLocalStorageOptions = {}) {
|
|
|
69
70
|
};
|
|
70
71
|
},
|
|
71
72
|
};
|
|
72
|
-
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
InLocalStorageCSFactory.type = STORAGE_LOCALSTORAGE;
|
|
76
|
+
return InLocalStorageCSFactory;
|
|
73
77
|
}
|
|
@@ -4,6 +4,7 @@ import ImpressionsCacheInMemory from './ImpressionsCacheInMemory';
|
|
|
4
4
|
import EventsCacheInMemory from './EventsCacheInMemory';
|
|
5
5
|
import { IStorageFactoryParams, IStorageSync } from '../types';
|
|
6
6
|
import ImpressionCountsCacheInMemory from './ImpressionCountsCacheInMemory';
|
|
7
|
+
import { STORAGE_MEMORY } from '../../utils/constants';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* InMemory storage factory for standalone server-side SplitFactory
|
|
@@ -32,3 +33,5 @@ export function InMemoryStorageFactory(params: IStorageFactoryParams): IStorageS
|
|
|
32
33
|
}
|
|
33
34
|
};
|
|
34
35
|
}
|
|
36
|
+
|
|
37
|
+
InMemoryStorageFactory.type = STORAGE_MEMORY;
|
|
@@ -4,6 +4,7 @@ import ImpressionsCacheInMemory from './ImpressionsCacheInMemory';
|
|
|
4
4
|
import EventsCacheInMemory from './EventsCacheInMemory';
|
|
5
5
|
import { IStorageSyncCS, IStorageFactoryParams } from '../types';
|
|
6
6
|
import ImpressionCountsCacheInMemory from './ImpressionCountsCacheInMemory';
|
|
7
|
+
import { STORAGE_MEMORY } from '../../utils/constants';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* InMemory storage factory for standalone client-side SplitFactory
|
|
@@ -46,3 +47,5 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
46
47
|
},
|
|
47
48
|
};
|
|
48
49
|
}
|
|
50
|
+
|
|
51
|
+
InMemoryStorageCSFactory.type = STORAGE_MEMORY;
|
|
@@ -47,7 +47,9 @@ export default class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
47
47
|
private _decrementCounts(split: ISplit) {
|
|
48
48
|
if (split.trafficTypeName) {
|
|
49
49
|
const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
50
|
-
return this.redis.decr(ttKey)
|
|
50
|
+
return this.redis.decr(ttKey).then(count => {
|
|
51
|
+
if (count === 0) return this.redis.del(ttKey);
|
|
52
|
+
});
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import RedisAdapter from './RedisAdapter';
|
|
2
|
-
import { IStorageAsync, IStorageFactoryParams } from '../types';
|
|
2
|
+
import { IStorageAsync, IStorageAsyncFactory, IStorageFactoryParams } from '../types';
|
|
3
3
|
import { validatePrefix } from '../KeyBuilder';
|
|
4
4
|
import KeyBuilderSS from '../KeyBuilderSS';
|
|
5
5
|
import SplitsCacheInRedis from './SplitsCacheInRedis';
|
|
@@ -8,6 +8,7 @@ import ImpressionsCacheInRedis from './ImpressionsCacheInRedis';
|
|
|
8
8
|
import EventsCacheInRedis from './EventsCacheInRedis';
|
|
9
9
|
import LatenciesCacheInRedis from './LatenciesCacheInRedis';
|
|
10
10
|
import CountsCacheInRedis from './CountsCacheInRedis';
|
|
11
|
+
import { STORAGE_REDIS } from '../../utils/constants';
|
|
11
12
|
|
|
12
13
|
export interface InRedisStorageOptions {
|
|
13
14
|
prefix?: string
|
|
@@ -18,11 +19,11 @@ export interface InRedisStorageOptions {
|
|
|
18
19
|
* InRedis storage factory for consumer server-side SplitFactory, that uses `Ioredis` Redis client for Node.
|
|
19
20
|
* @see {@link https://www.npmjs.com/package/ioredis}
|
|
20
21
|
*/
|
|
21
|
-
export function InRedisStorage(options: InRedisStorageOptions = {}) {
|
|
22
|
+
export function InRedisStorage(options: InRedisStorageOptions = {}): IStorageAsyncFactory {
|
|
22
23
|
|
|
23
24
|
const prefix = validatePrefix(options.prefix);
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
function InRedisStorageFactory({ log, metadata, onReadyCb }: IStorageFactoryParams): IStorageAsync {
|
|
26
27
|
|
|
27
28
|
const keys = new KeyBuilderSS(prefix, metadata);
|
|
28
29
|
const redisClient = new RedisAdapter(log, options.options || {});
|
|
@@ -47,5 +48,8 @@ export function InRedisStorage(options: InRedisStorageOptions = {}) {
|
|
|
47
48
|
// @TODO check that caches works as expected when redisClient is disconnected
|
|
48
49
|
}
|
|
49
50
|
};
|
|
50
|
-
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
InRedisStorageFactory.type = STORAGE_REDIS;
|
|
54
|
+
return InRedisStorageFactory;
|
|
51
55
|
}
|
|
@@ -31,7 +31,9 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
31
31
|
private _decrementCounts(split: ISplit) {
|
|
32
32
|
if (split.trafficTypeName) {
|
|
33
33
|
const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
34
|
-
return this.wrapper.decr(ttKey)
|
|
34
|
+
return this.wrapper.decr(ttKey).then(count => {
|
|
35
|
+
if (count === 0) return this.wrapper.del(ttKey);
|
|
36
|
+
});
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
|
|
@@ -36,28 +36,27 @@ export function inMemoryWrapperFactory(): ICustomStorageWrapper & { _cache: Reco
|
|
|
36
36
|
getKeysByPrefix(prefix: string) {
|
|
37
37
|
return Promise.resolve(Object.keys(_cache).filter(key => startsWith(key, prefix)));
|
|
38
38
|
},
|
|
39
|
-
getByPrefix(prefix: string) {
|
|
40
|
-
return Promise.resolve(Object.keys(_cache).filter(key => startsWith(key, prefix)).map(key => _cache[key] as string));
|
|
41
|
-
},
|
|
42
39
|
incr(key: string) {
|
|
43
40
|
if (key in _cache) {
|
|
44
41
|
const count = toNumber(_cache[key]) + 1;
|
|
45
|
-
if (isNaN(count)) return Promise.
|
|
42
|
+
if (isNaN(count)) return Promise.reject('Given key is not a number');
|
|
46
43
|
_cache[key] = count + '';
|
|
44
|
+
return Promise.resolve(count);
|
|
47
45
|
} else {
|
|
48
46
|
_cache[key] = '1';
|
|
47
|
+
return Promise.resolve(1);
|
|
49
48
|
}
|
|
50
|
-
return Promise.resolve(true);
|
|
51
49
|
},
|
|
52
50
|
decr(key: string) {
|
|
53
51
|
if (key in _cache) {
|
|
54
52
|
const count = toNumber(_cache[key]) - 1;
|
|
55
|
-
if (isNaN(count)) return Promise.
|
|
53
|
+
if (isNaN(count)) return Promise.reject('Given key is not a number');
|
|
56
54
|
_cache[key] = count + '';
|
|
55
|
+
return Promise.resolve(count);
|
|
57
56
|
} else {
|
|
58
57
|
_cache[key] = '-1';
|
|
58
|
+
return Promise.resolve(-1);
|
|
59
59
|
}
|
|
60
|
-
return Promise.resolve(true);
|
|
61
60
|
},
|
|
62
61
|
getMany(keys: string[]) {
|
|
63
62
|
return Promise.resolve(keys.map(key => _cache[key] ? _cache[key] as string : null));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ICustomStorageWrapper, IStorageAsync, IStorageFactoryParams } from '../types';
|
|
1
|
+
import { ICustomStorageWrapper, IStorageAsync, IStorageAsyncFactory, IStorageFactoryParams } from '../types';
|
|
2
2
|
|
|
3
3
|
import KeyBuilderSS from '../KeyBuilderSS';
|
|
4
4
|
import { SplitsCachePluggable } from './SplitsCachePluggable';
|
|
@@ -8,6 +8,7 @@ import { EventsCachePluggable } from './EventsCachePluggable';
|
|
|
8
8
|
import { wrapperAdapter, METHODS_TO_PROMISE_WRAP } from './wrapperAdapter';
|
|
9
9
|
import { isObject } from '../../utils/lang';
|
|
10
10
|
import { validatePrefix } from '../KeyBuilder';
|
|
11
|
+
import { STORAGE_CUSTOM } from '../../utils/constants';
|
|
11
12
|
|
|
12
13
|
const NO_VALID_WRAPPER = 'Expecting custom storage `wrapper` in options, but no valid wrapper instance was provided.';
|
|
13
14
|
const NO_VALID_WRAPPER_INTERFACE = 'The provided wrapper instance doesn’t follow the expected interface. Check our docs.';
|
|
@@ -34,13 +35,13 @@ function validatePluggableStorageOptions(options: any) {
|
|
|
34
35
|
/**
|
|
35
36
|
* Pluggable storage factory for consumer server-side & client-side SplitFactory.
|
|
36
37
|
*/
|
|
37
|
-
export function PluggableStorage(options: PluggableStorageOptions) {
|
|
38
|
+
export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyncFactory {
|
|
38
39
|
|
|
39
40
|
validatePluggableStorageOptions(options);
|
|
40
41
|
|
|
41
42
|
const prefix = validatePrefix(options.prefix);
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
function PluggableStorageFactory({ log, metadata, onReadyCb }: IStorageFactoryParams): IStorageAsync {
|
|
44
45
|
const keys = new KeyBuilderSS(prefix, metadata);
|
|
45
46
|
const wrapper = wrapperAdapter(log, options.wrapper);
|
|
46
47
|
|
|
@@ -63,5 +64,8 @@ export function PluggableStorage(options: PluggableStorageOptions) {
|
|
|
63
64
|
return wrapper.close();
|
|
64
65
|
}
|
|
65
66
|
};
|
|
66
|
-
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
PluggableStorageFactory.type = STORAGE_CUSTOM;
|
|
70
|
+
return PluggableStorageFactory;
|
|
67
71
|
}
|