@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,18 +1,18 @@
|
|
|
1
1
|
import { forOwn } from '../../utils/lang';
|
|
2
2
|
import { mySegmentsSyncTaskFactory } from './syncTasks/mySegmentsSyncTask';
|
|
3
|
-
import {
|
|
3
|
+
import { definitionsSyncTaskFactory } from './syncTasks/definitionsSyncTask';
|
|
4
4
|
import { getMatching } from '../../utils/key';
|
|
5
|
-
import {
|
|
5
|
+
import { SDK_DEFINITIONS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../readiness/constants';
|
|
6
6
|
import { POLLING_SMART_PAUSING, POLLING_START, POLLING_STOP } from '../../logger/constants';
|
|
7
|
-
import { usesSegmentsSync } from '../../storages/
|
|
7
|
+
import { usesSegmentsSync } from '../../storages/AbstractDefinitionsCacheSync';
|
|
8
8
|
/**
|
|
9
9
|
* Expose start / stop mechanism for polling data from services.
|
|
10
10
|
* For client-side API with multiple clients.
|
|
11
11
|
*/
|
|
12
|
-
export function pollingManagerCSFactory(params) {
|
|
12
|
+
export function pollingManagerCSFactory(params, definitionChangesFetcher) {
|
|
13
13
|
var splitApi = params.splitApi, storage = params.storage, readiness = params.readiness, settings = params.settings;
|
|
14
14
|
var log = settings.log;
|
|
15
|
-
var
|
|
15
|
+
var definitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings, true);
|
|
16
16
|
// Map of matching keys to their corresponding MySegmentsSyncTask.
|
|
17
17
|
var mySegmentsSyncTasks = {};
|
|
18
18
|
var matchingKey = getMatching(settings.core.key);
|
|
@@ -29,8 +29,8 @@ export function pollingManagerCSFactory(params) {
|
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
// smart pausing
|
|
32
|
-
readiness.
|
|
33
|
-
if (!
|
|
32
|
+
readiness.definitions.on(SDK_DEFINITIONS_ARRIVED, function () {
|
|
33
|
+
if (!definitionsSyncTask.isRunning())
|
|
34
34
|
return; // noop if not doing polling
|
|
35
35
|
var usingSegments = usesSegmentsSync(storage);
|
|
36
36
|
if (usingSegments !== mySegmentsSyncTask.isRunning()) {
|
|
@@ -53,32 +53,32 @@ export function pollingManagerCSFactory(params) {
|
|
|
53
53
|
if (!usesSegmentsSync(storage))
|
|
54
54
|
setTimeout(smartReady, 0);
|
|
55
55
|
else
|
|
56
|
-
readiness.
|
|
56
|
+
readiness.definitions.once(SDK_DEFINITIONS_ARRIVED, smartReady);
|
|
57
57
|
mySegmentsSyncTasks[matchingKey] = mySegmentsSyncTask;
|
|
58
58
|
return mySegmentsSyncTask;
|
|
59
59
|
}
|
|
60
60
|
return {
|
|
61
|
-
|
|
61
|
+
definitionsSyncTask: definitionsSyncTask,
|
|
62
62
|
segmentsSyncTask: mySegmentsSyncTask,
|
|
63
63
|
// Start periodic fetching (polling)
|
|
64
64
|
start: function () {
|
|
65
65
|
log.info(POLLING_START);
|
|
66
|
-
|
|
66
|
+
definitionsSyncTask.start();
|
|
67
67
|
if (usesSegmentsSync(storage))
|
|
68
68
|
startMySegmentsSyncTasks();
|
|
69
69
|
},
|
|
70
70
|
// Stop periodic fetching (polling)
|
|
71
71
|
stop: function () {
|
|
72
72
|
log.info(POLLING_STOP);
|
|
73
|
-
if (
|
|
74
|
-
|
|
73
|
+
if (definitionsSyncTask.isRunning())
|
|
74
|
+
definitionsSyncTask.stop();
|
|
75
75
|
stopMySegmentsSyncTasks();
|
|
76
76
|
},
|
|
77
77
|
// Used by SyncManager to know if running in polling mode.
|
|
78
|
-
isRunning:
|
|
79
|
-
// fetch
|
|
78
|
+
isRunning: definitionsSyncTask.isRunning,
|
|
79
|
+
// fetch definitions and segments
|
|
80
80
|
syncAll: function () {
|
|
81
|
-
var promises = [
|
|
81
|
+
var promises = [definitionsSyncTask.execute()];
|
|
82
82
|
forOwn(mySegmentsSyncTasks, function (mySegmentsSyncTask) {
|
|
83
83
|
promises.push(mySegmentsSyncTask.execute());
|
|
84
84
|
});
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { definitionsSyncTaskFactory } from './syncTasks/definitionsSyncTask';
|
|
2
2
|
import { segmentsSyncTaskFactory } from './syncTasks/segmentsSyncTask';
|
|
3
3
|
import { POLLING_START, POLLING_STOP, LOG_PREFIX_SYNC_POLLING } from '../../logger/constants';
|
|
4
4
|
/**
|
|
5
5
|
* Expose start / stop mechanism for pulling data from services.
|
|
6
6
|
*/
|
|
7
|
-
export function pollingManagerSSFactory(params) {
|
|
7
|
+
export function pollingManagerSSFactory(params, definitionChangesFetcher) {
|
|
8
8
|
var splitApi = params.splitApi, storage = params.storage, readiness = params.readiness, settings = params.settings;
|
|
9
9
|
var log = settings.log;
|
|
10
|
-
var
|
|
10
|
+
var definitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings);
|
|
11
11
|
var segmentsSyncTask = segmentsSyncTaskFactory(splitApi.fetchSegmentChanges, storage, readiness, settings);
|
|
12
12
|
return {
|
|
13
|
-
|
|
13
|
+
definitionsSyncTask: definitionsSyncTask,
|
|
14
14
|
segmentsSyncTask: segmentsSyncTask,
|
|
15
15
|
// Start periodic fetching (polling)
|
|
16
16
|
start: function () {
|
|
17
17
|
log.info(POLLING_START);
|
|
18
|
-
log.debug(LOG_PREFIX_SYNC_POLLING + ("
|
|
19
|
-
log.debug(LOG_PREFIX_SYNC_POLLING +
|
|
20
|
-
var startingUp =
|
|
18
|
+
log.debug(LOG_PREFIX_SYNC_POLLING + "".concat(definitionChangesFetcher.type, " will be refreshed each ").concat(settings.scheduler.featuresRefreshRate, " millis"));
|
|
19
|
+
log.debug(LOG_PREFIX_SYNC_POLLING + "segments will be refreshed each ".concat(settings.scheduler.segmentsRefreshRate, " millis"));
|
|
20
|
+
var startingUp = definitionsSyncTask.start();
|
|
21
21
|
if (startingUp) {
|
|
22
22
|
startingUp.then(function () {
|
|
23
|
-
if (
|
|
23
|
+
if (definitionsSyncTask.isRunning())
|
|
24
24
|
segmentsSyncTask.start();
|
|
25
25
|
});
|
|
26
26
|
}
|
|
@@ -28,16 +28,16 @@ export function pollingManagerSSFactory(params) {
|
|
|
28
28
|
// Stop periodic fetching (polling)
|
|
29
29
|
stop: function () {
|
|
30
30
|
log.info(POLLING_STOP);
|
|
31
|
-
if (
|
|
32
|
-
|
|
31
|
+
if (definitionsSyncTask.isRunning())
|
|
32
|
+
definitionsSyncTask.stop();
|
|
33
33
|
if (segmentsSyncTask.isRunning())
|
|
34
34
|
segmentsSyncTask.stop();
|
|
35
35
|
},
|
|
36
36
|
// Used by SyncManager to know if running in polling mode.
|
|
37
|
-
isRunning:
|
|
37
|
+
isRunning: definitionsSyncTask.isRunning,
|
|
38
38
|
syncAll: function () {
|
|
39
|
-
// fetch
|
|
40
|
-
return
|
|
39
|
+
// fetch definitions and segments. There is no need to catch this promise (`DefinitionChangesUpdater` is always resolved with a boolean value)
|
|
40
|
+
return definitionsSyncTask.execute().then(function () {
|
|
41
41
|
return segmentsSyncTask.execute();
|
|
42
42
|
});
|
|
43
43
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { syncTaskFactory } from '../../syncTask';
|
|
2
|
+
import { definitionChangesUpdaterFactory } from '../updaters/definitionChangesUpdater';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a sync task that periodically executes a `definitionChangesUpdater` task
|
|
5
|
+
*/
|
|
6
|
+
export function definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings, isClientSide) {
|
|
7
|
+
return syncTaskFactory(settings.log, definitionChangesUpdaterFactory(settings.log, definitionChangesFetcher, storage, settings.sync.__splitFiltersValidation, readiness.definitions, settings.startup.requestTimeoutBeforeReady, settings.startup.retriesOnFailureBeforeReady, isClientSide), settings.scheduler.featuresRefreshRate, 'definitionChangesUpdater');
|
|
8
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { timeout } from '../../../utils/promise/timeout';
|
|
2
|
+
import { SDK_DEFINITIONS_ARRIVED, FLAGS_UPDATE, SEGMENTS_UPDATE, CONFIGS_UPDATE } from '../../../readiness/constants';
|
|
3
|
+
import { SYNC_FETCH, SYNC_UPDATE, SYNC_FETCH_FAILS, SYNC_FETCH_RETRY } from '../../../logger/constants';
|
|
4
|
+
import { startsWith } from '../../../utils/lang';
|
|
5
|
+
import { IN_RULE_BASED_SEGMENT, IN_SEGMENT, RULE_BASED_SEGMENT, STANDARD_SEGMENT } from '../../../utils/constants';
|
|
6
|
+
import { setToArray } from '../../../utils/lang/sets';
|
|
7
|
+
import { SPLIT_UPDATE } from '../../streaming/constants';
|
|
8
|
+
// Checks that all registered segments have been fetched (changeNumber !== -1 for every segment).
|
|
9
|
+
// Returns a promise that could be rejected.
|
|
10
|
+
// @TODO review together with Segments and MySegments storage APIs
|
|
11
|
+
function checkAllSegmentsExist(segments) {
|
|
12
|
+
var registeredSegments = Promise.resolve(segments.getRegisteredSegments());
|
|
13
|
+
return registeredSegments.then(function (segmentNames) {
|
|
14
|
+
return Promise.all(segmentNames.map(function (segmentName) { return segments.getChangeNumber(segmentName); }))
|
|
15
|
+
.then(function (changeNumbers) { return changeNumbers.every(function (changeNumber) { return changeNumber !== undefined; }); });
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Collect segments from a raw FF or RBS definition.
|
|
20
|
+
* Exported for testing purposes.
|
|
21
|
+
*/
|
|
22
|
+
export function parseSegments(ruleEntity, matcherType) {
|
|
23
|
+
if (matcherType === void 0) { matcherType = IN_SEGMENT; }
|
|
24
|
+
var _a = ruleEntity, conditions = _a.conditions, excluded = _a.excluded;
|
|
25
|
+
var segments = new Set();
|
|
26
|
+
if (excluded && excluded.segments) {
|
|
27
|
+
excluded.segments.forEach(function (_a) {
|
|
28
|
+
var type = _a.type, name = _a.name;
|
|
29
|
+
if ((type === STANDARD_SEGMENT && matcherType === IN_SEGMENT) || (type === RULE_BASED_SEGMENT && matcherType === IN_RULE_BASED_SEGMENT)) {
|
|
30
|
+
segments.add(name);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (conditions) {
|
|
35
|
+
for (var i = 0; i < conditions.length; i++) {
|
|
36
|
+
var matchers = conditions[i].matcherGroup.matchers;
|
|
37
|
+
matchers.forEach(function (matcher) {
|
|
38
|
+
if (matcher.matcherType === matcherType)
|
|
39
|
+
segments.add(matcher.userDefinedSegmentMatcherData.segmentName);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return segments;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* If there are defined filters and one definition doesn't match with them, its status is changed to 'ARCHIVE' to avoid storing it
|
|
47
|
+
* If there is `bySet` filter, `byName` and `byPrefix` filters are ignored
|
|
48
|
+
*
|
|
49
|
+
* @param definition - definition to be evaluated
|
|
50
|
+
* @param filters - splitFiltersValidation bySet | byName
|
|
51
|
+
*/
|
|
52
|
+
function matchFilters(definition, filters) {
|
|
53
|
+
var _a = filters.groupedFilters, setsFilter = _a.bySet, namesFilter = _a.byName, prefixFilter = _a.byPrefix;
|
|
54
|
+
if (setsFilter.length > 0)
|
|
55
|
+
return definition.sets && definition.sets.some(function (definitionSet) { return setsFilter.indexOf(definitionSet) > -1; });
|
|
56
|
+
var namesFilterConfigured = namesFilter.length > 0;
|
|
57
|
+
var prefixFilterConfigured = prefixFilter.length > 0;
|
|
58
|
+
if (!namesFilterConfigured && !prefixFilterConfigured)
|
|
59
|
+
return true;
|
|
60
|
+
var matchNames = namesFilterConfigured && namesFilter.indexOf(definition.name) > -1;
|
|
61
|
+
var matchPrefix = prefixFilterConfigured && prefixFilter.some(function (prefix) { return startsWith(definition.name, prefix); });
|
|
62
|
+
return matchNames || matchPrefix;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Given the list of definitions from /splitChanges or /configs endpoint, it returns the mutations,
|
|
66
|
+
* i.e., an object with added definitions, removed definitions, and used segments.
|
|
67
|
+
* Exported for testing purposes.
|
|
68
|
+
*/
|
|
69
|
+
export function computeMutation(update, segments, filters) {
|
|
70
|
+
return update.updated.reduce(function (accum, ruleEntity) {
|
|
71
|
+
if (!filters || matchFilters(ruleEntity, filters)) {
|
|
72
|
+
accum.added.push(ruleEntity);
|
|
73
|
+
parseSegments(ruleEntity).forEach(function (segmentName) {
|
|
74
|
+
segments.add(segmentName);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
accum.removed.push(ruleEntity.name);
|
|
79
|
+
}
|
|
80
|
+
accum.names.push(ruleEntity.name);
|
|
81
|
+
return accum;
|
|
82
|
+
}, { added: [], removed: update.removed, names: update.removed.slice() });
|
|
83
|
+
}
|
|
84
|
+
function convertInstantUpdateToDefinitionChanges(instantUpdate) {
|
|
85
|
+
var payload = instantUpdate.payload, changeNumber = instantUpdate.changeNumber;
|
|
86
|
+
return payload.status === 'ARCHIVED' ?
|
|
87
|
+
{ till: changeNumber, updated: [], removed: [payload.name] } :
|
|
88
|
+
{ till: changeNumber, updated: [payload], removed: [] };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Factory of DefinitionChanges updater, a task that:
|
|
92
|
+
* - fetches definition changes using `definitionChangesFetcher`
|
|
93
|
+
* - updates definitions storage
|
|
94
|
+
* - uses `definitionsEventEmitter` to emit events related to definition data updates
|
|
95
|
+
*
|
|
96
|
+
* @param log - Logger instance
|
|
97
|
+
* @param definitionChangesFetcher - Fetcher of `/splitChanges` or `/configs`
|
|
98
|
+
* @param definitions - Definitions storage, with sync or async methods
|
|
99
|
+
* @param segments - Segments storage, with sync or async methods
|
|
100
|
+
* @param definitionsEventEmitter - Optional readiness manager. Not required for synchronizer or producer mode.
|
|
101
|
+
* @param requestTimeoutBeforeReady - How long the updater will wait for the request to timeout. Default 0, i.e., never timeout.
|
|
102
|
+
* @param retriesOnFailureBeforeReady - How many retries on `/splitChanges` or `/configs` we the updater do in case of failure or timeout. Default 0, i.e., no retries.
|
|
103
|
+
*/
|
|
104
|
+
export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, storage, splitFiltersValidation, definitionsEventEmitter, requestTimeoutBeforeReady, retriesOnFailureBeforeReady, isClientSide) {
|
|
105
|
+
if (requestTimeoutBeforeReady === void 0) { requestTimeoutBeforeReady = 0; }
|
|
106
|
+
if (retriesOnFailureBeforeReady === void 0) { retriesOnFailureBeforeReady = 0; }
|
|
107
|
+
var definitions = storage.definitions, rbSegments = storage.rbSegments, segments = storage.segments;
|
|
108
|
+
var startingUp = true;
|
|
109
|
+
/** timeout decorator for `definitionChangesFetcher` promise */
|
|
110
|
+
function _promiseDecorator(promise) {
|
|
111
|
+
if (startingUp && requestTimeoutBeforeReady)
|
|
112
|
+
promise = timeout(requestTimeoutBeforeReady, promise);
|
|
113
|
+
return promise;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* DefinitionChanges updater returns a promise that resolves with a `false` boolean value if it fails to fetch definitions or synchronize them with the storage.
|
|
117
|
+
* Returned promise will not be rejected.
|
|
118
|
+
*
|
|
119
|
+
* @param noCache - true to revalidate data to fetch
|
|
120
|
+
* @param till - query param to bypass CDN requests
|
|
121
|
+
*/
|
|
122
|
+
return function definitionChangesUpdater(noCache, till, instantUpdate) {
|
|
123
|
+
/**
|
|
124
|
+
* @param since - current changeNumber at definitionsCache
|
|
125
|
+
* @param retry - current number of retry attempts
|
|
126
|
+
*/
|
|
127
|
+
function _definitionChangesUpdater(sinces, retry) {
|
|
128
|
+
if (retry === void 0) { retry = 0; }
|
|
129
|
+
var since = sinces[0], rbSince = sinces[1];
|
|
130
|
+
log.debug(SYNC_FETCH, [definitionChangesFetcher.type, since, rbSince]);
|
|
131
|
+
return Promise.resolve(instantUpdate ?
|
|
132
|
+
instantUpdate.type === SPLIT_UPDATE ?
|
|
133
|
+
// IFFU edge case: a change to definition that adds an IN_RULE_BASED_SEGMENT matcher that is not present yet
|
|
134
|
+
Promise.resolve(rbSegments.contains(parseSegments(instantUpdate.payload, IN_RULE_BASED_SEGMENT))).then(function (contains) {
|
|
135
|
+
return contains ?
|
|
136
|
+
{ d: convertInstantUpdateToDefinitionChanges(instantUpdate) } :
|
|
137
|
+
definitionChangesFetcher(since, noCache, till, rbSince, _promiseDecorator);
|
|
138
|
+
}) :
|
|
139
|
+
{ rbs: convertInstantUpdateToDefinitionChanges(instantUpdate) } :
|
|
140
|
+
definitionChangesFetcher(since, noCache, till, rbSince, _promiseDecorator))
|
|
141
|
+
.then(function (definitionChanges) {
|
|
142
|
+
var usedSegments = new Set();
|
|
143
|
+
var updatedDefinitions = [];
|
|
144
|
+
var ffUpdate = false;
|
|
145
|
+
if (definitionChanges.d) {
|
|
146
|
+
var _a = computeMutation(definitionChanges.d, usedSegments, splitFiltersValidation), added = _a.added, removed = _a.removed, names = _a.names;
|
|
147
|
+
updatedDefinitions = names;
|
|
148
|
+
log.debug(SYNC_UPDATE, [definitionChangesFetcher.type, added.length, removed.length]);
|
|
149
|
+
ffUpdate = definitions.update(added, removed, definitionChanges.d.till);
|
|
150
|
+
}
|
|
151
|
+
var rbsUpdate = false;
|
|
152
|
+
if (definitionChanges.rbs) {
|
|
153
|
+
var _b = computeMutation(definitionChanges.rbs, usedSegments), added = _b.added, removed = _b.removed;
|
|
154
|
+
log.debug(SYNC_UPDATE, ['rule-based segments', added.length, removed.length]);
|
|
155
|
+
rbsUpdate = rbSegments.update(added, removed, definitionChanges.rbs.till);
|
|
156
|
+
}
|
|
157
|
+
return Promise.all([ffUpdate, rbsUpdate,
|
|
158
|
+
// @TODO if at least 1 segment fetch fails due to 404 and other segments are updated in the storage, SDK_UPDATE is not emitted
|
|
159
|
+
segments.registerSegments(setToArray(usedSegments))
|
|
160
|
+
]).then(function (_a) {
|
|
161
|
+
var ffChanged = _a[0], rbsChanged = _a[1];
|
|
162
|
+
if (storage.save)
|
|
163
|
+
storage.save();
|
|
164
|
+
startingUp = false;
|
|
165
|
+
if (definitionsEventEmitter) {
|
|
166
|
+
// To emit SDK_DEFINITIONS_ARRIVED for server-side SDK, we must check that all registered segments have been fetched
|
|
167
|
+
return Promise.resolve(!definitionsEventEmitter.definitionsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
|
|
168
|
+
.catch(function () { return false; } /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
|
|
169
|
+
.then(function (emitSplitsArrivedEvent) {
|
|
170
|
+
// emit SDK events
|
|
171
|
+
if (emitSplitsArrivedEvent) {
|
|
172
|
+
var metadata = {
|
|
173
|
+
type: updatedDefinitions.length > 0 ? definitionChangesFetcher.type === 'configs' ? CONFIGS_UPDATE : FLAGS_UPDATE : SEGMENTS_UPDATE,
|
|
174
|
+
names: updatedDefinitions.length > 0 ? updatedDefinitions : []
|
|
175
|
+
};
|
|
176
|
+
definitionsEventEmitter.emit(SDK_DEFINITIONS_ARRIVED, metadata);
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return true;
|
|
182
|
+
});
|
|
183
|
+
})
|
|
184
|
+
.catch(function (error) {
|
|
185
|
+
if (startingUp && retriesOnFailureBeforeReady > retry) {
|
|
186
|
+
retry += 1;
|
|
187
|
+
log.warn(SYNC_FETCH_RETRY, [definitionChangesFetcher.type, retry, error]);
|
|
188
|
+
return _definitionChangesUpdater(sinces, retry);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
startingUp = false;
|
|
192
|
+
log.warn(SYNC_FETCH_FAILS, [definitionChangesFetcher.type, error]);
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
// `getChangeNumber` never rejects or throws error
|
|
198
|
+
return Promise.all([definitions.getChangeNumber(), rbSegments.getChangeNumber()]).then(_definitionChangesUpdater);
|
|
199
|
+
};
|
|
200
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { timeout } from '../../../utils/promise/timeout';
|
|
2
2
|
import { SDK_SEGMENTS_ARRIVED, SEGMENTS_UPDATE } from '../../../readiness/constants';
|
|
3
|
-
import {
|
|
3
|
+
import { SYNC_FETCH_RETRY } from '../../../logger/constants';
|
|
4
4
|
import { MEMBERSHIPS_LS_UPDATE } from '../../streaming/constants';
|
|
5
|
-
import { usesSegmentsSync } from '../../../storages/
|
|
5
|
+
import { usesSegmentsSync } from '../../../storages/AbstractDefinitionsCacheSync';
|
|
6
6
|
/**
|
|
7
7
|
* factory of MySegments updater, a task that:
|
|
8
8
|
* - fetches mySegments using `mySegmentsFetcher`
|
|
@@ -53,7 +53,7 @@ export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, storage, segmen
|
|
|
53
53
|
return updaterPromise.catch(function (error) {
|
|
54
54
|
if (startingUp && retriesOnFailureBeforeReady > retry) {
|
|
55
55
|
retry += 1;
|
|
56
|
-
log.warn(
|
|
56
|
+
log.warn(SYNC_FETCH_RETRY, ['memberships', retry, error]);
|
|
57
57
|
return _mySegmentsUpdater(retry); // no need to forward `segmentList` and `noCache` params
|
|
58
58
|
}
|
|
59
59
|
else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SDK_SEGMENTS_ARRIVED, SEGMENTS_UPDATE } from '../../../readiness/constants';
|
|
2
|
-
import { LOG_PREFIX_INSTANTIATION,
|
|
2
|
+
import { LOG_PREFIX_INSTANTIATION, LOG_PREFIX_SYNC } from '../../../logger/constants';
|
|
3
3
|
import { timeout } from '../../../utils/promise/timeout';
|
|
4
4
|
/**
|
|
5
5
|
* Factory of SegmentChanges updater, a task that:
|
|
@@ -20,7 +20,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
20
20
|
return promise;
|
|
21
21
|
}
|
|
22
22
|
function updateSegment(segmentName, noCache, till, fetchOnlyNew, retries) {
|
|
23
|
-
log.debug(
|
|
23
|
+
log.debug("".concat(LOG_PREFIX_SYNC, "Processing segment ").concat(segmentName));
|
|
24
24
|
var sincePromise = Promise.resolve(segments.getChangeNumber(segmentName));
|
|
25
25
|
return sincePromise.then(function (since) {
|
|
26
26
|
// if fetchOnlyNew flag, avoid processing already fetched segments
|
|
@@ -28,14 +28,14 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
28
28
|
false :
|
|
29
29
|
segmentChangesFetcher(since || -1, segmentName, noCache, till, _promiseDecorator).then(function (changes) {
|
|
30
30
|
return Promise.all(changes.map(function (x) {
|
|
31
|
-
log.debug(
|
|
31
|
+
log.debug("".concat(LOG_PREFIX_SYNC, "Processing ").concat(segmentName, " with till = ").concat(x.till, ". Added: ").concat(x.added.length, ". Removed: ").concat(x.removed.length));
|
|
32
32
|
return segments.update(segmentName, x.added, x.removed, x.till);
|
|
33
33
|
})).then(function (updates) {
|
|
34
34
|
return updates.some(function (update) { return update; });
|
|
35
35
|
});
|
|
36
36
|
}).catch(function (error) {
|
|
37
37
|
if (retries) {
|
|
38
|
-
log.warn(
|
|
38
|
+
log.warn("".concat(LOG_PREFIX_SYNC, "Retrying fetch of segment ").concat(segmentName, " (attempt #").concat(retries, "). Reason: ").concat(error));
|
|
39
39
|
return updateSegment(segmentName, noCache, till, fetchOnlyNew, retries - 1);
|
|
40
40
|
}
|
|
41
41
|
throw error;
|
|
@@ -54,7 +54,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
54
54
|
* @param till - till target for the provided segmentName, for CDN bypass.
|
|
55
55
|
*/
|
|
56
56
|
return function segmentChangesUpdater(fetchOnlyNew, segmentName, noCache, till) {
|
|
57
|
-
log.debug(
|
|
57
|
+
log.debug("".concat(LOG_PREFIX_SYNC, "Started segments update"));
|
|
58
58
|
// If not a segment name provided, read list of available segments names to be updated.
|
|
59
59
|
var segmentsPromise = Promise.resolve(segmentName ? [segmentName] : segments.getRegisteredSegments());
|
|
60
60
|
return segmentsPromise.then(function (segmentNames) {
|
|
@@ -81,10 +81,10 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
81
81
|
// @TODO although factory status is destroyed, synchronization is not stopped
|
|
82
82
|
if (readiness)
|
|
83
83
|
readiness.setDestroyed();
|
|
84
|
-
log.error(LOG_PREFIX_INSTANTIATION
|
|
84
|
+
log.error("".concat(LOG_PREFIX_INSTANTIATION, ": you passed a client-side type authorizationKey, please grab an SDK Key from Harness UI that is of type server-side."));
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
|
-
log.warn(
|
|
87
|
+
log.warn("".concat(LOG_PREFIX_SYNC, "Error while doing fetch of segments. ").concat(error));
|
|
88
88
|
}
|
|
89
89
|
return false;
|
|
90
90
|
});
|
|
@@ -57,11 +57,11 @@ var SSEClient = /** @class */ (function () {
|
|
|
57
57
|
var params = CONTROL_CHANNEL_REGEX.test(channel) ? '[?occupancy=metrics.publishers]' : '';
|
|
58
58
|
return encodeURIComponent(params + channel);
|
|
59
59
|
}).join(',');
|
|
60
|
-
var url = this.settings.urls.streaming
|
|
60
|
+
var url = "".concat(this.settings.urls.streaming, "/sse?channels=").concat(channelsQueryParam, "&accessToken=").concat(authToken.token, "&v=").concat(ABLY_API_VERSION, "&heartbeats=true"); // same results using `&heartbeats=false`
|
|
61
61
|
var isServerSide = checkIfServerSide(this.settings);
|
|
62
62
|
this.connection = new this.eventSource(
|
|
63
63
|
// For client-side SDKs, metadata is passed as query param to avoid CORS issues and because native EventSource implementations in browsers do not support headers
|
|
64
|
-
isServerSide ? url : url +
|
|
64
|
+
isServerSide ? url : url + "&SplitSDKVersion=".concat(this.headers.SplitSDKVersion, "&SplitSDKClientKey=").concat(this.headers.SplitSDKClientKey),
|
|
65
65
|
// For server-side SDKs, metadata is passed via headers
|
|
66
66
|
objectAssign(isServerSide ?
|
|
67
67
|
{ headers: decorateHeaders(this.settings, this.headers) } :
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CONNECTION_ESTABLISHED, DISABLED, ENABLED, OCCUPANCY_PRI, OCCUPANCY_SEC, PAUSED, STREAMING_STATUS } from '../../../utils/constants';
|
|
2
|
-
import { ControlType, PUSH_SUBSYSTEM_UP,
|
|
2
|
+
import { ControlType, PUSH_SUBSYSTEM_UP, PUSH_NON_RETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN } from '../constants';
|
|
3
3
|
var CONTROL_CHANNEL_REGEXS = [/control_pri$/, /control_sec$/];
|
|
4
4
|
var STREAMING_EVENT_TYPES = [OCCUPANCY_PRI, OCCUPANCY_SEC];
|
|
5
5
|
/**
|
|
@@ -70,7 +70,7 @@ export function notificationKeeperFactory(pushEmitter, telemetryTracker) {
|
|
|
70
70
|
c.cTime = timestamp;
|
|
71
71
|
if (controlType === ControlType.STREAMING_DISABLED) {
|
|
72
72
|
telemetryTracker.streamingEvent(STREAMING_STATUS, DISABLED);
|
|
73
|
-
pushEmitter.emit(
|
|
73
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
74
74
|
}
|
|
75
75
|
else if (hasPublishers) {
|
|
76
76
|
if (controlType === ControlType.STREAMING_PAUSED && hasResumed) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { errorParser, messageParser } from './NotificationParser';
|
|
2
2
|
import { notificationKeeperFactory } from './NotificationKeeper';
|
|
3
|
-
import { PUSH_RETRYABLE_ERROR,
|
|
3
|
+
import { PUSH_RETRYABLE_ERROR, PUSH_NON_RETRYABLE_ERROR, OCCUPANCY, CONTROL, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, RB_SEGMENT_UPDATE } from '../constants';
|
|
4
4
|
import { STREAMING_PARSING_ERROR_FAILS, ERROR_STREAMING_SSE, STREAMING_PARSING_MESSAGE_FAILS, STREAMING_NEW_MESSAGE } from '../../../logger/constants';
|
|
5
5
|
import { ABLY_ERROR, NON_REQUESTED, SSE_CONNECTION_ERROR } from '../../../utils/constants';
|
|
6
6
|
/**
|
|
@@ -48,7 +48,7 @@ export function SSEHandlerFactory(log, pushEmitter, telemetryTracker) {
|
|
|
48
48
|
pushEmitter.emit(PUSH_RETRYABLE_ERROR);
|
|
49
49
|
}
|
|
50
50
|
else {
|
|
51
|
-
pushEmitter.emit(
|
|
51
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
54
|
/* NotificationProcessor */
|
package/esm/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js}
RENAMED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
import { STREAMING_PARSING_SPLIT_UPDATE } from '../../../logger/constants';
|
|
2
|
-
import {
|
|
2
|
+
import { SDK_DEFINITIONS_ARRIVED } from '../../../readiness/constants';
|
|
3
3
|
import { Backoff } from '../../../utils/Backoff';
|
|
4
4
|
import { SPLITS } from '../../../utils/constants';
|
|
5
5
|
import { RB_SEGMENT_UPDATE } from '../constants';
|
|
6
6
|
import { parseFFUpdatePayload } from '../parseUtils';
|
|
7
7
|
import { FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT, FETCH_BACKOFF_MAX_RETRIES } from './constants';
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* DefinitionsUpdateWorker factory
|
|
10
10
|
*/
|
|
11
|
-
export function
|
|
12
|
-
var ff =
|
|
13
|
-
var rbs =
|
|
14
|
-
function
|
|
11
|
+
export function DefinitionsUpdateWorker(log, storage, definitionsSyncTask, definitionsEventEmitter, telemetryTracker, segmentsSyncTask) {
|
|
12
|
+
var ff = DefinitionsUpdateWorker(storage.definitions);
|
|
13
|
+
var rbs = DefinitionsUpdateWorker(storage.rbSegments);
|
|
14
|
+
function DefinitionsUpdateWorker(cache) {
|
|
15
15
|
var maxChangeNumber = -1;
|
|
16
16
|
var handleNewEvent = false;
|
|
17
17
|
var isHandlingEvent;
|
|
18
18
|
var cdnBypass;
|
|
19
19
|
var instantUpdate;
|
|
20
|
-
var backoff = new Backoff(
|
|
21
|
-
function
|
|
20
|
+
var backoff = new Backoff(__handleDefinitionUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
|
|
21
|
+
function __handleDefinitionUpdateCall() {
|
|
22
22
|
isHandlingEvent = true;
|
|
23
23
|
if (maxChangeNumber > cache.getChangeNumber()) {
|
|
24
24
|
handleNewEvent = false;
|
|
25
25
|
// fetch splits revalidating data if cached
|
|
26
|
-
|
|
26
|
+
definitionsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(function () {
|
|
27
27
|
if (!isHandlingEvent)
|
|
28
28
|
return; // halt if `stop` has been called
|
|
29
29
|
if (handleNewEvent) {
|
|
30
|
-
|
|
30
|
+
__handleDefinitionUpdateCall();
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
33
|
if (instantUpdate)
|
|
@@ -37,7 +37,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
37
37
|
segmentsSyncTask.execute(true);
|
|
38
38
|
var attempts = backoff.attempts + 1;
|
|
39
39
|
if (ff.isSync() && rbs.isSync()) {
|
|
40
|
-
log.debug("Refresh completed"
|
|
40
|
+
log.debug("Refresh completed".concat(cdnBypass ? ' bypassing the CDN' : '', " in ").concat(attempts, " attempts."));
|
|
41
41
|
isHandlingEvent = false;
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
@@ -46,13 +46,13 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
if (cdnBypass) {
|
|
49
|
-
log.debug("No changes fetched after "
|
|
49
|
+
log.debug("No changes fetched after ".concat(attempts, " attempts with CDN bypassed."));
|
|
50
50
|
isHandlingEvent = false;
|
|
51
51
|
}
|
|
52
52
|
else {
|
|
53
53
|
backoff.reset();
|
|
54
54
|
cdnBypass = true;
|
|
55
|
-
|
|
55
|
+
__handleDefinitionUpdateCall();
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
});
|
|
@@ -80,7 +80,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
80
80
|
instantUpdate = { payload: payload, changeNumber: changeNumber, type: type };
|
|
81
81
|
}
|
|
82
82
|
if (backoff.timeoutID || !isHandlingEvent)
|
|
83
|
-
|
|
83
|
+
__handleDefinitionUpdateCall();
|
|
84
84
|
backoff.reset();
|
|
85
85
|
},
|
|
86
86
|
stop: function () {
|
|
@@ -115,11 +115,11 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
115
115
|
* @param splitName - name of split to kill
|
|
116
116
|
* @param defaultTreatment - default treatment value
|
|
117
117
|
*/
|
|
118
|
-
|
|
118
|
+
killDefinition: function (_a) {
|
|
119
119
|
var changeNumber = _a.changeNumber, splitName = _a.splitName, defaultTreatment = _a.defaultTreatment;
|
|
120
|
-
if (storage.
|
|
120
|
+
if (storage.definitions.killLocally(splitName, defaultTreatment, changeNumber)) {
|
|
121
121
|
// trigger an SDK_UPDATE if Split was killed locally
|
|
122
|
-
|
|
122
|
+
definitionsEventEmitter.emit(SDK_DEFINITIONS_ARRIVED, true);
|
|
123
123
|
}
|
|
124
124
|
// queues the SplitChanges fetch (only if changeNumber is newer)
|
|
125
125
|
ff.put({ changeNumber: changeNumber });
|
|
@@ -48,7 +48,7 @@ export function MySegmentsUpdateWorker(log, storage, mySegmentsSyncTask, telemet
|
|
|
48
48
|
telemetryTracker.trackUpdatesFromSSE(MEMBERSHIPS);
|
|
49
49
|
var attempts = backoff.attempts + 1;
|
|
50
50
|
if (maxChangeNumber <= currentChangeNumber) {
|
|
51
|
-
log.debug("Refresh completed"
|
|
51
|
+
log.debug("Refresh completed".concat(cdnBypass ? ' bypassing the CDN' : '', " in ").concat(attempts, " attempts."));
|
|
52
52
|
isHandlingEvent = false;
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
@@ -57,7 +57,7 @@ export function MySegmentsUpdateWorker(log, storage, mySegmentsSyncTask, telemet
|
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
59
|
if (cdnBypass) {
|
|
60
|
-
log.debug("No changes fetched after "
|
|
60
|
+
log.debug("No changes fetched after ".concat(attempts, " attempts with CDN bypassed."));
|
|
61
61
|
isHandlingEvent = false;
|
|
62
62
|
}
|
|
63
63
|
else {
|
|
@@ -25,7 +25,7 @@ export function SegmentsUpdateWorker(log, segmentsSyncTask, segmentsCache) {
|
|
|
25
25
|
else {
|
|
26
26
|
var attempts = backoff.attempts + 1;
|
|
27
27
|
if (maxChangeNumber <= (segmentsCache.getChangeNumber(segment) || -1)) {
|
|
28
|
-
log.debug("Refresh completed"
|
|
28
|
+
log.debug("Refresh completed".concat(cdnBypass ? ' bypassing the CDN' : '', " in ").concat(attempts, " attempts."));
|
|
29
29
|
isHandlingEvent = false;
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
@@ -34,7 +34,7 @@ export function SegmentsUpdateWorker(log, segmentsSyncTask, segmentsCache) {
|
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
if (cdnBypass) {
|
|
37
|
-
log.debug("No changes fetched after "
|
|
37
|
+
log.debug("No changes fetched after ".concat(attempts, " attempts with CDN bypassed."));
|
|
38
38
|
isHandlingEvent = false;
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
@@ -5,7 +5,7 @@ export var SECONDS_BEFORE_EXPIRATION = 600;
|
|
|
5
5
|
* emitted on SSE and Authenticate non-recoverable errors, STREAMING_DISABLED control notification and authentication with pushEnabled false
|
|
6
6
|
* triggers `handleNonRetryableError` call
|
|
7
7
|
*/
|
|
8
|
-
export var
|
|
8
|
+
export var PUSH_NON_RETRYABLE_ERROR = 'PUSH_NON_RETRYABLE_ERROR';
|
|
9
9
|
/**
|
|
10
10
|
* emitted on SSE and Authenticate recoverable errors
|
|
11
11
|
* triggers `handleRetryableError` call
|
|
@@ -17,7 +17,7 @@ export var PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR';
|
|
|
17
17
|
*/
|
|
18
18
|
export var PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
|
|
19
19
|
/**
|
|
20
|
-
* emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0,
|
|
20
|
+
* emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0, PUSH_NON_RETRYABLE_ERROR and PUSH_RETRYABLE_ERROR events.
|
|
21
21
|
* triggers `startPolling` and `stopWorkers` calls
|
|
22
22
|
*/
|
|
23
23
|
export var PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
|