@splitsoftware/splitio-commons 2.12.0 → 3.0.0-rc.0
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 +14 -1
- package/cjs/evaluator/condition/engineUtils.js +2 -2
- package/cjs/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +70 -0
- package/cjs/evaluator/fallbackConfigsCalculator/index.js +25 -0
- package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
- package/cjs/evaluator/fallbackTreatmentsCalculator/index.js +21 -32
- package/cjs/evaluator/index.js +67 -42
- package/cjs/evaluator/matchers/whitelist.js +1 -1
- package/cjs/integrations/pluggable.js +1 -1
- package/cjs/listeners/browser.js +4 -3
- package/cjs/listeners/node.js +4 -4
- package/cjs/logger/constants.js +14 -20
- package/cjs/logger/index.js +1 -1
- package/cjs/logger/messages/debug.js +6 -7
- package/cjs/logger/messages/error.js +4 -4
- package/cjs/logger/messages/info.js +2 -4
- package/cjs/logger/messages/warn.js +9 -9
- package/cjs/platform/browser.js +15 -0
- package/cjs/platform/getEventSource/browser.js +8 -0
- package/cjs/platform/getEventSource/eventsource.js +480 -0
- package/cjs/platform/getEventSource/node.js +26 -0
- package/cjs/platform/getFetch/browser.js +9 -0
- package/cjs/platform/getFetch/node.js +27 -0
- package/cjs/platform/getOptions/node.js +25 -0
- package/cjs/platform/node.js +17 -0
- package/cjs/readiness/constants.js +2 -1
- package/cjs/sdkClient/client.js +9 -35
- package/cjs/sdkClient/clientAttributesDecoration.js +3 -3
- package/cjs/sdkClient/clientInputValidation.js +38 -81
- package/cjs/sdkClient/identity.js +1 -1
- package/cjs/sdkClient/sdkClient.js +4 -49
- package/cjs/sdkClient/sdkLifecycle.js +70 -0
- package/cjs/sdkClient/trackMethod.js +56 -0
- package/cjs/sdkFactory/index.js +8 -45
- package/cjs/sdkManager/index.js +3 -3
- package/cjs/services/splitApi.js +18 -13
- package/cjs/services/splitHttpClient.js +1 -1
- package/cjs/storages/AbstractSplitsCacheAsync.js +1 -1
- package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
- package/cjs/storages/KeyBuilder.js +12 -12
- package/cjs/storages/KeyBuilderCS.js +13 -13
- package/cjs/storages/KeyBuilderSS.js +15 -15
- package/cjs/storages/getRolloutPlan.js +1 -1
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -1
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +1 -1
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +1 -1
- package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +2 -2
- package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +5 -5
- package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RedisAdapter.js +8 -8
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +6 -6
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +7 -7
- package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +3 -3
- package/cjs/storages/pluggable/EventsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +6 -6
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/SplitsCachePluggable.js +4 -4
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +7 -7
- package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +2 -2
- package/cjs/storages/pluggable/index.js +3 -3
- package/cjs/storages/pluggable/wrapperAdapter.js +1 -1
- package/cjs/storages/setRolloutPlan.js +1 -1
- package/cjs/storages/utils.js +6 -6
- package/cjs/sync/offline/splitsParser/parseCondition.js +1 -1
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +23 -14
- package/cjs/sync/polling/pollingManagerCS.js +11 -11
- package/cjs/sync/polling/pollingManagerSS.js +13 -13
- package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +12 -0
- package/cjs/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +67 -59
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +1 -1
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
- package/cjs/sync/streaming/SSEClient/index.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +4 -4
- package/cjs/sync/streaming/parseUtils.js +12 -12
- package/cjs/sync/streaming/pushManager.js +2 -2
- package/cjs/sync/submitters/impressionsSubmitter.js +6 -6
- package/cjs/sync/submitters/submitter.js +1 -1
- package/cjs/sync/syncManagerOnline.js +5 -2
- package/cjs/trackers/eventTracker.js +10 -12
- package/cjs/trackers/impressionObserver/buildKey.js +1 -1
- package/cjs/trackers/impressionsTracker.js +37 -20
- package/cjs/trackers/uniqueKeysTracker.js +1 -1
- package/cjs/utils/EventEmitter.js +391 -0
- package/cjs/utils/filter/bloomFilter.js +37 -0
- package/cjs/utils/inputValidation/apiKey.js +1 -1
- package/cjs/utils/inputValidation/attribute.js +2 -2
- package/cjs/utils/inputValidation/{split.js → definition.js} +10 -10
- package/cjs/utils/inputValidation/{splitExistence.js → definitionExistence.js} +6 -6
- package/cjs/utils/inputValidation/definitions.js +25 -0
- package/cjs/utils/inputValidation/eventProperties.js +1 -1
- package/cjs/utils/inputValidation/index.js +7 -7
- package/cjs/utils/inputValidation/isOperational.js +4 -4
- package/cjs/utils/inputValidation/target.js +22 -0
- package/cjs/utils/labels/index.js +3 -3
- package/cjs/utils/lang/index.js +1 -1
- package/cjs/utils/promise/timeout.js +1 -1
- package/cjs/utils/settingsValidation/splitFilters.js +4 -4
- package/cjs/utils/settingsValidation/url.js +5 -5
- package/esm/evaluator/condition/engineUtils.js +2 -2
- package/esm/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +64 -0
- package/esm/evaluator/fallbackConfigsCalculator/index.js +21 -0
- package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
- package/esm/evaluator/fallbackTreatmentsCalculator/index.js +21 -33
- package/esm/evaluator/index.js +66 -42
- package/esm/evaluator/matchers/whitelist.js +1 -1
- package/esm/integrations/pluggable.js +1 -1
- package/esm/listeners/browser.js +4 -3
- package/esm/listeners/node.js +4 -4
- package/esm/logger/constants.js +11 -17
- package/esm/logger/index.js +1 -1
- package/esm/logger/messages/debug.js +5 -6
- package/esm/logger/messages/error.js +3 -3
- package/esm/logger/messages/info.js +1 -3
- package/esm/logger/messages/warn.js +8 -8
- package/esm/platform/browser.js +12 -0
- package/esm/platform/getEventSource/browser.js +4 -0
- package/esm/platform/getEventSource/eventsource.js +480 -0
- package/esm/platform/getEventSource/node.js +20 -0
- package/esm/platform/getFetch/browser.js +5 -0
- package/esm/platform/getFetch/node.js +22 -0
- package/esm/platform/getOptions/node.js +20 -0
- package/esm/platform/node.js +14 -0
- package/esm/readiness/constants.js +1 -0
- package/esm/sdkClient/client.js +10 -37
- package/esm/sdkClient/clientAttributesDecoration.js +3 -3
- package/esm/sdkClient/clientInputValidation.js +40 -83
- package/esm/sdkClient/identity.js +1 -1
- package/esm/sdkClient/sdkClient.js +4 -49
- package/esm/sdkClient/sdkLifecycle.js +66 -0
- package/esm/sdkClient/trackMethod.js +52 -0
- package/esm/sdkFactory/index.js +8 -45
- package/esm/sdkManager/index.js +4 -4
- package/esm/services/splitApi.js +18 -13
- package/esm/services/splitHttpClient.js +1 -1
- package/esm/storages/AbstractSplitsCacheAsync.js +1 -1
- package/esm/storages/AbstractSplitsCacheSync.js +1 -1
- package/esm/storages/KeyBuilder.js +12 -12
- package/esm/storages/KeyBuilderCS.js +12 -12
- package/esm/storages/KeyBuilderSS.js +14 -14
- package/esm/storages/getRolloutPlan.js +1 -1
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +1 -1
- package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +2 -2
- package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +4 -4
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/RedisAdapter.js +7 -7
- package/esm/storages/inRedis/SplitsCacheInRedis.js +4 -4
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +7 -7
- package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -1
- package/esm/storages/pluggable/EventsCachePluggable.js +1 -1
- package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +5 -5
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/esm/storages/pluggable/SplitsCachePluggable.js +2 -2
- package/esm/storages/pluggable/TelemetryCachePluggable.js +7 -7
- package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -1
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/storages/pluggable/wrapperAdapter.js +1 -1
- package/esm/storages/setRolloutPlan.js +1 -1
- package/esm/storages/utils.js +6 -6
- package/esm/sync/offline/splitsParser/parseCondition.js +1 -1
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +24 -15
- package/esm/sync/polling/pollingManagerCS.js +11 -11
- package/esm/sync/polling/pollingManagerSS.js +13 -13
- package/esm/sync/polling/syncTasks/definitionsSyncTask.js +8 -0
- package/esm/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +67 -59
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
- package/esm/sync/streaming/SSEClient/index.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +4 -4
- package/esm/sync/streaming/parseUtils.js +10 -10
- package/esm/sync/streaming/pushManager.js +3 -3
- package/esm/sync/submitters/impressionsSubmitter.js +6 -6
- package/esm/sync/submitters/submitter.js +1 -1
- package/esm/sync/syncManagerOnline.js +5 -2
- package/esm/trackers/eventTracker.js +10 -12
- package/esm/trackers/impressionObserver/buildKey.js +1 -1
- package/esm/trackers/impressionsTracker.js +38 -21
- package/esm/trackers/uniqueKeysTracker.js +1 -1
- package/esm/utils/EventEmitter.js +387 -0
- package/esm/utils/filter/bloomFilter.js +33 -0
- package/esm/utils/inputValidation/apiKey.js +1 -1
- package/esm/utils/inputValidation/attribute.js +2 -2
- package/esm/utils/inputValidation/{split.js → definition.js} +8 -8
- package/esm/utils/inputValidation/definitionExistence.js +15 -0
- package/esm/utils/inputValidation/definitions.js +21 -0
- package/esm/utils/inputValidation/index.js +3 -3
- package/esm/utils/inputValidation/isOperational.js +4 -4
- package/esm/utils/inputValidation/target.js +18 -0
- package/esm/utils/labels/index.js +2 -2
- package/esm/utils/promise/timeout.js +1 -1
- package/esm/utils/settingsValidation/splitFilters.js +4 -4
- package/esm/utils/settingsValidation/url.js +5 -5
- package/package.json +15 -6
- package/src/dtos/types.ts +65 -70
- package/src/evaluator/Engine.ts +4 -4
- package/src/evaluator/combiners/and.ts +3 -3
- package/src/evaluator/combiners/ifelseif.ts +2 -2
- package/src/evaluator/condition/engineUtils.ts +2 -2
- package/src/evaluator/condition/index.ts +3 -3
- package/src/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.ts +76 -0
- package/src/evaluator/fallbackConfigsCalculator/index.ts +24 -0
- package/src/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.ts +5 -7
- package/src/evaluator/fallbackTreatmentsCalculator/index.ts +27 -41
- package/src/evaluator/index.ts +80 -45
- package/src/evaluator/matchers/dependency.ts +2 -2
- package/src/evaluator/matchers/matcherTypes.ts +2 -2
- package/src/evaluator/matchers/prerequisites.ts +4 -4
- package/src/evaluator/matchers/rbsegment.ts +2 -2
- package/src/evaluator/matchers/whitelist.ts +2 -2
- package/src/evaluator/matchersTransform/index.ts +2 -2
- package/src/evaluator/matchersTransform/whitelist.ts +2 -2
- package/src/evaluator/parser/index.ts +4 -4
- package/src/evaluator/treatments/index.ts +2 -2
- package/src/evaluator/types.ts +6 -6
- package/src/evaluator/value/index.ts +1 -1
- package/src/integrations/pluggable.ts +1 -1
- package/src/listeners/browser.ts +11 -8
- package/src/listeners/node.ts +2 -5
- package/src/logger/constants.ts +11 -17
- package/src/logger/messages/debug.ts +5 -6
- package/src/logger/messages/error.ts +3 -3
- package/src/logger/messages/info.ts +1 -3
- package/src/logger/messages/warn.ts +8 -8
- package/src/platform/browser.ts +14 -0
- package/src/platform/getEventSource/browser.ts +4 -0
- package/src/platform/getEventSource/eventsource.js +519 -0
- package/src/platform/getEventSource/node.ts +23 -0
- package/src/platform/getFetch/browser.ts +5 -0
- package/src/platform/getFetch/node.ts +27 -0
- package/src/platform/getOptions/node.ts +24 -0
- package/src/platform/node.ts +16 -0
- package/src/readiness/constants.ts +1 -0
- package/src/sdkClient/client.ts +11 -41
- package/src/sdkClient/clientInputValidation.ts +44 -84
- package/src/sdkClient/sdkClient.ts +5 -54
- package/src/sdkClient/sdkLifecycle.ts +78 -0
- package/src/sdkClient/trackMethod.ts +59 -0
- package/src/sdkFactory/index.ts +10 -54
- package/src/sdkFactory/types.ts +19 -16
- package/src/sdkManager/index.ts +9 -9
- package/src/services/splitApi.ts +6 -0
- package/src/services/types.ts +3 -2
- package/src/storages/AbstractSplitsCacheAsync.ts +7 -7
- package/src/storages/AbstractSplitsCacheSync.ts +10 -10
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +2 -2
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +6 -6
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +2 -2
- package/src/storages/inMemory/SplitsCacheInMemory.ts +5 -5
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +2 -2
- package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +2 -2
- package/src/storages/inRedis/SplitsCacheInRedis.ts +9 -9
- package/src/storages/pluggable/RBSegmentsCachePluggable.ts +2 -2
- package/src/storages/pluggable/SplitsCachePluggable.ts +9 -9
- package/src/storages/types.ts +21 -16
- package/src/sync/offline/splitsParser/parseCondition.ts +2 -2
- package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +3 -3
- package/src/sync/offline/splitsParser/types.ts +6 -3
- package/src/sync/offline/syncManagerOffline.ts +2 -2
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +6 -6
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +57 -22
- package/src/sync/polling/fetchers/types.ts +5 -3
- package/src/sync/polling/pollingManagerCS.ts +12 -10
- package/src/sync/polling/pollingManagerSS.ts +15 -13
- package/src/sync/polling/syncTasks/{splitsSyncTask.ts → definitionsSyncTask.ts} +10 -11
- package/src/sync/polling/types.ts +3 -3
- package/src/sync/polling/updaters/{splitChangesUpdater.ts → definitionChangesUpdater.ts} +77 -68
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +7 -7
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +6 -6
- package/src/sync/streaming/parseUtils.ts +12 -12
- package/src/sync/streaming/pushManager.ts +3 -3
- package/src/sync/submitters/impressionsSubmitter.ts +9 -9
- package/src/sync/submitters/types.ts +3 -0
- package/src/sync/syncManagerOnline.ts +6 -2
- package/src/trackers/eventTracker.ts +7 -10
- package/src/trackers/impressionsTracker.ts +42 -26
- package/src/trackers/types.ts +3 -1
- package/src/utils/EventEmitter.js +444 -0
- package/src/utils/filter/bloomFilter.ts +38 -0
- package/src/utils/inputValidation/definition.ts +27 -0
- package/src/utils/inputValidation/definitionExistence.ts +19 -0
- package/src/utils/inputValidation/definitions.ts +21 -0
- package/src/utils/inputValidation/index.ts +3 -3
- package/src/utils/inputValidation/isOperational.ts +4 -4
- package/src/utils/inputValidation/target.ts +21 -0
- package/src/utils/labels/index.ts +2 -2
- package/src/utils/settingsValidation/splitFilters.ts +3 -3
- package/types/splitio.d.ts +202 -9
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
- package/cjs/utils/inputValidation/splits.js +0 -25
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
- package/esm/utils/inputValidation/splitExistence.js +0 -15
- package/esm/utils/inputValidation/splits.js +0 -21
- package/src/utils/inputValidation/split.ts +0 -27
- package/src/utils/inputValidation/splitExistence.ts +0 -19
- package/src/utils/inputValidation/splits.ts +0 -21
package/src/sdkClient/client.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { evaluateFeature, evaluateFeatures, evaluateFeaturesByFlagSets } from '../evaluator';
|
|
2
2
|
import { thenable } from '../utils/promise/thenable';
|
|
3
3
|
import { getMatching, getBucketing } from '../utils/key';
|
|
4
|
-
import {
|
|
5
|
-
import { validateTrafficTypeExistence } from '../utils/inputValidation/trafficTypeExistence';
|
|
4
|
+
import { validateDefinitionExistence } from '../utils/inputValidation/definitionExistence';
|
|
6
5
|
import { SDK_NOT_READY } from '../utils/labels';
|
|
7
|
-
import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG,
|
|
6
|
+
import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, TREATMENTS_BY_FLAGSETS, TREATMENTS_BY_FLAGSET, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENT_WITH_CONFIG, GET_TREATMENT, GET_TREATMENTS } from '../utils/constants';
|
|
8
7
|
import { IEvaluationResult } from '../evaluator/types';
|
|
9
8
|
import SplitIO from '../../types/splitio';
|
|
10
|
-
import {
|
|
9
|
+
import { IMPRESSION_QUEUEING } from '../logger/constants';
|
|
11
10
|
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
12
11
|
import { isConsumerMode } from '../utils/settingsValidation/mode';
|
|
13
12
|
import { Method } from '../sync/submitters/types';
|
|
14
13
|
import { ImpressionDecorated } from '../trackers/types';
|
|
14
|
+
import { trackMethodFactory } from './trackMethod';
|
|
15
15
|
|
|
16
16
|
const treatmentNotReady = { treatment: CONTROL, label: SDK_NOT_READY };
|
|
17
17
|
|
|
@@ -23,7 +23,7 @@ function treatmentsNotReady(featureFlagNames: string[]) {
|
|
|
23
23
|
return evaluations;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
function stringify(options?: SplitIO.EvaluationOptions) {
|
|
26
|
+
export function stringify(options?: SplitIO.EvaluationOptions) {
|
|
27
27
|
if (options && options.properties) {
|
|
28
28
|
try {
|
|
29
29
|
return JSON.stringify(options.properties);
|
|
@@ -35,7 +35,7 @@ function stringify(options?: SplitIO.EvaluationOptions) {
|
|
|
35
35
|
* Creator of base client with getTreatments and track methods.
|
|
36
36
|
*/
|
|
37
37
|
export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | SplitIO.IAsyncClient {
|
|
38
|
-
const { sdkReadinessManager: { readinessManager }, storage, settings, impressionsTracker,
|
|
38
|
+
const { sdkReadinessManager: { readinessManager }, storage, settings, impressionsTracker, telemetryTracker, fallbackCalculator } = params;
|
|
39
39
|
const { log, mode } = settings;
|
|
40
40
|
const isAsync = isConsumerMode(mode);
|
|
41
41
|
|
|
@@ -147,16 +147,14 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
147
147
|
let { treatment, label, config = null } = evaluation;
|
|
148
148
|
|
|
149
149
|
if (treatment === CONTROL) {
|
|
150
|
-
const fallbackTreatment =
|
|
150
|
+
const fallbackTreatment = fallbackCalculator(featureFlagName, label);
|
|
151
151
|
treatment = fallbackTreatment.treatment;
|
|
152
152
|
label = fallbackTreatment.label;
|
|
153
153
|
config = fallbackTreatment.config;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
log
|
|
157
|
-
|
|
158
|
-
if (validateSplitExistence(log, readinessManager, featureFlagName, label, invokingMethodName)) {
|
|
159
|
-
log.info(IMPRESSION_QUEUEING);
|
|
156
|
+
if (validateDefinitionExistence(log, readinessManager, featureFlagName, label, invokingMethodName)) {
|
|
157
|
+
log.info(IMPRESSION_QUEUEING, ['Feature flag', featureFlagName, matchingKey, treatment, label]);
|
|
160
158
|
queue.push({
|
|
161
159
|
imp: {
|
|
162
160
|
feature: featureFlagName,
|
|
@@ -175,42 +173,14 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
175
173
|
if (withConfig) {
|
|
176
174
|
return {
|
|
177
175
|
treatment,
|
|
178
|
-
config
|
|
176
|
+
config: config as string | null
|
|
179
177
|
};
|
|
180
178
|
}
|
|
181
179
|
|
|
182
180
|
return treatment;
|
|
183
181
|
}
|
|
184
182
|
|
|
185
|
-
|
|
186
|
-
const stopTelemetryTracker = telemetryTracker.trackEval(TRACK);
|
|
187
|
-
|
|
188
|
-
const matchingKey = getMatching(key);
|
|
189
|
-
const timestamp = Date.now();
|
|
190
|
-
const eventData: SplitIO.EventData = {
|
|
191
|
-
eventTypeId,
|
|
192
|
-
trafficTypeName,
|
|
193
|
-
value,
|
|
194
|
-
timestamp,
|
|
195
|
-
key: matchingKey,
|
|
196
|
-
properties
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
// This may be async but we only warn, we don't actually care if it is valid or not in terms of queueing the event.
|
|
200
|
-
validateTrafficTypeExistence(log, readinessManager, storage.splits, mode, trafficTypeName, TRACK_FN_LABEL);
|
|
201
|
-
|
|
202
|
-
const result = eventTracker.track(eventData, size);
|
|
203
|
-
|
|
204
|
-
if (thenable(result)) {
|
|
205
|
-
return result.then((result) => {
|
|
206
|
-
stopTelemetryTracker();
|
|
207
|
-
return result;
|
|
208
|
-
});
|
|
209
|
-
} else {
|
|
210
|
-
stopTelemetryTracker();
|
|
211
|
-
return result;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
183
|
+
const track = trackMethodFactory(params);
|
|
214
184
|
|
|
215
185
|
return {
|
|
216
186
|
getTreatment,
|
|
@@ -1,31 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
2
|
validateAttributes,
|
|
3
|
-
validateEvent,
|
|
4
|
-
validateEventValue,
|
|
5
|
-
validateEventProperties,
|
|
6
3
|
validateKey,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
validateTrafficType,
|
|
4
|
+
validateDefinition,
|
|
5
|
+
validateDefinitions,
|
|
10
6
|
validateIfNotDestroyed,
|
|
11
7
|
validateIfReadyFromCache,
|
|
12
8
|
validateEvaluationOptions
|
|
13
9
|
} from '../utils/inputValidation';
|
|
14
10
|
import { startsWith } from '../utils/lang';
|
|
15
|
-
import { GET_TREATMENT, GET_TREATMENTS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENT_WITH_CONFIG
|
|
11
|
+
import { GET_TREATMENT, GET_TREATMENTS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENT_WITH_CONFIG } from '../utils/constants';
|
|
16
12
|
import { IReadinessManager } from '../readiness/types';
|
|
17
13
|
import { MaybeThenable } from '../dtos/types';
|
|
18
14
|
import { ISettings } from '../types';
|
|
19
15
|
import SplitIO from '../../types/splitio';
|
|
20
16
|
import { isConsumerMode } from '../utils/settingsValidation/mode';
|
|
21
17
|
import { validateFlagSets } from '../utils/settingsValidation/splitFilters';
|
|
22
|
-
import {
|
|
18
|
+
import { IFallbackCalculator } from '../evaluator/fallbackTreatmentsCalculator';
|
|
23
19
|
|
|
24
20
|
/**
|
|
25
21
|
* Decorator that validates the input before actually executing the client methods.
|
|
26
22
|
* We should "guard" the client here, while not polluting the "real" implementation of those methods.
|
|
27
23
|
*/
|
|
28
|
-
export function clientInputValidationDecorator<TClient extends SplitIO.IClient | SplitIO.IAsyncClient>(settings: ISettings, client: TClient, readinessManager: IReadinessManager,
|
|
24
|
+
export function clientInputValidationDecorator<TClient extends SplitIO.IClient | SplitIO.IAsyncClient>(settings: ISettings, client: TClient, readinessManager: IReadinessManager, fallbackCalculator: IFallbackCalculator): TClient {
|
|
29
25
|
|
|
30
26
|
const { log, mode } = settings;
|
|
31
27
|
const isAsync = isConsumerMode(mode);
|
|
@@ -39,14 +35,14 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
39
35
|
const nameOrNames = methodName.indexOf('ByFlagSet') > -1 ?
|
|
40
36
|
validateFlagSets(log, methodName, maybeNameOrNames as string[], settings.sync.__splitFiltersValidation.groupedFilters.bySet) :
|
|
41
37
|
startsWith(methodName, GET_TREATMENTS) ?
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
validateDefinitions(log, maybeNameOrNames, methodName) :
|
|
39
|
+
validateDefinition(log, maybeNameOrNames, methodName);
|
|
44
40
|
|
|
45
41
|
const attributes = validateAttributes(log, maybeAttributes, methodName);
|
|
46
42
|
const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, methodName);
|
|
47
43
|
const options = validateEvaluationOptions(log, maybeOptions, methodName);
|
|
48
44
|
|
|
49
|
-
validateIfReadyFromCache(log, readinessManager, methodName
|
|
45
|
+
validateIfReadyFromCache(log, readinessManager, methodName);
|
|
50
46
|
|
|
51
47
|
const valid = isNotDestroyed && key && nameOrNames && attributes !== false;
|
|
52
48
|
|
|
@@ -59,17 +55,20 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
59
55
|
};
|
|
60
56
|
}
|
|
61
57
|
|
|
62
|
-
function evaluateFallBackTreatment(featureFlagName: string, withConfig: boolean)
|
|
63
|
-
|
|
58
|
+
function evaluateFallBackTreatment(featureFlagName: string | false | string[], withConfig: boolean) {
|
|
59
|
+
if (Array.isArray(featureFlagName)) {
|
|
60
|
+
const res: SplitIO.Treatments = {};
|
|
61
|
+
featureFlagName.forEach((split: string) => res[split] = evaluateFallBackTreatment(split, withConfig) as SplitIO.Treatment);
|
|
62
|
+
return res;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const { treatment, config } = fallbackCalculator(featureFlagName as string);
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
return withConfig ?
|
|
68
|
+
{
|
|
67
69
|
treatment,
|
|
68
70
|
config
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return treatment;
|
|
71
|
+
} : treatment;
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
function wrapResult<T>(value: T): MaybeThenable<T> {
|
|
@@ -79,104 +78,65 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
79
78
|
function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
80
79
|
const params = validateEvaluationParams(GET_TREATMENT, maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions);
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const result = evaluateFallBackTreatment(params.nameOrNames as string, false);
|
|
86
|
-
return wrapResult(result);
|
|
87
|
-
}
|
|
81
|
+
return params.valid ?
|
|
82
|
+
client.getTreatment(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options) :
|
|
83
|
+
wrapResult(evaluateFallBackTreatment(params.nameOrNames, false));
|
|
88
84
|
}
|
|
89
85
|
|
|
90
86
|
function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
91
87
|
const params = validateEvaluationParams(GET_TREATMENT_WITH_CONFIG, maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions);
|
|
92
88
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const result = evaluateFallBackTreatment(params.nameOrNames as string, true);
|
|
97
|
-
return wrapResult(result);
|
|
98
|
-
}
|
|
89
|
+
return params.valid ?
|
|
90
|
+
client.getTreatmentWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options) :
|
|
91
|
+
wrapResult(evaluateFallBackTreatment(params.nameOrNames, true));
|
|
99
92
|
}
|
|
100
93
|
|
|
101
94
|
function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
102
95
|
const params = validateEvaluationParams(GET_TREATMENTS, maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions);
|
|
103
96
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const res: SplitIO.Treatments = {};
|
|
108
|
-
if (params.nameOrNames) (params.nameOrNames as string[]).forEach((split: string) => res[split] = evaluateFallBackTreatment(split, false) as SplitIO.Treatment);
|
|
109
|
-
|
|
110
|
-
return wrapResult(res);
|
|
111
|
-
}
|
|
97
|
+
return params.valid ?
|
|
98
|
+
client.getTreatments(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
|
|
99
|
+
wrapResult(evaluateFallBackTreatment(params.nameOrNames || [], false));
|
|
112
100
|
}
|
|
113
101
|
|
|
114
102
|
function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
115
103
|
const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG, maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions);
|
|
116
104
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const res: SplitIO.TreatmentsWithConfig = {};
|
|
121
|
-
if (params.nameOrNames) (params.nameOrNames as string[]).forEach(split => res[split] = evaluateFallBackTreatment(split, true) as SplitIO.TreatmentWithConfig);
|
|
122
|
-
|
|
123
|
-
return wrapResult(res);
|
|
124
|
-
}
|
|
105
|
+
return params.valid ?
|
|
106
|
+
client.getTreatmentsWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
|
|
107
|
+
wrapResult(evaluateFallBackTreatment(params.nameOrNames || [], true));
|
|
125
108
|
}
|
|
126
109
|
|
|
127
110
|
function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
128
111
|
const params = validateEvaluationParams(GET_TREATMENTS_BY_FLAG_SETS, maybeKey, maybeFlagSets, maybeAttributes, maybeOptions);
|
|
129
112
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return wrapResult({});
|
|
134
|
-
}
|
|
113
|
+
return params.valid ?
|
|
114
|
+
client.getTreatmentsByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
|
|
115
|
+
wrapResult({});
|
|
135
116
|
}
|
|
136
117
|
|
|
137
118
|
function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
138
119
|
const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, maybeKey, maybeFlagSets, maybeAttributes, maybeOptions);
|
|
139
120
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return wrapResult({});
|
|
144
|
-
}
|
|
121
|
+
return params.valid ?
|
|
122
|
+
client.getTreatmentsWithConfigByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
|
|
123
|
+
wrapResult({});
|
|
145
124
|
}
|
|
146
125
|
|
|
147
126
|
function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
148
127
|
const params = validateEvaluationParams(GET_TREATMENTS_BY_FLAG_SET, maybeKey, [maybeFlagSet], maybeAttributes, maybeOptions);
|
|
149
128
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return wrapResult({});
|
|
154
|
-
}
|
|
129
|
+
return params.valid ?
|
|
130
|
+
client.getTreatmentsByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options) :
|
|
131
|
+
wrapResult({});
|
|
155
132
|
}
|
|
156
133
|
|
|
157
134
|
function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
158
135
|
const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, maybeKey, [maybeFlagSet], maybeAttributes, maybeOptions);
|
|
159
136
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return wrapResult({});
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function track(maybeKey: SplitIO.SplitKey, maybeTT: string, maybeEvent: string, maybeEventValue?: number, maybeProperties?: SplitIO.Properties) {
|
|
168
|
-
const key = validateKey(log, maybeKey, TRACK_FN_LABEL);
|
|
169
|
-
const tt = validateTrafficType(log, maybeTT, TRACK_FN_LABEL);
|
|
170
|
-
const event = validateEvent(log, maybeEvent, TRACK_FN_LABEL);
|
|
171
|
-
const eventValue = validateEventValue(log, maybeEventValue, TRACK_FN_LABEL);
|
|
172
|
-
const { properties, size } = validateEventProperties(log, maybeProperties, TRACK_FN_LABEL);
|
|
173
|
-
const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, TRACK_FN_LABEL);
|
|
174
|
-
|
|
175
|
-
if (isNotDestroyed && key && tt && event && eventValue !== false && properties !== false) { // @ts-expect-error
|
|
176
|
-
return client.track(key, tt, event, eventValue, properties, size);
|
|
177
|
-
} else {
|
|
178
|
-
return isAsync ? Promise.resolve(false) : false;
|
|
179
|
-
}
|
|
137
|
+
return params.valid ?
|
|
138
|
+
client.getTreatmentsWithConfigByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options) :
|
|
139
|
+
wrapResult({});
|
|
180
140
|
}
|
|
181
141
|
|
|
182
142
|
return {
|
|
@@ -188,6 +148,6 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
188
148
|
getTreatmentsWithConfigByFlagSets,
|
|
189
149
|
getTreatmentsByFlagSet,
|
|
190
150
|
getTreatmentsWithConfigByFlagSet,
|
|
191
|
-
track
|
|
151
|
+
track: client.track,
|
|
192
152
|
} as TClient;
|
|
193
153
|
}
|
|
@@ -1,39 +1,16 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
2
|
import SplitIO from '../../types/splitio';
|
|
3
|
-
import { releaseApiKey } from '../utils/inputValidation/apiKey';
|
|
4
3
|
import { clientFactory } from './client';
|
|
5
4
|
import { clientInputValidationDecorator } from './clientInputValidation';
|
|
6
5
|
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
7
|
-
|
|
8
|
-
const COOLDOWN_TIME_IN_MILLIS = 1000;
|
|
6
|
+
import { sdkLifecycleFactory } from './sdkLifecycle';
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
|
-
* Creates an Sdk client, i.e., a base client with status and destroy interface
|
|
9
|
+
* Creates an Sdk client, i.e., a base client with status, init, flush and destroy interface
|
|
12
10
|
*/
|
|
13
11
|
export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: boolean): SplitIO.IClient | SplitIO.IAsyncClient {
|
|
14
|
-
const { sdkReadinessManager,
|
|
15
|
-
|
|
16
|
-
let lastActionTime = 0;
|
|
17
|
-
|
|
18
|
-
function __cooldown(func: Function, time: number) {
|
|
19
|
-
const now = Date.now();
|
|
20
|
-
//get the actual time elapsed in ms
|
|
21
|
-
const timeElapsed = now - lastActionTime;
|
|
22
|
-
//check if the time elapsed is less than desired cooldown
|
|
23
|
-
if (timeElapsed < time) {
|
|
24
|
-
//if yes, return message with remaining time in seconds
|
|
25
|
-
settings.log.warn(`Flush cooldown, remaining time ${(time - timeElapsed) / 1000} seconds`);
|
|
26
|
-
return Promise.resolve();
|
|
27
|
-
} else {
|
|
28
|
-
//Do the requested action and re-assign the lastActionTime
|
|
29
|
-
lastActionTime = now;
|
|
30
|
-
return func();
|
|
31
|
-
}
|
|
32
|
-
}
|
|
12
|
+
const { sdkReadinessManager, settings } = params;
|
|
33
13
|
|
|
34
|
-
function __flush() {
|
|
35
|
-
return syncManager ? syncManager.flush() : Promise.resolve();
|
|
36
|
-
}
|
|
37
14
|
|
|
38
15
|
return objectAssign(
|
|
39
16
|
// Proto-linkage of the readiness Event Emitter
|
|
@@ -44,35 +21,9 @@ export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: bo
|
|
|
44
21
|
settings,
|
|
45
22
|
clientFactory(params),
|
|
46
23
|
sdkReadinessManager.readinessManager,
|
|
47
|
-
params.
|
|
24
|
+
params.fallbackCalculator
|
|
48
25
|
),
|
|
49
26
|
|
|
50
|
-
|
|
51
|
-
{
|
|
52
|
-
flush() {
|
|
53
|
-
// @TODO define cooldown time
|
|
54
|
-
return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
|
|
55
|
-
},
|
|
56
|
-
destroy() {
|
|
57
|
-
// Mark the SDK as destroyed immediately
|
|
58
|
-
sdkReadinessManager.readinessManager.destroy();
|
|
59
|
-
|
|
60
|
-
// For main client, cleanup the SDK Key, listeners and scheduled jobs, and record stat before flushing data
|
|
61
|
-
if (!isSharedClient) {
|
|
62
|
-
releaseApiKey(settings.core.authorizationKey);
|
|
63
|
-
telemetryTracker.sessionLength();
|
|
64
|
-
signalListener && signalListener.stop();
|
|
65
|
-
uniqueKeysTracker.stop();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Stop background jobs
|
|
69
|
-
syncManager && syncManager.stop();
|
|
70
|
-
|
|
71
|
-
return __flush().then(() => {
|
|
72
|
-
// Cleanup storage
|
|
73
|
-
return storage.destroy();
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
27
|
+
sdkLifecycleFactory(params, isSharedClient)
|
|
77
28
|
);
|
|
78
29
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { releaseApiKey, validateAndTrackApiKey } from '../utils/inputValidation/apiKey';
|
|
2
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
3
|
+
|
|
4
|
+
const COOLDOWN_TIME_IN_MILLIS = 1000;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates an Sdk client, i.e., a base client with status, init, flush and destroy interface
|
|
8
|
+
*/
|
|
9
|
+
export function sdkLifecycleFactory(params: ISdkFactoryContext, isSharedClient?: boolean): { init(): void; flush(): Promise<void>; destroy(): Promise<void> } {
|
|
10
|
+
const { sdkReadinessManager, syncManager, storage, settings, telemetryTracker, impressionsTracker, platform } = params;
|
|
11
|
+
|
|
12
|
+
let hasInit = false;
|
|
13
|
+
let lastActionTime = 0;
|
|
14
|
+
|
|
15
|
+
const signalListener = platform.SignalListener && new platform.SignalListener(params);
|
|
16
|
+
|
|
17
|
+
function __cooldown(func: Function, time: number) {
|
|
18
|
+
const now = Date.now();
|
|
19
|
+
//get the actual time elapsed in ms
|
|
20
|
+
const timeElapsed = now - lastActionTime;
|
|
21
|
+
//check if the time elapsed is less than desired cooldown
|
|
22
|
+
if (timeElapsed < time) {
|
|
23
|
+
//if yes, return message with remaining time in seconds
|
|
24
|
+
settings.log.warn(`Flush cooldown, remaining time ${(time - timeElapsed) / 1000} seconds`);
|
|
25
|
+
return Promise.resolve();
|
|
26
|
+
} else {
|
|
27
|
+
//Do the requested action and re-assign the lastActionTime
|
|
28
|
+
lastActionTime = now;
|
|
29
|
+
return func();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function __flush() {
|
|
34
|
+
return syncManager ? syncManager.flush() : Promise.resolve();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
init() {
|
|
39
|
+
if (hasInit) return;
|
|
40
|
+
hasInit = true;
|
|
41
|
+
|
|
42
|
+
if (!isSharedClient) {
|
|
43
|
+
validateAndTrackApiKey(settings.log, settings.core.authorizationKey);
|
|
44
|
+
sdkReadinessManager.readinessManager.init();
|
|
45
|
+
impressionsTracker.start();
|
|
46
|
+
syncManager && syncManager.start();
|
|
47
|
+
signalListener && signalListener.start();
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
flush() {
|
|
52
|
+
// @TODO define cooldown time
|
|
53
|
+
return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
destroy() {
|
|
57
|
+
hasInit = false;
|
|
58
|
+
// Mark the SDK as destroyed immediately
|
|
59
|
+
sdkReadinessManager.readinessManager.destroy();
|
|
60
|
+
|
|
61
|
+
// For main client, cleanup the SDK Key, listeners and scheduled jobs, and record stat before flushing data
|
|
62
|
+
if (!isSharedClient) {
|
|
63
|
+
releaseApiKey(settings.core.authorizationKey);
|
|
64
|
+
telemetryTracker.sessionLength();
|
|
65
|
+
signalListener && signalListener.stop();
|
|
66
|
+
impressionsTracker.stop();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Stop background jobs
|
|
70
|
+
syncManager && syncManager.stop();
|
|
71
|
+
|
|
72
|
+
return __flush().then(() => {
|
|
73
|
+
// Cleanup storage
|
|
74
|
+
return storage.destroy();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { thenable } from '../utils/promise/thenable';
|
|
2
|
+
import { getMatching } from '../utils/key';
|
|
3
|
+
import { validateTrafficTypeExistence } from '../utils/inputValidation/trafficTypeExistence';
|
|
4
|
+
import { validateKey, validateTrafficType, validateEvent, validateEventValue, validateEventProperties, validateIfNotDestroyed } from '../utils/inputValidation';
|
|
5
|
+
import { TRACK, TRACK_FN_LABEL } from '../utils/constants';
|
|
6
|
+
import { isConsumerMode } from '../utils/settingsValidation/mode';
|
|
7
|
+
import SplitIO from '../../types/splitio';
|
|
8
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates a standalone `track` function with input validation.
|
|
12
|
+
* Reusable by FF SDK client, Configs SDK, and thin-client SDK.
|
|
13
|
+
*/
|
|
14
|
+
export function trackMethodFactory(params: Pick<ISdkFactoryContext, 'settings' | 'eventTracker' | 'telemetryTracker' | 'storage' | 'sdkReadinessManager'>, warnTTExistence = true) {
|
|
15
|
+
const { settings, storage: { splits }, telemetryTracker, eventTracker, sdkReadinessManager: { readinessManager } } = params;
|
|
16
|
+
const { log, mode } = settings;
|
|
17
|
+
const isAsync = isConsumerMode(mode);
|
|
18
|
+
|
|
19
|
+
return function track(maybeKey: SplitIO.SplitKey, maybeTT: string, maybeEvent: string, maybeEventValue?: number, maybeProperties?: SplitIO.Properties) {
|
|
20
|
+
// Input validation
|
|
21
|
+
const key = validateKey(log, maybeKey, TRACK_FN_LABEL);
|
|
22
|
+
const trafficTypeName = validateTrafficType(log, maybeTT, TRACK_FN_LABEL);
|
|
23
|
+
const eventTypeId = validateEvent(log, maybeEvent, TRACK_FN_LABEL);
|
|
24
|
+
const value = validateEventValue(log, maybeEventValue, TRACK_FN_LABEL);
|
|
25
|
+
const { properties, size } = validateEventProperties(log, maybeProperties, TRACK_FN_LABEL);
|
|
26
|
+
const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, TRACK_FN_LABEL);
|
|
27
|
+
|
|
28
|
+
if (!(isNotDestroyed && key && trafficTypeName && eventTypeId && value !== false && properties !== false)) {
|
|
29
|
+
return isAsync ? Promise.resolve(false) : false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Core logic
|
|
33
|
+
const stopTelemetryTracker = telemetryTracker.trackEval(TRACK);
|
|
34
|
+
|
|
35
|
+
const eventData: SplitIO.EventData = {
|
|
36
|
+
eventTypeId,
|
|
37
|
+
trafficTypeName,
|
|
38
|
+
value,
|
|
39
|
+
timestamp: Date.now(),
|
|
40
|
+
key: getMatching(key),
|
|
41
|
+
properties: properties as SplitIO.Properties | undefined
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// This may be async but we only warn, we don't actually care if it is valid or not in terms of queueing the event.
|
|
45
|
+
if (warnTTExistence) validateTrafficTypeExistence(log, readinessManager, splits, mode, trafficTypeName, TRACK_FN_LABEL);
|
|
46
|
+
|
|
47
|
+
const result = eventTracker.track(eventData, size);
|
|
48
|
+
|
|
49
|
+
if (thenable(result)) {
|
|
50
|
+
return result.then((result) => {
|
|
51
|
+
stopTelemetryTracker();
|
|
52
|
+
return result;
|
|
53
|
+
});
|
|
54
|
+
} else {
|
|
55
|
+
stopTelemetryTracker();
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|