@splitsoftware/splitio-commons 2.12.0 → 3.0.0-rc.1
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 +19 -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 +73 -48
- 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 +15 -21
- 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 -10
- 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 +5 -4
- package/cjs/readiness/readinessManager.js +22 -22
- package/cjs/readiness/sdkReadinessManager.js +0 -16
- 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 +71 -0
- package/cjs/sdkClient/trackMethod.js +56 -0
- package/cjs/sdkFactory/index.js +13 -50
- package/cjs/sdkManager/index.js +5 -5
- package/cjs/services/authProvider.js +67 -0
- package/cjs/services/secureSplitHttpClient.js +39 -0
- package/cjs/services/splitApi.js +24 -14
- package/cjs/services/splitHttpClient.js +1 -1
- package/cjs/storages/AbstractDefinitionsCacheAsync.js +51 -0
- package/cjs/storages/AbstractDefinitionsCacheSync.js +76 -0
- package/cjs/storages/KeyBuilder.js +16 -16
- package/cjs/storages/KeyBuilderCS.js +17 -17
- package/cjs/storages/KeyBuilderSS.js +16 -16
- package/cjs/storages/getRolloutPlan.js +4 -4
- package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +194 -0
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -1
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +10 -10
- package/cjs/storages/inLocalStorage/index.js +6 -6
- package/cjs/storages/inLocalStorage/validateCache.js +3 -3
- package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +121 -0
- package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +5 -5
- package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +5 -5
- package/cjs/storages/inRedis/DefinitionsCacheInRedis.js +243 -0
- 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/TelemetryCacheInRedis.js +7 -7
- package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +3 -3
- package/cjs/storages/inRedis/index.js +2 -2
- package/cjs/storages/pluggable/DefinitionsCachePluggable.js +212 -0
- 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/TelemetryCachePluggable.js +7 -7
- package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +2 -2
- package/cjs/storages/pluggable/index.js +5 -5
- package/cjs/storages/pluggable/wrapperAdapter.js +1 -1
- package/cjs/storages/setRolloutPlan.js +6 -6
- package/cjs/storages/utils.js +6 -6
- package/cjs/sync/offline/splitsParser/parseCondition.js +1 -1
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +24 -15
- package/cjs/sync/polling/pollingManagerCS.js +18 -18
- 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} +72 -64
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +3 -3
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
- package/cjs/sync/streaming/SSEClient/index.js +2 -2
- package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
- package/cjs/sync/streaming/SSEHandler/index.js +1 -1
- package/cjs/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +18 -18
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
- package/cjs/sync/streaming/constants.js +3 -3
- package/cjs/sync/streaming/parseUtils.js +12 -12
- package/cjs/sync/streaming/pushManager.js +14 -14
- package/cjs/sync/submitters/impressionsSubmitter.js +6 -6
- package/cjs/sync/submitters/submitter.js +1 -1
- package/cjs/sync/submitters/telemetrySubmitter.js +1 -2
- package/cjs/sync/syncManagerOnline.js +9 -6
- 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/Backoff.js +20 -0
- 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/lang/sets.js +4 -4
- package/cjs/utils/promise/timeout.js +1 -1
- package/cjs/utils/settingsValidation/splitFilters.js +4 -4
- package/cjs/utils/settingsValidation/url.js +6 -6
- 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 +72 -48
- 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 +12 -18
- 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 -9
- 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 +4 -3
- package/esm/readiness/readinessManager.js +23 -23
- package/esm/readiness/sdkReadinessManager.js +1 -17
- 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 +67 -0
- package/esm/sdkClient/trackMethod.js +52 -0
- package/esm/sdkFactory/index.js +14 -51
- package/esm/sdkManager/index.js +6 -6
- package/esm/services/authProvider.js +63 -0
- package/esm/services/secureSplitHttpClient.js +35 -0
- package/esm/services/splitApi.js +24 -14
- package/esm/services/splitHttpClient.js +1 -1
- package/esm/storages/AbstractDefinitionsCacheAsync.js +48 -0
- package/esm/storages/AbstractDefinitionsCacheSync.js +71 -0
- package/esm/storages/KeyBuilder.js +16 -16
- package/esm/storages/KeyBuilderCS.js +16 -16
- package/esm/storages/KeyBuilderSS.js +15 -15
- package/esm/storages/getRolloutPlan.js +4 -4
- package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +191 -0
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +7 -7
- package/esm/storages/inLocalStorage/index.js +6 -6
- package/esm/storages/inLocalStorage/validateCache.js +3 -3
- package/esm/storages/inMemory/DefinitionsCacheInMemory.js +118 -0
- package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/InMemoryStorage.js +4 -4
- package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +2 -2
- package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +5 -5
- package/esm/storages/inRedis/DefinitionsCacheInRedis.js +240 -0
- 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/TelemetryCacheInRedis.js +7 -7
- package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -1
- package/esm/storages/inRedis/index.js +2 -2
- package/esm/storages/pluggable/DefinitionsCachePluggable.js +209 -0
- 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/TelemetryCachePluggable.js +7 -7
- package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -1
- package/esm/storages/pluggable/index.js +4 -4
- package/esm/storages/pluggable/wrapperAdapter.js +1 -1
- package/esm/storages/setRolloutPlan.js +6 -6
- package/esm/storages/utils.js +6 -6
- package/esm/sync/offline/splitsParser/parseCondition.js +1 -1
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +25 -16
- package/esm/sync/polling/pollingManagerCS.js +15 -15
- package/esm/sync/polling/pollingManagerSS.js +13 -13
- package/esm/sync/polling/syncTasks/definitionsSyncTask.js +8 -0
- package/esm/sync/polling/updaters/definitionChangesUpdater.js +200 -0
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -3
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
- package/esm/sync/streaming/SSEClient/index.js +2 -2
- package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
- package/esm/sync/streaming/SSEHandler/index.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +17 -17
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
- package/esm/sync/streaming/constants.js +2 -2
- package/esm/sync/streaming/parseUtils.js +10 -10
- package/esm/sync/streaming/pushManager.js +16 -16
- package/esm/sync/submitters/impressionsSubmitter.js +6 -6
- package/esm/sync/submitters/submitter.js +1 -1
- package/esm/sync/submitters/telemetrySubmitter.js +1 -2
- package/esm/sync/syncManagerOnline.js +8 -5
- 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/Backoff.js +20 -0
- 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/lang/sets.js +4 -4
- package/esm/utils/promise/timeout.js +1 -1
- package/esm/utils/settingsValidation/splitFilters.js +4 -4
- package/esm/utils/settingsValidation/url.js +6 -6
- 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 +86 -51
- 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 +12 -18
- 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 -9
- 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 +4 -3
- package/src/readiness/readinessManager.ts +22 -22
- package/src/readiness/sdkReadinessManager.ts +1 -16
- package/src/readiness/types.ts +10 -16
- 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 +79 -0
- package/src/sdkClient/trackMethod.ts +59 -0
- package/src/sdkFactory/index.ts +15 -59
- package/src/sdkFactory/types.ts +19 -16
- package/src/sdkManager/index.ts +15 -15
- package/src/services/authProvider.ts +86 -0
- package/src/services/secureSplitHttpClient.ts +44 -0
- package/src/services/splitApi.ts +14 -2
- package/src/services/types.ts +7 -2
- package/src/storages/AbstractDefinitionsCacheAsync.ts +63 -0
- package/src/storages/AbstractDefinitionsCacheSync.ts +95 -0
- package/src/storages/KeyBuilder.ts +6 -6
- package/src/storages/KeyBuilderCS.ts +6 -6
- package/src/storages/KeyBuilderSS.ts +2 -2
- package/src/storages/getRolloutPlan.ts +3 -3
- package/src/storages/inLocalStorage/DefinitionsCacheInLocal.ts +234 -0
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +8 -8
- package/src/storages/inLocalStorage/index.ts +6 -6
- package/src/storages/inLocalStorage/validateCache.ts +4 -4
- package/src/storages/inMemory/DefinitionsCacheInMemory.ts +130 -0
- package/src/storages/inMemory/InMemoryStorage.ts +4 -4
- package/src/storages/inMemory/InMemoryStorageCS.ts +5 -5
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +3 -3
- package/src/storages/inMemory/SegmentsCacheInMemory.ts +1 -1
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +5 -5
- package/src/storages/inRedis/{SplitsCacheInRedis.ts → DefinitionsCacheInRedis.ts} +69 -69
- package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +2 -2
- package/src/storages/inRedis/index.ts +2 -2
- package/src/storages/pluggable/DefinitionsCachePluggable.ts +230 -0
- package/src/storages/pluggable/RBSegmentsCachePluggable.ts +2 -2
- package/src/storages/pluggable/index.ts +2 -2
- package/src/storages/setRolloutPlan.ts +7 -7
- package/src/storages/types.ts +34 -29
- 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 +14 -14
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +58 -23
- package/src/sync/polling/fetchers/types.ts +5 -3
- package/src/sync/polling/pollingManagerCS.ts +16 -14
- package/src/sync/polling/pollingManagerSS.ts +15 -13
- package/src/sync/polling/syncTasks/{splitsSyncTask.ts → definitionsSyncTask.ts} +11 -12
- package/src/sync/polling/types.ts +3 -3
- package/src/sync/polling/updaters/definitionChangesUpdater.ts +239 -0
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +3 -3
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +7 -7
- package/src/sync/streaming/AuthClient/index.ts +2 -2
- package/src/sync/streaming/AuthClient/types.ts +14 -11
- package/src/sync/streaming/SSEClient/index.ts +2 -2
- package/src/sync/streaming/SSEClient/types.ts +2 -2
- package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +2 -2
- package/src/sync/streaming/SSEHandler/index.ts +2 -2
- package/src/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.ts → DefinitionsUpdateWorker.ts} +21 -21
- package/src/sync/streaming/constants.ts +2 -2
- package/src/sync/streaming/parseUtils.ts +12 -12
- package/src/sync/streaming/pushManager.ts +18 -18
- package/src/sync/streaming/types.ts +2 -2
- package/src/sync/submitters/impressionsSubmitter.ts +9 -9
- package/src/sync/submitters/telemetrySubmitter.ts +1 -2
- package/src/sync/submitters/types.ts +3 -0
- package/src/sync/syncManagerOnline.ts +9 -5
- package/src/trackers/eventTracker.ts +7 -10
- package/src/trackers/impressionsTracker.ts +42 -26
- package/src/trackers/types.ts +3 -1
- package/src/utils/Backoff.ts +21 -0
- 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/inputValidation/trafficTypeExistence.ts +2 -2
- package/src/utils/jwt/types.ts +1 -1
- package/src/utils/labels/index.ts +2 -2
- package/src/utils/lang/sets.ts +4 -2
- package/src/utils/settingsValidation/splitFilters.ts +3 -3
- package/src/utils/settingsValidation/url.ts +1 -1
- package/types/splitio.d.ts +222 -11
- package/cjs/storages/AbstractSplitsCacheAsync.js +0 -51
- package/cjs/storages/AbstractSplitsCacheSync.js +0 -76
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +0 -194
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +0 -121
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +0 -243
- package/cjs/storages/pluggable/SplitsCachePluggable.js +0 -212
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
- package/cjs/utils/inputValidation/splits.js +0 -25
- package/esm/storages/AbstractSplitsCacheAsync.js +0 -48
- package/esm/storages/AbstractSplitsCacheSync.js +0 -71
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +0 -191
- package/esm/storages/inMemory/SplitsCacheInMemory.js +0 -118
- package/esm/storages/inRedis/SplitsCacheInRedis.js +0 -240
- package/esm/storages/pluggable/SplitsCachePluggable.js +0 -209
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
- package/esm/sync/polling/updaters/splitChangesUpdater.js +0 -192
- package/esm/utils/inputValidation/splitExistence.js +0 -15
- package/esm/utils/inputValidation/splits.js +0 -21
- package/src/storages/AbstractSplitsCacheAsync.ts +0 -63
- package/src/storages/AbstractSplitsCacheSync.ts +0 -95
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +0 -234
- package/src/storages/inMemory/SplitsCacheInMemory.ts +0 -130
- package/src/storages/pluggable/SplitsCachePluggable.ts +0 -230
- package/src/sync/polling/updaters/splitChangesUpdater.ts +0 -230
- package/src/utils/inputValidation/split.ts +0 -27
- package/src/utils/inputValidation/splitExistence.ts +0 -19
- package/src/utils/inputValidation/splits.ts +0 -21
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
2
|
import { ISettings } from '../types';
|
|
3
3
|
import SplitIO, { SdkReadyMetadata } from '../../types/splitio';
|
|
4
|
-
import {
|
|
5
|
-
import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter,
|
|
4
|
+
import { SDK_DEFINITIONS_ARRIVED, SDK_DEFINITIONS_CACHE_LOADED, SDK_SEGMENTS_ARRIVED, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE, SDK_READY } from './constants';
|
|
5
|
+
import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter, IDefinitionsEventEmitter } from './types';
|
|
6
6
|
|
|
7
|
-
function
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
function definitionsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter): IDefinitionsEventEmitter {
|
|
8
|
+
const definitionsEventEmitter = objectAssign(new EventEmitter(), {
|
|
9
|
+
definitionsArrived: false,
|
|
10
|
+
definitionsCacheLoaded: false,
|
|
11
11
|
hasInit: false,
|
|
12
12
|
initCallbacks: []
|
|
13
13
|
});
|
|
@@ -15,10 +15,10 @@ function splitsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter
|
|
|
15
15
|
// `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
|
|
16
16
|
// - `/memberships` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
|
|
17
17
|
// - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
definitionsEventEmitter.on(SDK_DEFINITIONS_ARRIVED, (metadata: SplitIO.SdkUpdateMetadata, isSplitKill: boolean) => { if (!isSplitKill) definitionsEventEmitter.definitionsArrived = true; });
|
|
19
|
+
definitionsEventEmitter.once(SDK_DEFINITIONS_CACHE_LOADED, () => { definitionsEventEmitter.definitionsCacheLoaded = true; });
|
|
20
20
|
|
|
21
|
-
return
|
|
21
|
+
return definitionsEventEmitter;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function segmentsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter): ISegmentsEventEmitter {
|
|
@@ -37,7 +37,7 @@ function segmentsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitt
|
|
|
37
37
|
export function readinessManagerFactory(
|
|
38
38
|
EventEmitter: new () => SplitIO.IEventEmitter,
|
|
39
39
|
settings: ISettings,
|
|
40
|
-
|
|
40
|
+
definitions: IDefinitionsEventEmitter = definitionsEventEmitterFactory(EventEmitter),
|
|
41
41
|
isShared?: boolean
|
|
42
42
|
): IReadinessManager {
|
|
43
43
|
|
|
@@ -59,8 +59,8 @@ export function readinessManagerFactory(
|
|
|
59
59
|
|
|
60
60
|
// emit SDK_READY_FROM_CACHE
|
|
61
61
|
let isReadyFromCache = false;
|
|
62
|
-
if (
|
|
63
|
-
else
|
|
62
|
+
if (definitions.definitionsCacheLoaded) isReadyFromCache = true; // ready from cache, but doesn't emit SDK_READY_FROM_CACHE
|
|
63
|
+
else definitions.once(SDK_DEFINITIONS_CACHE_LOADED, checkIsReadyFromCache);
|
|
64
64
|
|
|
65
65
|
// emit SDK_READY_TIMED_OUT
|
|
66
66
|
let hasTimedout = false;
|
|
@@ -75,7 +75,7 @@ export function readinessManagerFactory(
|
|
|
75
75
|
|
|
76
76
|
// emit SDK_READY and SDK_UPDATE
|
|
77
77
|
let isReady = false;
|
|
78
|
-
|
|
78
|
+
definitions.on(SDK_DEFINITIONS_ARRIVED, checkIsReadyOrUpdate);
|
|
79
79
|
segments.on(SDK_SEGMENTS_ARRIVED, checkIsReadyOrUpdate);
|
|
80
80
|
|
|
81
81
|
let isDestroyed = false;
|
|
@@ -85,8 +85,8 @@ export function readinessManagerFactory(
|
|
|
85
85
|
if (readyTimeout > 0 && !isReady) readyTimeoutId = setTimeout(timeout, readyTimeout);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
if (
|
|
88
|
+
definitions.initCallbacks.push(__init);
|
|
89
|
+
if (definitions.hasInit) __init();
|
|
90
90
|
|
|
91
91
|
function checkIsReadyFromCache(cacheMetadata: SdkReadyMetadata) {
|
|
92
92
|
metadataReady = cacheMetadata;
|
|
@@ -114,7 +114,7 @@ export function readinessManagerFactory(
|
|
|
114
114
|
setTimeout(() => { throw e; }, 0);
|
|
115
115
|
}
|
|
116
116
|
} else {
|
|
117
|
-
if (
|
|
117
|
+
if (definitions.definitionsArrived && segments.segmentsArrived) {
|
|
118
118
|
clearTimeout(readyTimeoutId);
|
|
119
119
|
isReady = true;
|
|
120
120
|
try {
|
|
@@ -137,12 +137,12 @@ export function readinessManagerFactory(
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
return {
|
|
140
|
-
|
|
140
|
+
definitions,
|
|
141
141
|
segments,
|
|
142
142
|
gate,
|
|
143
143
|
|
|
144
144
|
shared() {
|
|
145
|
-
return readinessManagerFactory(EventEmitter, settings,
|
|
145
|
+
return readinessManagerFactory(EventEmitter, settings, definitions, true);
|
|
146
146
|
},
|
|
147
147
|
|
|
148
148
|
// @TODO review/remove next methods when non-recoverable errors are reworked
|
|
@@ -153,9 +153,9 @@ export function readinessManagerFactory(
|
|
|
153
153
|
setDestroyed() { isDestroyed = true; },
|
|
154
154
|
|
|
155
155
|
init() {
|
|
156
|
-
if (
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
if (definitions.hasInit) return;
|
|
157
|
+
definitions.hasInit = true;
|
|
158
|
+
definitions.initCallbacks.forEach(cb => cb());
|
|
159
159
|
},
|
|
160
160
|
|
|
161
161
|
destroy() {
|
|
@@ -163,7 +163,7 @@ export function readinessManagerFactory(
|
|
|
163
163
|
syncLastUpdate();
|
|
164
164
|
clearTimeout(readyTimeoutId);
|
|
165
165
|
|
|
166
|
-
if (!isShared)
|
|
166
|
+
if (!isShared) definitions.hasInit = false;
|
|
167
167
|
},
|
|
168
168
|
|
|
169
169
|
isReady() { return isReady; },
|
|
@@ -5,10 +5,9 @@ import { ISdkReadinessManager } from './types';
|
|
|
5
5
|
import { ISettings } from '../types';
|
|
6
6
|
import SplitIO from '../../types/splitio';
|
|
7
7
|
import { SDK_READY, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE } from './constants';
|
|
8
|
-
import { ERROR_CLIENT_LISTENER, CLIENT_READY_FROM_CACHE, CLIENT_READY
|
|
8
|
+
import { ERROR_CLIENT_LISTENER, CLIENT_READY_FROM_CACHE, CLIENT_READY } from '../logger/constants';
|
|
9
9
|
|
|
10
10
|
const NEW_LISTENER_EVENT = 'newListener';
|
|
11
|
-
const REMOVE_LISTENER_EVENT = 'removeListener';
|
|
12
11
|
const TIMEOUT_ERROR = new Error(SDK_READY_TIMED_OUT);
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -25,19 +24,10 @@ export function sdkReadinessManagerFactory(
|
|
|
25
24
|
|
|
26
25
|
const log = settings.log;
|
|
27
26
|
|
|
28
|
-
/** Ready callback warning */
|
|
29
|
-
let internalReadyCbCount = 0;
|
|
30
|
-
let readyCbCount = 0;
|
|
31
|
-
readinessManager.gate.on(REMOVE_LISTENER_EVENT, (event: any) => {
|
|
32
|
-
if (event === SDK_READY) readyCbCount--;
|
|
33
|
-
});
|
|
34
|
-
|
|
35
27
|
readinessManager.gate.on(NEW_LISTENER_EVENT, (event: any) => {
|
|
36
28
|
if (event === SDK_READY || event === SDK_READY_TIMED_OUT) {
|
|
37
29
|
if (readinessManager.isReady()) {
|
|
38
30
|
log.error(ERROR_CLIENT_LISTENER, [event === SDK_READY ? 'SDK_READY' : 'SDK_READY_TIMED_OUT']);
|
|
39
|
-
} else if (event === SDK_READY) {
|
|
40
|
-
readyCbCount++;
|
|
41
31
|
}
|
|
42
32
|
} else if (event === SDK_READY_FROM_CACHE && readinessManager.isReadyFromCache()) {
|
|
43
33
|
log.error(ERROR_CLIENT_LISTENER, ['SDK_READY_FROM_CACHE']);
|
|
@@ -61,7 +51,6 @@ export function sdkReadinessManagerFactory(
|
|
|
61
51
|
readinessManager.gate.once(SDK_READY, () => {
|
|
62
52
|
log.info(CLIENT_READY);
|
|
63
53
|
|
|
64
|
-
if (readyCbCount === internalReadyCbCount && !promise.hasOnFulfilled()) log.warn(CLIENT_NO_LISTENER);
|
|
65
54
|
resolve();
|
|
66
55
|
});
|
|
67
56
|
readinessManager.gate.once(SDK_READY_TIMED_OUT, (message: string) => {
|
|
@@ -91,10 +80,6 @@ export function sdkReadinessManagerFactory(
|
|
|
91
80
|
return sdkReadinessManagerFactory(EventEmitter, settings, readinessManager.shared());
|
|
92
81
|
},
|
|
93
82
|
|
|
94
|
-
incInternalReadyCbCount() {
|
|
95
|
-
internalReadyCbCount++;
|
|
96
|
-
},
|
|
97
|
-
|
|
98
83
|
sdkStatus: objectAssign(
|
|
99
84
|
// Expose Event Emitter functionality
|
|
100
85
|
Object.create(readinessManager.gate),
|
package/src/readiness/types.ts
CHANGED
|
@@ -16,17 +16,17 @@ export interface IReadinessEventEmitter extends SplitIO.IEventEmitter {
|
|
|
16
16
|
|
|
17
17
|
/** Splits data emitter */
|
|
18
18
|
|
|
19
|
-
type
|
|
20
|
-
type
|
|
21
|
-
type
|
|
19
|
+
type SDK_DEFINITIONS_ARRIVED = 'state::splits-arrived'
|
|
20
|
+
type SDK_DEFINITIONS_CACHE_LOADED = 'state::splits-cache-loaded'
|
|
21
|
+
type IDefinitionsEvent = SDK_DEFINITIONS_ARRIVED | SDK_DEFINITIONS_CACHE_LOADED
|
|
22
22
|
|
|
23
|
-
export interface
|
|
24
|
-
emit(event:
|
|
25
|
-
on(event:
|
|
23
|
+
export interface IDefinitionsEventEmitter extends SplitIO.IEventEmitter {
|
|
24
|
+
emit(event: IDefinitionsEvent, ...args: any[]): boolean
|
|
25
|
+
on(event: IDefinitionsEvent, listener: (...args: any[]) => void): this;
|
|
26
26
|
on(event: SDK_UPDATE, listener: (metadata: SplitIO.SdkUpdateMetadata) => void): this;
|
|
27
|
-
once(event:
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
once(event: IDefinitionsEvent, listener: (...args: any[]) => void): this;
|
|
28
|
+
definitionsArrived: boolean
|
|
29
|
+
definitionsCacheLoaded: boolean
|
|
30
30
|
hasInit: boolean,
|
|
31
31
|
initCallbacks: (() => void)[]
|
|
32
32
|
}
|
|
@@ -48,7 +48,7 @@ export interface ISegmentsEventEmitter extends SplitIO.IEventEmitter {
|
|
|
48
48
|
|
|
49
49
|
export interface IReadinessManager {
|
|
50
50
|
/** Event emitters */
|
|
51
|
-
|
|
51
|
+
definitions: IDefinitionsEventEmitter,
|
|
52
52
|
segments: ISegmentsEventEmitter,
|
|
53
53
|
gate: IReadinessEventEmitter,
|
|
54
54
|
|
|
@@ -77,12 +77,6 @@ export interface ISdkReadinessManager {
|
|
|
77
77
|
readinessManager: IReadinessManager
|
|
78
78
|
sdkStatus: SplitIO.IStatusInterface
|
|
79
79
|
|
|
80
|
-
/**
|
|
81
|
-
* Increment internalReadyCbCount, an offset value of SDK_READY listeners that are added/removed internally
|
|
82
|
-
* by the SDK. It is required to properly log the warning 'No listeners for SDK Readiness detected'
|
|
83
|
-
*/
|
|
84
|
-
incInternalReadyCbCount(): void
|
|
85
|
-
|
|
86
80
|
/** for client-side */
|
|
87
81
|
shared(): ISdkReadinessManager
|
|
88
82
|
}
|
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
|
}
|