@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
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sdkLifecycleFactory = void 0;
|
|
4
|
+
var apiKey_1 = require("../utils/inputValidation/apiKey");
|
|
5
|
+
var COOLDOWN_TIME_IN_MILLIS = 1000;
|
|
6
|
+
/**
|
|
7
|
+
* Creates an Sdk client, i.e., a base client with status, init, flush and destroy interface
|
|
8
|
+
*/
|
|
9
|
+
function sdkLifecycleFactory(params, isSharedClient) {
|
|
10
|
+
var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, settings = params.settings, telemetryTracker = params.telemetryTracker, impressionsTracker = params.impressionsTracker, platform = params.platform, splitApi = params.splitApi;
|
|
11
|
+
var hasInit = false;
|
|
12
|
+
var lastActionTime = 0;
|
|
13
|
+
var signalListener = platform.SignalListener && new platform.SignalListener(params);
|
|
14
|
+
function __cooldown(func, time) {
|
|
15
|
+
var now = Date.now();
|
|
16
|
+
//get the actual time elapsed in ms
|
|
17
|
+
var timeElapsed = now - lastActionTime;
|
|
18
|
+
//check if the time elapsed is less than desired cooldown
|
|
19
|
+
if (timeElapsed < time) {
|
|
20
|
+
//if yes, return message with remaining time in seconds
|
|
21
|
+
settings.log.warn("Flush cooldown, remaining time ".concat((time - timeElapsed) / 1000, " seconds"));
|
|
22
|
+
return Promise.resolve();
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
//Do the requested action and re-assign the lastActionTime
|
|
26
|
+
lastActionTime = now;
|
|
27
|
+
return func();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function __flush() {
|
|
31
|
+
return syncManager ? syncManager.flush() : Promise.resolve();
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
init: function () {
|
|
35
|
+
if (hasInit)
|
|
36
|
+
return;
|
|
37
|
+
hasInit = true;
|
|
38
|
+
if (!isSharedClient) {
|
|
39
|
+
(0, apiKey_1.validateAndTrackApiKey)(settings.log, settings.core.authorizationKey);
|
|
40
|
+
sdkReadinessManager.readinessManager.init();
|
|
41
|
+
impressionsTracker.start();
|
|
42
|
+
syncManager && syncManager.start();
|
|
43
|
+
signalListener && signalListener.start();
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
flush: function () {
|
|
47
|
+
// @TODO define cooldown time
|
|
48
|
+
return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
|
|
49
|
+
},
|
|
50
|
+
destroy: function () {
|
|
51
|
+
hasInit = false;
|
|
52
|
+
// Mark the SDK as destroyed immediately
|
|
53
|
+
sdkReadinessManager.readinessManager.destroy();
|
|
54
|
+
// For main client, cleanup the SDK Key, listeners and scheduled jobs, and record stat before flushing data
|
|
55
|
+
if (!isSharedClient) {
|
|
56
|
+
(0, apiKey_1.releaseApiKey)(settings.core.authorizationKey);
|
|
57
|
+
telemetryTracker.sessionLength();
|
|
58
|
+
signalListener && signalListener.stop();
|
|
59
|
+
impressionsTracker.stop();
|
|
60
|
+
}
|
|
61
|
+
// Stop background jobs
|
|
62
|
+
syncManager && syncManager.stop();
|
|
63
|
+
splitApi && splitApi.stop();
|
|
64
|
+
return __flush().then(function () {
|
|
65
|
+
// Cleanup storage
|
|
66
|
+
return storage.destroy();
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
exports.sdkLifecycleFactory = sdkLifecycleFactory;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.trackMethodFactory = void 0;
|
|
4
|
+
var thenable_1 = require("../utils/promise/thenable");
|
|
5
|
+
var key_1 = require("../utils/key");
|
|
6
|
+
var trafficTypeExistence_1 = require("../utils/inputValidation/trafficTypeExistence");
|
|
7
|
+
var inputValidation_1 = require("../utils/inputValidation");
|
|
8
|
+
var constants_1 = require("../utils/constants");
|
|
9
|
+
var mode_1 = require("../utils/settingsValidation/mode");
|
|
10
|
+
/**
|
|
11
|
+
* Creates a standalone `track` function with input validation.
|
|
12
|
+
* Reusable by FF SDK client, Configs SDK, and thin-client SDK.
|
|
13
|
+
*/
|
|
14
|
+
function trackMethodFactory(params, warnTTExistence) {
|
|
15
|
+
if (warnTTExistence === void 0) { warnTTExistence = true; }
|
|
16
|
+
var settings = params.settings, definitions = params.storage.definitions, telemetryTracker = params.telemetryTracker, eventTracker = params.eventTracker, readinessManager = params.sdkReadinessManager.readinessManager;
|
|
17
|
+
var log = settings.log, mode = settings.mode;
|
|
18
|
+
var isAsync = (0, mode_1.isConsumerMode)(mode);
|
|
19
|
+
return function track(maybeKey, maybeTT, maybeEvent, maybeEventValue, maybeProperties) {
|
|
20
|
+
// Input validation
|
|
21
|
+
var key = (0, inputValidation_1.validateKey)(log, maybeKey, constants_1.TRACK_FN_LABEL);
|
|
22
|
+
var trafficTypeName = (0, inputValidation_1.validateTrafficType)(log, maybeTT, constants_1.TRACK_FN_LABEL);
|
|
23
|
+
var eventTypeId = (0, inputValidation_1.validateEvent)(log, maybeEvent, constants_1.TRACK_FN_LABEL);
|
|
24
|
+
var value = (0, inputValidation_1.validateEventValue)(log, maybeEventValue, constants_1.TRACK_FN_LABEL);
|
|
25
|
+
var _a = (0, inputValidation_1.validateEventProperties)(log, maybeProperties, constants_1.TRACK_FN_LABEL), properties = _a.properties, size = _a.size;
|
|
26
|
+
var isNotDestroyed = (0, inputValidation_1.validateIfNotDestroyed)(log, readinessManager, constants_1.TRACK_FN_LABEL);
|
|
27
|
+
if (!(isNotDestroyed && key && trafficTypeName && eventTypeId && value !== false && properties !== false)) {
|
|
28
|
+
return isAsync ? Promise.resolve(false) : false;
|
|
29
|
+
}
|
|
30
|
+
// Core logic
|
|
31
|
+
var stopTelemetryTracker = telemetryTracker.trackEval(constants_1.TRACK);
|
|
32
|
+
var eventData = {
|
|
33
|
+
eventTypeId: eventTypeId,
|
|
34
|
+
trafficTypeName: trafficTypeName,
|
|
35
|
+
value: value,
|
|
36
|
+
timestamp: Date.now(),
|
|
37
|
+
key: (0, key_1.getMatching)(key),
|
|
38
|
+
properties: properties
|
|
39
|
+
};
|
|
40
|
+
// 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.
|
|
41
|
+
if (warnTTExistence)
|
|
42
|
+
(0, trafficTypeExistence_1.validateTrafficTypeExistence)(log, readinessManager, definitions, mode, trafficTypeName, constants_1.TRACK_FN_LABEL);
|
|
43
|
+
var result = eventTracker.track(eventData, size);
|
|
44
|
+
if ((0, thenable_1.thenable)(result)) {
|
|
45
|
+
return result.then(function (result) {
|
|
46
|
+
stopTelemetryTracker();
|
|
47
|
+
return result;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
stopTelemetryTracker();
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
exports.trackMethodFactory = trackMethodFactory;
|
package/cjs/sdkFactory/index.js
CHANGED
|
@@ -5,16 +5,10 @@ var sdkReadinessManager_1 = require("../readiness/sdkReadinessManager");
|
|
|
5
5
|
var impressionsTracker_1 = require("../trackers/impressionsTracker");
|
|
6
6
|
var eventTracker_1 = require("../trackers/eventTracker");
|
|
7
7
|
var telemetryTracker_1 = require("../trackers/telemetryTracker");
|
|
8
|
-
var apiKey_1 = require("../utils/inputValidation/apiKey");
|
|
9
8
|
var sdkLogger_1 = require("../logger/sdkLogger");
|
|
10
9
|
var constants_1 = require("../logger/constants");
|
|
11
10
|
var constants_2 = require("../readiness/constants");
|
|
12
11
|
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
13
|
-
var strategyDebug_1 = require("../trackers/strategy/strategyDebug");
|
|
14
|
-
var strategyOptimized_1 = require("../trackers/strategy/strategyOptimized");
|
|
15
|
-
var strategyNone_1 = require("../trackers/strategy/strategyNone");
|
|
16
|
-
var uniqueKeysTracker_1 = require("../trackers/uniqueKeysTracker");
|
|
17
|
-
var constants_3 = require("../utils/constants");
|
|
18
12
|
var setRolloutPlan_1 = require("../storages/setRolloutPlan");
|
|
19
13
|
var key_1 = require("../utils/key");
|
|
20
14
|
var fallbackTreatmentsCalculator_1 = require("../evaluator/fallbackTreatmentsCalculator");
|
|
@@ -22,19 +16,10 @@ var fallbackTreatmentsCalculator_1 = require("../evaluator/fallbackTreatmentsCal
|
|
|
22
16
|
* Modular SDK factory
|
|
23
17
|
*/
|
|
24
18
|
function sdkFactory(params) {
|
|
25
|
-
var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory,
|
|
26
|
-
var log = settings.log,
|
|
19
|
+
var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, lazyInit = params.lazyInit;
|
|
20
|
+
var log = settings.log, initialRolloutPlan = settings.initialRolloutPlan, key = settings.core.key;
|
|
27
21
|
// @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid SDK Key, etc.
|
|
28
22
|
// On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
|
|
29
|
-
// initialization
|
|
30
|
-
var hasInit = false;
|
|
31
|
-
var initCallbacks = [];
|
|
32
|
-
function whenInit(cb) {
|
|
33
|
-
if (hasInit)
|
|
34
|
-
cb();
|
|
35
|
-
else
|
|
36
|
-
initCallbacks.push(cb);
|
|
37
|
-
}
|
|
38
23
|
var sdkReadinessManager = (0, sdkReadinessManager_1.sdkReadinessManagerFactory)(platform.EventEmitter, settings);
|
|
39
24
|
var readiness = sdkReadinessManager.readinessManager;
|
|
40
25
|
var storage = storageFactory({
|
|
@@ -45,54 +30,33 @@ function sdkFactory(params) {
|
|
|
45
30
|
readiness.timeout();
|
|
46
31
|
return;
|
|
47
32
|
}
|
|
48
|
-
readiness.
|
|
33
|
+
readiness.definitions.emit(constants_2.SDK_DEFINITIONS_ARRIVED);
|
|
49
34
|
readiness.segments.emit(constants_2.SDK_SEGMENTS_ARRIVED);
|
|
50
35
|
},
|
|
51
36
|
onReadyFromCacheCb: function () {
|
|
52
|
-
readiness.
|
|
37
|
+
readiness.definitions.emit(constants_2.SDK_DEFINITIONS_CACHE_LOADED);
|
|
53
38
|
}
|
|
54
39
|
});
|
|
55
|
-
var
|
|
40
|
+
var fallbackCalculator = (0, fallbackTreatmentsCalculator_1.FallbackTreatmentsCalculator)(settings.fallbackTreatments);
|
|
56
41
|
if (initialRolloutPlan) {
|
|
57
42
|
(0, setRolloutPlan_1.setRolloutPlan)(log, initialRolloutPlan, storage, key && (0, key_1.getMatching)(key));
|
|
58
|
-
if (storage.
|
|
59
|
-
readiness.
|
|
43
|
+
if (storage.definitions.getChangeNumber() > -1)
|
|
44
|
+
readiness.definitions.emit(constants_2.SDK_DEFINITIONS_CACHE_LOADED, { initialCacheLoad: false /* Not an initial load, cache exists */ });
|
|
60
45
|
}
|
|
61
46
|
var clients = {};
|
|
62
47
|
var telemetryTracker = (0, telemetryTracker_1.telemetryTrackerFactory)(storage.telemetry, platform.now);
|
|
63
48
|
var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
|
|
64
|
-
var
|
|
65
|
-
var
|
|
66
|
-
var noneStrategy = (0, strategyNone_1.strategyNoneFactory)(storage.impressionCounts, uniqueKeysTracker);
|
|
67
|
-
var strategy = impressionsMode === constants_3.OPTIMIZED ?
|
|
68
|
-
(0, strategyOptimized_1.strategyOptimizedFactory)(observer, storage.impressionCounts) :
|
|
69
|
-
impressionsMode === constants_3.DEBUG ?
|
|
70
|
-
(0, strategyDebug_1.strategyDebugFactory)(observer) :
|
|
71
|
-
noneStrategy;
|
|
72
|
-
var impressionsTracker = (0, impressionsTracker_1.impressionsTrackerFactory)(settings, storage.impressions, noneStrategy, strategy, whenInit, integrationsManager, storage.telemetry);
|
|
73
|
-
var eventTracker = (0, eventTracker_1.eventTrackerFactory)(settings, storage.events, whenInit, integrationsManager, storage.telemetry);
|
|
49
|
+
var impressionsTracker = (0, impressionsTracker_1.impressionsTrackerFactory)(params, storage, integrationsManager);
|
|
50
|
+
var eventTracker = (0, eventTracker_1.eventTrackerFactory)(settings, storage.events, integrationsManager, storage.telemetry);
|
|
74
51
|
// splitApi is used by SyncManager and Browser signal listener
|
|
75
52
|
var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
|
|
76
|
-
var ctx = { clients: clients, splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker,
|
|
77
|
-
|
|
78
|
-
ctx.syncManager = syncManager;
|
|
79
|
-
var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
|
|
80
|
-
ctx.signalListener = signalListener;
|
|
53
|
+
var ctx = { clients: clients, splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform, fallbackCalculator: fallbackCalculator };
|
|
54
|
+
ctx.syncManager = syncManagerFactory && syncManagerFactory(ctx);
|
|
81
55
|
// SDK client and manager
|
|
82
56
|
var clientMethod = sdkClientMethodFactory(ctx);
|
|
83
|
-
var managerInstance = sdkManagerFactory(settings, storage.
|
|
57
|
+
var managerInstance = sdkManagerFactory(settings, storage.definitions, sdkReadinessManager);
|
|
84
58
|
function init() {
|
|
85
|
-
|
|
86
|
-
return;
|
|
87
|
-
hasInit = true;
|
|
88
|
-
// We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
|
|
89
|
-
(0, apiKey_1.validateAndTrackApiKey)(log, settings.core.authorizationKey);
|
|
90
|
-
readiness.init();
|
|
91
|
-
uniqueKeysTracker.start();
|
|
92
|
-
syncManager && syncManager.start();
|
|
93
|
-
signalListener && signalListener.start();
|
|
94
|
-
initCallbacks.forEach(function (cb) { return cb(); });
|
|
95
|
-
initCallbacks.length = 0;
|
|
59
|
+
Object.keys(clients).map(function (key) { return clients[key].init(); });
|
|
96
60
|
}
|
|
97
61
|
log.info(constants_1.NEW_FACTORY, [settings.version]);
|
|
98
62
|
// @ts-ignore
|
|
@@ -108,7 +72,6 @@ function sdkFactory(params) {
|
|
|
108
72
|
Logger: (0, sdkLogger_1.createLoggerAPI)(log),
|
|
109
73
|
settings: settings,
|
|
110
74
|
destroy: function () {
|
|
111
|
-
hasInit = false;
|
|
112
75
|
return Promise.all(Object.keys(clients).map(function (key) { return clients[key].destroy(); })).then(function () { });
|
|
113
76
|
}
|
|
114
77
|
}, extraProps && extraProps(ctx), lazyInit ? { init: init } : init());
|
package/cjs/sdkManager/index.js
CHANGED
|
@@ -53,18 +53,18 @@ function sdkManagerFactory(settings, splits, _a) {
|
|
|
53
53
|
* Get the feature flag object corresponding to the given feature flag name if valid
|
|
54
54
|
*/
|
|
55
55
|
split: function (featureFlagName) {
|
|
56
|
-
var splitName = (0, inputValidation_1.
|
|
56
|
+
var splitName = (0, inputValidation_1.validateDefinition)(log, featureFlagName, constants_1.SPLIT_FN_LABEL);
|
|
57
57
|
if (!(0, inputValidation_1.validateIfOperational)(log, readinessManager, constants_1.SPLIT_FN_LABEL) || !splitName) {
|
|
58
58
|
return isAsync ? Promise.resolve(null) : null;
|
|
59
59
|
}
|
|
60
|
-
var split = splits.
|
|
60
|
+
var split = splits.get(splitName);
|
|
61
61
|
if ((0, thenable_1.thenable)(split)) {
|
|
62
62
|
return split.catch(function () { return null; }).then(function (result) {
|
|
63
|
-
(0, inputValidation_1.
|
|
63
|
+
(0, inputValidation_1.validateDefinitionExistence)(log, readinessManager, splitName, result, constants_1.SPLIT_FN_LABEL);
|
|
64
64
|
return objectToView(result);
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
|
-
(0, inputValidation_1.
|
|
67
|
+
(0, inputValidation_1.validateDefinitionExistence)(log, readinessManager, splitName, split, constants_1.SPLIT_FN_LABEL);
|
|
68
68
|
return objectToView(split);
|
|
69
69
|
},
|
|
70
70
|
/**
|
|
@@ -86,7 +86,7 @@ function sdkManagerFactory(settings, splits, _a) {
|
|
|
86
86
|
if (!(0, inputValidation_1.validateIfOperational)(log, readinessManager, constants_1.NAMES_FN_LABEL)) {
|
|
87
87
|
return isAsync ? Promise.resolve([]) : [];
|
|
88
88
|
}
|
|
89
|
-
var splitNames = splits.
|
|
89
|
+
var splitNames = splits.getNames();
|
|
90
90
|
return (0, thenable_1.thenable)(splitNames) ?
|
|
91
91
|
splitNames.catch(function () { return []; }) : // handle possible rejections when using pluggable storage
|
|
92
92
|
splitNames;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.authProviderFactory = void 0;
|
|
4
|
+
var AuthClient_1 = require("../sync/streaming/AuthClient");
|
|
5
|
+
var Backoff_1 = require("../utils/Backoff");
|
|
6
|
+
var constants_1 = require("../logger/constants");
|
|
7
|
+
var constants_2 = require("../utils/constants");
|
|
8
|
+
var SKEW_SECONDS = 30;
|
|
9
|
+
function isExpired(credential) {
|
|
10
|
+
return Date.now() / 1000 + SKEW_SECONDS >= credential.decodedToken.exp;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Factory of AuthProvider, which provides JWT credentials for authenticated HTTP requests.
|
|
14
|
+
* Credentials are fetched lazily on demand, cached in memory, and retried with backoff on failure.
|
|
15
|
+
*/
|
|
16
|
+
function authProviderFactory(settings, splitHttpClient, telemetryTracker) {
|
|
17
|
+
var urls = settings.urls, log = settings.log;
|
|
18
|
+
function fetchAuth() {
|
|
19
|
+
var url = "".concat(urls.auth, "/v3/auth?capabilities=config");
|
|
20
|
+
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(constants_2.TOKEN));
|
|
21
|
+
}
|
|
22
|
+
var authenticate = (0, AuthClient_1.authenticateFactory)(fetchAuth);
|
|
23
|
+
var backoff = new Backoff_1.Backoff(fetchCredential);
|
|
24
|
+
var cachedCredential;
|
|
25
|
+
var inFlightPromise;
|
|
26
|
+
var stopped = false;
|
|
27
|
+
function fetchCredential() {
|
|
28
|
+
return authenticate().then(function (credential) {
|
|
29
|
+
log.info(constants_1.LOG_PREFIX_SYNC_AUTH + 'credential fetched successfully');
|
|
30
|
+
cachedCredential = credential;
|
|
31
|
+
inFlightPromise = undefined;
|
|
32
|
+
backoff.reset();
|
|
33
|
+
return credential;
|
|
34
|
+
}).catch(function (error) {
|
|
35
|
+
// Avoid rejected promises and unnecessary retries after stop()
|
|
36
|
+
if (stopped)
|
|
37
|
+
return cachedCredential;
|
|
38
|
+
if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500) {
|
|
39
|
+
log.error(constants_1.LOG_PREFIX_SYNC_AUTH + 'non-retryable error fetching credential (status ' + error.statusCode + '): ' + error.message);
|
|
40
|
+
inFlightPromise = undefined;
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
log.warn(constants_1.LOG_PREFIX_SYNC_AUTH + 'credential fetch failed (attempt ' + (backoff.attempts + 1) + '). Error: ' + error.message);
|
|
44
|
+
return backoff.scheduleCallAsync();
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
credential: function () {
|
|
49
|
+
if (cachedCredential && !isExpired(cachedCredential)) {
|
|
50
|
+
return Promise.resolve(cachedCredential);
|
|
51
|
+
}
|
|
52
|
+
if (cachedCredential)
|
|
53
|
+
log.debug(constants_1.LOG_PREFIX_SYNC_AUTH + 'cached credential expired');
|
|
54
|
+
return inFlightPromise || (inFlightPromise = fetchCredential());
|
|
55
|
+
},
|
|
56
|
+
invalidate: function () {
|
|
57
|
+
cachedCredential = undefined;
|
|
58
|
+
},
|
|
59
|
+
stop: function () {
|
|
60
|
+
stopped = true;
|
|
61
|
+
cachedCredential = undefined;
|
|
62
|
+
inFlightPromise = undefined;
|
|
63
|
+
backoff.reset();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
exports.authProviderFactory = authProviderFactory;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.secureSplitHttpClientFactory = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var splitHttpClient_1 = require("./splitHttpClient");
|
|
6
|
+
var authProvider_1 = require("./authProvider");
|
|
7
|
+
/**
|
|
8
|
+
* Factory of Secure HTTP client, which authenticates requests using a JWT token.
|
|
9
|
+
* On 401 responses, invalidates the cached credential and retries once with a fresh token.
|
|
10
|
+
*
|
|
11
|
+
* @param settings - SDK settings
|
|
12
|
+
* @param platform - object containing environment-specific dependencies
|
|
13
|
+
* @param fetchAuth - function to fetch auth credentials from the /v2/auth endpoint
|
|
14
|
+
*/
|
|
15
|
+
function secureSplitHttpClientFactory(settings, platform, telemetryTracker) {
|
|
16
|
+
var splitHttpClient = (0, splitHttpClient_1.splitHttpClientFactory)(settings, platform);
|
|
17
|
+
var authProvider = (0, authProvider_1.authProviderFactory)(settings, splitHttpClient, telemetryTracker);
|
|
18
|
+
function makeRequest(url, options, latencyTracker, logErrorsAsInfo, token) {
|
|
19
|
+
return splitHttpClient(url, tslib_1.__assign(tslib_1.__assign({}, options), { headers: tslib_1.__assign(tslib_1.__assign({}, options === null || options === void 0 ? void 0 : options.headers), { Authorization: "Bearer ".concat(token) }) }), latencyTracker, logErrorsAsInfo);
|
|
20
|
+
}
|
|
21
|
+
var httpClient = function (url, options, latencyTracker, logErrorsAsInfo) {
|
|
22
|
+
return authProvider.credential().then(function (credential) {
|
|
23
|
+
return makeRequest(url, options, latencyTracker, logErrorsAsInfo, credential.token)
|
|
24
|
+
.catch(function (error) {
|
|
25
|
+
if (error.statusCode === 401) {
|
|
26
|
+
// retry once for 401, in case the token has just expired
|
|
27
|
+
authProvider.invalidate();
|
|
28
|
+
return authProvider.credential().then(function (newCredential) {
|
|
29
|
+
return makeRequest(url, options, latencyTracker, logErrorsAsInfo, newCredential.token);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
throw error;
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
httpClient.stop = function () { return authProvider.stop(); };
|
|
37
|
+
return httpClient;
|
|
38
|
+
}
|
|
39
|
+
exports.secureSplitHttpClientFactory = secureSplitHttpClientFactory;
|
package/cjs/services/splitApi.js
CHANGED
|
@@ -16,23 +16,24 @@ function userKeyToQueryParam(userKey) {
|
|
|
16
16
|
* @param platform - object containing environment-specific dependencies
|
|
17
17
|
* @param telemetryTracker - telemetry tracker
|
|
18
18
|
*/
|
|
19
|
-
function splitApiFactory(settings, platform, telemetryTracker) {
|
|
19
|
+
function splitApiFactory(settings, platform, telemetryTracker, secureSplitHttpClientFactory) {
|
|
20
20
|
var urls = settings.urls;
|
|
21
21
|
var filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
|
|
22
22
|
var SplitSDKImpressionsMode = settings.sync.impressionsMode;
|
|
23
23
|
var splitHttpClient = (0, splitHttpClient_1.splitHttpClientFactory)(settings, platform);
|
|
24
|
+
var secureSplitHttpClient = secureSplitHttpClientFactory ? secureSplitHttpClientFactory(settings, platform, telemetryTracker) : undefined;
|
|
24
25
|
return {
|
|
25
26
|
// @TODO throw errors if health check requests fail, to log them in the Synchronizer
|
|
26
27
|
getSdkAPIHealthCheck: function () {
|
|
27
|
-
var url = urls.sdk
|
|
28
|
+
var url = "".concat(urls.sdk, "/version");
|
|
28
29
|
return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
|
|
29
30
|
},
|
|
30
31
|
getEventsAPIHealthCheck: function () {
|
|
31
|
-
var url = urls.events
|
|
32
|
+
var url = "".concat(urls.events, "/version");
|
|
32
33
|
return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
|
|
33
34
|
},
|
|
34
35
|
fetchAuth: function (userMatchingKeys) {
|
|
35
|
-
var url = urls.auth
|
|
36
|
+
var url = "".concat(urls.auth, "/v2/auth?s=").concat(settings.sync.flagSpecVersion);
|
|
36
37
|
if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
|
|
37
38
|
var queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
|
|
38
39
|
if (queryParams)
|
|
@@ -41,7 +42,7 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
41
42
|
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(constants_1.TOKEN));
|
|
42
43
|
},
|
|
43
44
|
fetchSplitChanges: function (since, noCache, till, rbSince) {
|
|
44
|
-
var url = urls.sdk
|
|
45
|
+
var url = "".concat(urls.sdk, "/splitChanges?s=").concat(settings.sync.flagSpecVersion, "&since=").concat(since).concat(rbSince ? '&rbSince=' + rbSince : '').concat(filterQueryString || '').concat(till ? '&till=' + till : '');
|
|
45
46
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(constants_1.SPLITS))
|
|
46
47
|
.catch(function (err) {
|
|
47
48
|
if (err.statusCode === 414)
|
|
@@ -49,8 +50,13 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
49
50
|
throw err;
|
|
50
51
|
});
|
|
51
52
|
},
|
|
53
|
+
// @TODO support filterQueryString and handle ERROR_TOO_MANY_SETS error
|
|
54
|
+
fetchConfigs: function (since, noCache, till) {
|
|
55
|
+
var url = "".concat(urls.sdk, "/v1/configs?since=").concat(since).concat(filterQueryString || '').concat(till ? '&till=' + till : '');
|
|
56
|
+
return (secureSplitHttpClient || splitHttpClient)(url, noCache ? noCacheHeaderOptions : undefined);
|
|
57
|
+
},
|
|
52
58
|
fetchSegmentChanges: function (since, segmentName, noCache, till) {
|
|
53
|
-
var url = urls.sdk
|
|
59
|
+
var url = "".concat(urls.sdk, "/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
|
|
54
60
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(constants_1.SEGMENT));
|
|
55
61
|
},
|
|
56
62
|
fetchMemberships: function (userMatchingKey, noCache, till) {
|
|
@@ -60,7 +66,7 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
60
66
|
* - avoid 404 responses. E.g.: '/api/memberships/foo/bar'
|
|
61
67
|
* - match user keys with special characters. E.g.: 'foo%bar', 'foo/bar'
|
|
62
68
|
*/
|
|
63
|
-
var url = urls.sdk
|
|
69
|
+
var url = "".concat(urls.sdk, "/memberships/").concat(encodeURIComponent(userMatchingKey)).concat(till ? '?till=' + till : '');
|
|
64
70
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(constants_1.MEMBERSHIPS));
|
|
65
71
|
},
|
|
66
72
|
/**
|
|
@@ -70,7 +76,7 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
70
76
|
* @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
71
77
|
*/
|
|
72
78
|
postEventsBulk: function (body, headers) {
|
|
73
|
-
var url = urls.events
|
|
79
|
+
var url = "".concat(urls.events, "/events/bulk");
|
|
74
80
|
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.EVENTS));
|
|
75
81
|
},
|
|
76
82
|
/**
|
|
@@ -80,7 +86,7 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
80
86
|
* @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
81
87
|
*/
|
|
82
88
|
postTestImpressionsBulk: function (body, headers) {
|
|
83
|
-
var url = urls.events
|
|
89
|
+
var url = "".concat(urls.events, "/testImpressions/bulk");
|
|
84
90
|
return splitHttpClient(url, {
|
|
85
91
|
// Adding extra headers to send impressions in OPTIMIZED or DEBUG modes.
|
|
86
92
|
method: 'POST',
|
|
@@ -95,7 +101,7 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
95
101
|
* @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
96
102
|
*/
|
|
97
103
|
postTestImpressionsCount: function (body, headers) {
|
|
98
|
-
var url = urls.events
|
|
104
|
+
var url = "".concat(urls.events, "/testImpressions/count");
|
|
99
105
|
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.IMPRESSIONS_COUNT));
|
|
100
106
|
},
|
|
101
107
|
/**
|
|
@@ -105,7 +111,7 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
105
111
|
* @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
106
112
|
*/
|
|
107
113
|
postUniqueKeysBulkCs: function (body, headers) {
|
|
108
|
-
var url = urls.telemetry
|
|
114
|
+
var url = "".concat(urls.telemetry, "/v1/keys/cs");
|
|
109
115
|
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.TELEMETRY));
|
|
110
116
|
},
|
|
111
117
|
/**
|
|
@@ -115,16 +121,20 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
115
121
|
* @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
116
122
|
*/
|
|
117
123
|
postUniqueKeysBulkSs: function (body, headers) {
|
|
118
|
-
var url = urls.telemetry
|
|
124
|
+
var url = "".concat(urls.telemetry, "/v1/keys/ss");
|
|
119
125
|
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.TELEMETRY));
|
|
120
126
|
},
|
|
121
127
|
postMetricsConfig: function (body, headers) {
|
|
122
|
-
var url = urls.telemetry
|
|
128
|
+
var url = "".concat(urls.telemetry, "/v1/metrics/config");
|
|
123
129
|
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.TELEMETRY), true);
|
|
124
130
|
},
|
|
125
131
|
postMetricsUsage: function (body, headers) {
|
|
126
|
-
var url = urls.telemetry
|
|
132
|
+
var url = "".concat(urls.telemetry, "/v1/metrics/usage");
|
|
127
133
|
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.TELEMETRY), true);
|
|
134
|
+
},
|
|
135
|
+
stop: function () {
|
|
136
|
+
if (secureSplitHttpClient)
|
|
137
|
+
secureSplitHttpClient.stop();
|
|
128
138
|
}
|
|
129
139
|
};
|
|
130
140
|
}
|
|
@@ -24,7 +24,7 @@ function splitHttpClientFactory(settings, _a) {
|
|
|
24
24
|
var commonHeaders = {
|
|
25
25
|
'Accept': 'application/json',
|
|
26
26
|
'Content-Type': 'application/json',
|
|
27
|
-
'Authorization': "Bearer "
|
|
27
|
+
'Authorization': "Bearer ".concat(authorizationKey),
|
|
28
28
|
'SplitSDKVersion': version
|
|
29
29
|
};
|
|
30
30
|
if (ip)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AbstractDefinitionsCacheAsync = void 0;
|
|
4
|
+
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
5
|
+
/**
|
|
6
|
+
* This class provides a skeletal implementation of the IDefinitionsCacheAsync interface
|
|
7
|
+
* to minimize the effort required to implement this interface.
|
|
8
|
+
*/
|
|
9
|
+
var AbstractDefinitionsCacheAsync = /** @class */ (function () {
|
|
10
|
+
function AbstractDefinitionsCacheAsync() {
|
|
11
|
+
}
|
|
12
|
+
AbstractDefinitionsCacheAsync.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
13
|
+
var _this = this;
|
|
14
|
+
return Promise.all([
|
|
15
|
+
this.setChangeNumber(changeNumber),
|
|
16
|
+
Promise.all(toAdd.map(function (addedFF) { return _this.add(addedFF); })),
|
|
17
|
+
Promise.all(toRemove.map(function (removedFF) { return _this.remove(removedFF); }))
|
|
18
|
+
]).then(function (_a) {
|
|
19
|
+
var added = _a[1], removed = _a[2];
|
|
20
|
+
return added.some(function (result) { return result; }) || removed.some(function (result) { return result; });
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
// @TODO revisit segment-related methods ('usesSegments', 'getRegisteredSegments', 'registerSegments')
|
|
24
|
+
// noop, just keeping the interface. This is used by standalone client-side API only, and so only implemented by InMemory and InLocalStorage.
|
|
25
|
+
AbstractDefinitionsCacheAsync.prototype.usesSegments = function () {
|
|
26
|
+
return Promise.resolve(true);
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Kill `name` definition and set `defaultTreatment` and `changeNumber`.
|
|
30
|
+
* Used for SPLIT_KILL push notifications.
|
|
31
|
+
*
|
|
32
|
+
* @returns a promise that is resolved once the definition kill operation is performed. The fulfillment value is a boolean: `true` if the operation succeeded updating the definition or `false` if no definition is updated,
|
|
33
|
+
* for instance, if the `changeNumber` is old, or if the definition is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
|
|
34
|
+
* The promise will never be rejected.
|
|
35
|
+
*/
|
|
36
|
+
AbstractDefinitionsCacheAsync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
|
|
37
|
+
var _this = this;
|
|
38
|
+
return this.get(name).then(function (definition) {
|
|
39
|
+
if (definition && (!definition.changeNumber || definition.changeNumber < changeNumber)) {
|
|
40
|
+
var newDefinition = (0, objectAssign_1.objectAssign)({}, definition);
|
|
41
|
+
newDefinition.killed = true;
|
|
42
|
+
newDefinition.defaultTreatment = defaultTreatment;
|
|
43
|
+
newDefinition.changeNumber = changeNumber;
|
|
44
|
+
return _this.add(newDefinition);
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}).catch(function () { return false; });
|
|
48
|
+
};
|
|
49
|
+
return AbstractDefinitionsCacheAsync;
|
|
50
|
+
}());
|
|
51
|
+
exports.AbstractDefinitionsCacheAsync = AbstractDefinitionsCacheAsync;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usesSegmentsSync = exports.usesSegments = exports.AbstractDefinitionsCacheSync = void 0;
|
|
4
|
+
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
5
|
+
var constants_1 = require("../utils/constants");
|
|
6
|
+
/**
|
|
7
|
+
* This class provides a skeletal implementation of the IDefinitionsCacheSync interface
|
|
8
|
+
* to minimize the effort required to implement this interface.
|
|
9
|
+
*/
|
|
10
|
+
var AbstractDefinitionsCacheSync = /** @class */ (function () {
|
|
11
|
+
function AbstractDefinitionsCacheSync() {
|
|
12
|
+
}
|
|
13
|
+
AbstractDefinitionsCacheSync.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
14
|
+
var _this = this;
|
|
15
|
+
var updated = toAdd.map(function (addedFF) { return _this.add(addedFF); }).some(function (result) { return result; });
|
|
16
|
+
updated = toRemove.map(function (removedFF) { return _this.remove(removedFF); }).some(function (result) { return result; }) || updated;
|
|
17
|
+
this.setChangeNumber(changeNumber);
|
|
18
|
+
return updated;
|
|
19
|
+
};
|
|
20
|
+
AbstractDefinitionsCacheSync.prototype.getMany = function (names) {
|
|
21
|
+
var _this = this;
|
|
22
|
+
var definitions = {};
|
|
23
|
+
names.forEach(function (name) {
|
|
24
|
+
definitions[name] = _this.get(name);
|
|
25
|
+
});
|
|
26
|
+
return definitions;
|
|
27
|
+
};
|
|
28
|
+
AbstractDefinitionsCacheSync.prototype.getAll = function () {
|
|
29
|
+
var _this = this;
|
|
30
|
+
return this.getNames().map(function (key) { return _this.get(key); });
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Kill `name` definition and set `defaultTreatment` and `changeNumber`.
|
|
34
|
+
* Used for SPLIT_KILL push notifications.
|
|
35
|
+
*
|
|
36
|
+
* @returns `true` if the operation successed updating the definition, or `false` if no definition is updated,
|
|
37
|
+
* for instance, if the `changeNumber` is old, or if the definition is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
|
|
38
|
+
*/
|
|
39
|
+
AbstractDefinitionsCacheSync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
|
|
40
|
+
var definition = this.get(name);
|
|
41
|
+
if (definition && (!definition.changeNumber || definition.changeNumber < changeNumber)) {
|
|
42
|
+
var newDefinition = (0, objectAssign_1.objectAssign)({}, definition);
|
|
43
|
+
newDefinition.killed = true;
|
|
44
|
+
newDefinition.defaultTreatment = defaultTreatment;
|
|
45
|
+
newDefinition.changeNumber = changeNumber;
|
|
46
|
+
return this.add(newDefinition);
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
};
|
|
50
|
+
return AbstractDefinitionsCacheSync;
|
|
51
|
+
}());
|
|
52
|
+
exports.AbstractDefinitionsCacheSync = AbstractDefinitionsCacheSync;
|
|
53
|
+
/**
|
|
54
|
+
* Given a parsed definition, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
|
|
55
|
+
* This util is intended to simplify the implementation of `definitionsCache::usesSegments` method
|
|
56
|
+
*/
|
|
57
|
+
function usesSegments(ruleEntity) {
|
|
58
|
+
var conditions = ruleEntity.conditions || [];
|
|
59
|
+
for (var i = 0; i < conditions.length; i++) {
|
|
60
|
+
var matchers = conditions[i].matcherGroup.matchers;
|
|
61
|
+
for (var j = 0; j < matchers.length; j++) {
|
|
62
|
+
var matcher = matchers[j].matcherType;
|
|
63
|
+
if (matcher === constants_1.IN_SEGMENT || matcher === constants_1.IN_LARGE_SEGMENT)
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
var excluded = ruleEntity.excluded;
|
|
68
|
+
if (excluded && excluded.segments && excluded.segments.length > 0)
|
|
69
|
+
return true;
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
exports.usesSegments = usesSegments;
|
|
73
|
+
function usesSegmentsSync(storage) {
|
|
74
|
+
return storage.definitions.usesSegments() || storage.rbSegments.usesSegments();
|
|
75
|
+
}
|
|
76
|
+
exports.usesSegmentsSync = usesSegmentsSync;
|