react-native-nitro-amplitude 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.watchmanconfig +6 -0
- package/LICENSE +21 -0
- package/README.md +139 -0
- package/android/CMakeLists.txt +34 -0
- package/android/build.gradle +85 -0
- package/android/consumer-rules.pro +35 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/cpp/AndroidAmplitudeAdapterCpp.cpp +126 -0
- package/android/src/main/cpp/AndroidAmplitudeAdapterCpp.hpp +48 -0
- package/android/src/main/cpp/cpp-adapter.cpp +9 -0
- package/android/src/main/java/com/nitroamplitude/AndroidAmplitudeAdapter.kt +147 -0
- package/android/src/main/java/com/nitroamplitude/NitroAmplitudePackage.kt +24 -0
- package/app.plugin.js +36 -0
- package/cpp/bindings/HybridAmplitudeContext.cpp +83 -0
- package/cpp/bindings/HybridAmplitudeContext.hpp +29 -0
- package/cpp/bindings/HybridAmplitudeStorage.cpp +163 -0
- package/cpp/bindings/HybridAmplitudeStorage.hpp +38 -0
- package/cpp/bindings/HybridAmplitudeWorker.cpp +162 -0
- package/cpp/bindings/HybridAmplitudeWorker.hpp +74 -0
- package/cpp/core/NativeAmplitudeAdapter.hpp +44 -0
- package/ios/IOSAmplitudeAdapterCpp.hpp +37 -0
- package/ios/IOSAmplitudeAdapterCpp.mm +155 -0
- package/lib/commonjs/AmplitudeContext.nitro.js +6 -0
- package/lib/commonjs/AmplitudeContext.nitro.js.map +1 -0
- package/lib/commonjs/AmplitudeStorage.nitro.js +6 -0
- package/lib/commonjs/AmplitudeStorage.nitro.js.map +1 -0
- package/lib/commonjs/AmplitudeWorker.nitro.js +6 -0
- package/lib/commonjs/AmplitudeWorker.nitro.js.map +1 -0
- package/lib/commonjs/analytics/campaign/campaign-tracker.js +105 -0
- package/lib/commonjs/analytics/campaign/campaign-tracker.js.map +1 -0
- package/lib/commonjs/analytics/campaign/types.js +6 -0
- package/lib/commonjs/analytics/campaign/types.js.map +1 -0
- package/lib/commonjs/analytics/config.js +283 -0
- package/lib/commonjs/analytics/config.js.map +1 -0
- package/lib/commonjs/analytics/cookie-migration/index.js +59 -0
- package/lib/commonjs/analytics/cookie-migration/index.js.map +1 -0
- package/lib/commonjs/analytics/index.js +95 -0
- package/lib/commonjs/analytics/index.js.map +1 -0
- package/lib/commonjs/analytics/migration/remnant-data-migration.js +177 -0
- package/lib/commonjs/analytics/migration/remnant-data-migration.js.map +1 -0
- package/lib/commonjs/analytics/nitro-transport.js +31 -0
- package/lib/commonjs/analytics/nitro-transport.js.map +1 -0
- package/lib/commonjs/analytics/plugins/context.js +140 -0
- package/lib/commonjs/analytics/plugins/context.js.map +1 -0
- package/lib/commonjs/analytics/react-native-client.js +352 -0
- package/lib/commonjs/analytics/react-native-client.js.map +1 -0
- package/lib/commonjs/analytics/storage/local-storage.js +73 -0
- package/lib/commonjs/analytics/storage/local-storage.js.map +1 -0
- package/lib/commonjs/analytics/types.js +175 -0
- package/lib/commonjs/analytics/types.js.map +1 -0
- package/lib/commonjs/analytics/typings/browser-snippet.d.js +6 -0
- package/lib/commonjs/analytics/typings/browser-snippet.d.js.map +1 -0
- package/lib/commonjs/analytics/typings/ua-parser.d.js +2 -0
- package/lib/commonjs/analytics/typings/ua-parser.d.js.map +1 -0
- package/lib/commonjs/analytics/utils/platform.js +16 -0
- package/lib/commonjs/analytics/utils/platform.js.map +1 -0
- package/lib/commonjs/analytics/version.js +8 -0
- package/lib/commonjs/analytics/version.js.map +1 -0
- package/lib/commonjs/experiment/experimentClient.js +792 -0
- package/lib/commonjs/experiment/experimentClient.js.map +1 -0
- package/lib/commonjs/experiment/factory.js +77 -0
- package/lib/commonjs/experiment/factory.js.map +1 -0
- package/lib/commonjs/experiment/gen/version.js +9 -0
- package/lib/commonjs/experiment/gen/version.js.map +1 -0
- package/lib/commonjs/experiment/index.js +143 -0
- package/lib/commonjs/experiment/index.js.map +1 -0
- package/lib/commonjs/experiment/integration/NativeExperimentReactNativeClient.js +11 -0
- package/lib/commonjs/experiment/integration/NativeExperimentReactNativeClient.js.map +1 -0
- package/lib/commonjs/experiment/integration/connector.js +67 -0
- package/lib/commonjs/experiment/integration/connector.js.map +1 -0
- package/lib/commonjs/experiment/integration/default.js +92 -0
- package/lib/commonjs/experiment/integration/default.js.map +1 -0
- package/lib/commonjs/experiment/logger/ampLogger.js +80 -0
- package/lib/commonjs/experiment/logger/ampLogger.js.map +1 -0
- package/lib/commonjs/experiment/logger/consoleLogger.js +60 -0
- package/lib/commonjs/experiment/logger/consoleLogger.js.map +1 -0
- package/lib/commonjs/experiment/storage/cache.js +197 -0
- package/lib/commonjs/experiment/storage/cache.js.map +1 -0
- package/lib/commonjs/experiment/storage/local-storage.js +25 -0
- package/lib/commonjs/experiment/storage/local-storage.js.map +1 -0
- package/lib/commonjs/experiment/stubClient.js +46 -0
- package/lib/commonjs/experiment/stubClient.js.map +1 -0
- package/lib/commonjs/experiment/transport/http.js +72 -0
- package/lib/commonjs/experiment/transport/http.js.map +1 -0
- package/lib/commonjs/experiment/types/client.js +6 -0
- package/lib/commonjs/experiment/types/client.js.map +1 -0
- package/lib/commonjs/experiment/types/config.js +67 -0
- package/lib/commonjs/experiment/types/config.js.map +1 -0
- package/lib/commonjs/experiment/types/exposure.js +2 -0
- package/lib/commonjs/experiment/types/exposure.js.map +1 -0
- package/lib/commonjs/experiment/types/logger.js +42 -0
- package/lib/commonjs/experiment/types/logger.js.map +1 -0
- package/lib/commonjs/experiment/types/source.js +54 -0
- package/lib/commonjs/experiment/types/source.js.map +1 -0
- package/lib/commonjs/experiment/types/storage.js +2 -0
- package/lib/commonjs/experiment/types/storage.js.map +1 -0
- package/lib/commonjs/experiment/types/transport.js +2 -0
- package/lib/commonjs/experiment/types/transport.js.map +1 -0
- package/lib/commonjs/experiment/types/user.js +2 -0
- package/lib/commonjs/experiment/types/user.js.map +1 -0
- package/lib/commonjs/experiment/types/variant.js +2 -0
- package/lib/commonjs/experiment/types/variant.js.map +1 -0
- package/lib/commonjs/experiment/util/backoff.js +54 -0
- package/lib/commonjs/experiment/util/backoff.js.map +1 -0
- package/lib/commonjs/experiment/util/base64.js +23 -0
- package/lib/commonjs/experiment/util/base64.js.map +1 -0
- package/lib/commonjs/experiment/util/convert.js +78 -0
- package/lib/commonjs/experiment/util/convert.js.map +1 -0
- package/lib/commonjs/experiment/util/index.js +25 -0
- package/lib/commonjs/experiment/util/index.js.map +1 -0
- package/lib/commonjs/experiment/util/platform.js +16 -0
- package/lib/commonjs/experiment/util/platform.js.map +1 -0
- package/lib/commonjs/experiment/util/randomstring.js +16 -0
- package/lib/commonjs/experiment/util/randomstring.js.map +1 -0
- package/lib/commonjs/experiment/util/userSessionExposureTracker.js +40 -0
- package/lib/commonjs/experiment/util/userSessionExposureTracker.js.map +1 -0
- package/lib/commonjs/index.js +298 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/index.web.js +22 -0
- package/lib/commonjs/index.web.js.map +1 -0
- package/lib/commonjs/native/context.js +43 -0
- package/lib/commonjs/native/context.js.map +1 -0
- package/lib/commonjs/native/http.js +62 -0
- package/lib/commonjs/native/http.js.map +1 -0
- package/lib/commonjs/native/hybrid.js +31 -0
- package/lib/commonjs/native/hybrid.js.map +1 -0
- package/lib/commonjs/native/storage.js +93 -0
- package/lib/commonjs/native/storage.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/module/AmplitudeContext.nitro.js +4 -0
- package/lib/module/AmplitudeContext.nitro.js.map +1 -0
- package/lib/module/AmplitudeStorage.nitro.js +4 -0
- package/lib/module/AmplitudeStorage.nitro.js.map +1 -0
- package/lib/module/AmplitudeWorker.nitro.js +4 -0
- package/lib/module/AmplitudeWorker.nitro.js.map +1 -0
- package/lib/module/analytics/campaign/campaign-tracker.js +100 -0
- package/lib/module/analytics/campaign/campaign-tracker.js.map +1 -0
- package/lib/module/analytics/campaign/types.js +4 -0
- package/lib/module/analytics/campaign/types.js.map +1 -0
- package/lib/module/analytics/config.js +272 -0
- package/lib/module/analytics/config.js.map +1 -0
- package/lib/module/analytics/cookie-migration/index.js +51 -0
- package/lib/module/analytics/cookie-migration/index.js.map +1 -0
- package/lib/module/analytics/index.js +34 -0
- package/lib/module/analytics/index.js.map +1 -0
- package/lib/module/analytics/migration/remnant-data-migration.js +172 -0
- package/lib/module/analytics/migration/remnant-data-migration.js.map +1 -0
- package/lib/module/analytics/nitro-transport.js +26 -0
- package/lib/module/analytics/nitro-transport.js.map +1 -0
- package/lib/module/analytics/plugins/context.js +134 -0
- package/lib/module/analytics/plugins/context.js.map +1 -0
- package/lib/module/analytics/react-native-client.js +346 -0
- package/lib/module/analytics/react-native-client.js.map +1 -0
- package/lib/module/analytics/storage/local-storage.js +68 -0
- package/lib/module/analytics/storage/local-storage.js.map +1 -0
- package/lib/module/analytics/types.js +4 -0
- package/lib/module/analytics/types.js.map +1 -0
- package/lib/module/analytics/typings/browser-snippet.d.js +4 -0
- package/lib/module/analytics/typings/browser-snippet.d.js.map +1 -0
- package/lib/module/analytics/typings/ua-parser.d.js +2 -0
- package/lib/module/analytics/typings/ua-parser.d.js.map +1 -0
- package/lib/module/analytics/utils/platform.js +10 -0
- package/lib/module/analytics/utils/platform.js.map +1 -0
- package/lib/module/analytics/version.js +4 -0
- package/lib/module/analytics/version.js.map +1 -0
- package/lib/module/experiment/experimentClient.js +788 -0
- package/lib/module/experiment/experimentClient.js.map +1 -0
- package/lib/module/experiment/factory.js +73 -0
- package/lib/module/experiment/factory.js.map +1 -0
- package/lib/module/experiment/gen/version.js +5 -0
- package/lib/module/experiment/gen/version.js.map +1 -0
- package/lib/module/experiment/index.js +16 -0
- package/lib/module/experiment/index.js.map +1 -0
- package/lib/module/experiment/integration/NativeExperimentReactNativeClient.js +7 -0
- package/lib/module/experiment/integration/NativeExperimentReactNativeClient.js.map +1 -0
- package/lib/module/experiment/integration/connector.js +61 -0
- package/lib/module/experiment/integration/connector.js.map +1 -0
- package/lib/module/experiment/integration/default.js +87 -0
- package/lib/module/experiment/integration/default.js.map +1 -0
- package/lib/module/experiment/logger/ampLogger.js +76 -0
- package/lib/module/experiment/logger/ampLogger.js.map +1 -0
- package/lib/module/experiment/logger/consoleLogger.js +55 -0
- package/lib/module/experiment/logger/consoleLogger.js.map +1 -0
- package/lib/module/experiment/storage/cache.js +187 -0
- package/lib/module/experiment/storage/cache.js.map +1 -0
- package/lib/module/experiment/storage/local-storage.js +19 -0
- package/lib/module/experiment/storage/local-storage.js.map +1 -0
- package/lib/module/experiment/stubClient.js +41 -0
- package/lib/module/experiment/stubClient.js.map +1 -0
- package/lib/module/experiment/transport/http.js +66 -0
- package/lib/module/experiment/transport/http.js.map +1 -0
- package/lib/module/experiment/types/client.js +4 -0
- package/lib/module/experiment/types/client.js.map +1 -0
- package/lib/module/experiment/types/config.js +64 -0
- package/lib/module/experiment/types/config.js.map +1 -0
- package/lib/module/experiment/types/exposure.js +2 -0
- package/lib/module/experiment/types/exposure.js.map +1 -0
- package/lib/module/experiment/types/logger.js +39 -0
- package/lib/module/experiment/types/logger.js.map +1 -0
- package/lib/module/experiment/types/source.js +51 -0
- package/lib/module/experiment/types/source.js.map +1 -0
- package/lib/module/experiment/types/storage.js +2 -0
- package/lib/module/experiment/types/storage.js.map +1 -0
- package/lib/module/experiment/types/transport.js +2 -0
- package/lib/module/experiment/types/transport.js.map +1 -0
- package/lib/module/experiment/types/user.js +2 -0
- package/lib/module/experiment/types/user.js.map +1 -0
- package/lib/module/experiment/types/variant.js +2 -0
- package/lib/module/experiment/types/variant.js.map +1 -0
- package/lib/module/experiment/util/backoff.js +49 -0
- package/lib/module/experiment/util/backoff.js.map +1 -0
- package/lib/module/experiment/util/base64.js +16 -0
- package/lib/module/experiment/util/base64.js.map +1 -0
- package/lib/module/experiment/util/convert.js +71 -0
- package/lib/module/experiment/util/convert.js.map +1 -0
- package/lib/module/experiment/util/index.js +17 -0
- package/lib/module/experiment/util/index.js.map +1 -0
- package/lib/module/experiment/util/platform.js +10 -0
- package/lib/module/experiment/util/platform.js.map +1 -0
- package/lib/module/experiment/util/randomstring.js +11 -0
- package/lib/module/experiment/util/randomstring.js.map +1 -0
- package/lib/module/experiment/util/userSessionExposureTracker.js +35 -0
- package/lib/module/experiment/util/userSessionExposureTracker.js.map +1 -0
- package/lib/module/index.js +50 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/index.web.js +14 -0
- package/lib/module/index.web.js.map +1 -0
- package/lib/module/native/context.js +35 -0
- package/lib/module/native/context.js.map +1 -0
- package/lib/module/native/http.js +57 -0
- package/lib/module/native/http.js.map +1 -0
- package/lib/module/native/hybrid.js +24 -0
- package/lib/module/native/hybrid.js.map +1 -0
- package/lib/module/native/storage.js +86 -0
- package/lib/module/native/storage.js.map +1 -0
- package/lib/typescript/AmplitudeContext.nitro.d.ts +17 -0
- package/lib/typescript/AmplitudeContext.nitro.d.ts.map +1 -0
- package/lib/typescript/AmplitudeStorage.nitro.d.ts +17 -0
- package/lib/typescript/AmplitudeStorage.nitro.d.ts.map +1 -0
- package/lib/typescript/AmplitudeWorker.nitro.d.ts +11 -0
- package/lib/typescript/AmplitudeWorker.nitro.d.ts.map +1 -0
- package/lib/typescript/analytics/campaign/campaign-tracker.d.ts +85 -0
- package/lib/typescript/analytics/campaign/campaign-tracker.d.ts.map +1 -0
- package/lib/typescript/analytics/campaign/types.d.ts +11 -0
- package/lib/typescript/analytics/campaign/types.d.ts.map +1 -0
- package/lib/typescript/analytics/config.d.ts +68 -0
- package/lib/typescript/analytics/config.d.ts.map +1 -0
- package/lib/typescript/analytics/cookie-migration/index.d.ts +6 -0
- package/lib/typescript/analytics/cookie-migration/index.d.ts.map +1 -0
- package/lib/typescript/analytics/index.d.ts +7 -0
- package/lib/typescript/analytics/index.d.ts.map +1 -0
- package/lib/typescript/analytics/migration/remnant-data-migration.d.ts +20 -0
- package/lib/typescript/analytics/migration/remnant-data-migration.d.ts.map +1 -0
- package/lib/typescript/analytics/nitro-transport.d.ts +9 -0
- package/lib/typescript/analytics/nitro-transport.d.ts.map +1 -0
- package/lib/typescript/analytics/plugins/context.d.ts +14 -0
- package/lib/typescript/analytics/plugins/context.d.ts.map +1 -0
- package/lib/typescript/analytics/react-native-client.d.ts +55 -0
- package/lib/typescript/analytics/react-native-client.d.ts.map +1 -0
- package/lib/typescript/analytics/storage/local-storage.d.ts +14 -0
- package/lib/typescript/analytics/storage/local-storage.d.ts.map +1 -0
- package/lib/typescript/analytics/types.d.ts +2 -0
- package/lib/typescript/analytics/types.d.ts.map +1 -0
- package/lib/typescript/analytics/utils/platform.d.ts +3 -0
- package/lib/typescript/analytics/utils/platform.d.ts.map +1 -0
- package/lib/typescript/analytics/version.d.ts +2 -0
- package/lib/typescript/analytics/version.d.ts.map +1 -0
- package/lib/typescript/experiment/experimentClient.d.ts +234 -0
- package/lib/typescript/experiment/experimentClient.d.ts.map +1 -0
- package/lib/typescript/experiment/factory.d.ts +11 -0
- package/lib/typescript/experiment/factory.d.ts.map +1 -0
- package/lib/typescript/experiment/gen/version.d.ts +2 -0
- package/lib/typescript/experiment/gen/version.d.ts.map +1 -0
- package/lib/typescript/experiment/index.d.ts +15 -0
- package/lib/typescript/experiment/index.d.ts.map +1 -0
- package/lib/typescript/experiment/integration/NativeExperimentReactNativeClient.d.ts +16 -0
- package/lib/typescript/experiment/integration/NativeExperimentReactNativeClient.d.ts.map +1 -0
- package/lib/typescript/experiment/integration/connector.d.ts +16 -0
- package/lib/typescript/experiment/integration/connector.d.ts.map +1 -0
- package/lib/typescript/experiment/integration/default.d.ts +20 -0
- package/lib/typescript/experiment/integration/default.d.ts.map +1 -0
- package/lib/typescript/experiment/logger/ampLogger.d.ts +47 -0
- package/lib/typescript/experiment/logger/ampLogger.d.ts.map +1 -0
- package/lib/typescript/experiment/logger/consoleLogger.d.ts +40 -0
- package/lib/typescript/experiment/logger/consoleLogger.d.ts.map +1 -0
- package/lib/typescript/experiment/storage/cache.d.ts +35 -0
- package/lib/typescript/experiment/storage/cache.d.ts.map +1 -0
- package/lib/typescript/experiment/storage/local-storage.d.ts +11 -0
- package/lib/typescript/experiment/storage/local-storage.d.ts.map +1 -0
- package/lib/typescript/experiment/stubClient.d.ts +21 -0
- package/lib/typescript/experiment/stubClient.d.ts.map +1 -0
- package/lib/typescript/experiment/transport/http.d.ts +17 -0
- package/lib/typescript/experiment/transport/http.d.ts.map +1 -0
- package/lib/typescript/experiment/types/client.d.ts +36 -0
- package/lib/typescript/experiment/types/client.d.ts.map +1 -0
- package/lib/typescript/experiment/types/config.d.ts +164 -0
- package/lib/typescript/experiment/types/config.d.ts.map +1 -0
- package/lib/typescript/experiment/types/exposure.d.ts +107 -0
- package/lib/typescript/experiment/types/exposure.d.ts.map +1 -0
- package/lib/typescript/experiment/types/logger.d.ts +67 -0
- package/lib/typescript/experiment/types/logger.d.ts.map +1 -0
- package/lib/typescript/experiment/types/source.d.ts +43 -0
- package/lib/typescript/experiment/types/source.d.ts.map +1 -0
- package/lib/typescript/experiment/types/storage.d.ts +7 -0
- package/lib/typescript/experiment/types/storage.d.ts.map +1 -0
- package/lib/typescript/experiment/types/transport.d.ts +8 -0
- package/lib/typescript/experiment/types/transport.d.ts.map +1 -0
- package/lib/typescript/experiment/types/user.d.ts +106 -0
- package/lib/typescript/experiment/types/user.d.ts.map +1 -0
- package/lib/typescript/experiment/types/variant.d.ts +33 -0
- package/lib/typescript/experiment/types/variant.d.ts.map +1 -0
- package/lib/typescript/experiment/util/backoff.d.ts +14 -0
- package/lib/typescript/experiment/util/backoff.d.ts.map +1 -0
- package/lib/typescript/experiment/util/base64.d.ts +3 -0
- package/lib/typescript/experiment/util/base64.d.ts.map +1 -0
- package/lib/typescript/experiment/util/convert.d.ts +7 -0
- package/lib/typescript/experiment/util/convert.d.ts.map +1 -0
- package/lib/typescript/experiment/util/index.d.ts +6 -0
- package/lib/typescript/experiment/util/index.d.ts.map +1 -0
- package/lib/typescript/experiment/util/platform.d.ts +3 -0
- package/lib/typescript/experiment/util/platform.d.ts.map +1 -0
- package/lib/typescript/experiment/util/randomstring.d.ts +2 -0
- package/lib/typescript/experiment/util/randomstring.d.ts.map +1 -0
- package/lib/typescript/experiment/util/userSessionExposureTracker.d.ts +16 -0
- package/lib/typescript/experiment/util/userSessionExposureTracker.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +31 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/index.web.d.ts +12 -0
- package/lib/typescript/index.web.d.ts.map +1 -0
- package/lib/typescript/native/context.d.ts +29 -0
- package/lib/typescript/native/context.d.ts.map +1 -0
- package/lib/typescript/native/http.d.ts +6 -0
- package/lib/typescript/native/http.d.ts.map +1 -0
- package/lib/typescript/native/hybrid.d.ts +8 -0
- package/lib/typescript/native/hybrid.d.ts.map +1 -0
- package/lib/typescript/native/storage.d.ts +29 -0
- package/lib/typescript/native/storage.d.ts.map +1 -0
- package/nitro.json +33 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/NitroAmplitude+autolinking.cmake +83 -0
- package/nitrogen/generated/android/NitroAmplitude+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NitroAmplitudeOnLoad.cpp +69 -0
- package/nitrogen/generated/android/NitroAmplitudeOnLoad.hpp +34 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitroamplitude/NitroAmplitudeOnLoad.kt +35 -0
- package/nitrogen/generated/ios/NitroAmplitude+autolinking.rb +62 -0
- package/nitrogen/generated/ios/NitroAmplitude-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/NitroAmplitude-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/NitroAmplitude-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/ios/NitroAmplitudeAutolinking.mm +55 -0
- package/nitrogen/generated/ios/NitroAmplitudeAutolinking.swift +16 -0
- package/nitrogen/generated/shared/c++/HybridAmplitudeContextSpec.cpp +25 -0
- package/nitrogen/generated/shared/c++/HybridAmplitudeContextSpec.hpp +67 -0
- package/nitrogen/generated/shared/c++/HybridAmplitudeStorageSpec.cpp +30 -0
- package/nitrogen/generated/shared/c++/HybridAmplitudeStorageSpec.hpp +73 -0
- package/nitrogen/generated/shared/c++/HybridAmplitudeWorkerSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/HybridAmplitudeWorkerSpec.hpp +66 -0
- package/package.json +130 -0
- package/react-native-nitro-amplitude.podspec +36 -0
- package/src/AmplitudeContext.nitro.ts +21 -0
- package/src/AmplitudeStorage.nitro.ts +17 -0
- package/src/AmplitudeWorker.nitro.ts +25 -0
- package/src/analytics/campaign/campaign-tracker.ts +162 -0
- package/src/analytics/campaign/types.ts +18 -0
- package/src/analytics/config.ts +373 -0
- package/src/analytics/cookie-migration/index.ts +69 -0
- package/src/analytics/index.ts +36 -0
- package/src/analytics/migration/remnant-data-migration.ts +206 -0
- package/src/analytics/nitro-transport.ts +35 -0
- package/src/analytics/plugins/context.ts +166 -0
- package/src/analytics/react-native-client.ts +573 -0
- package/src/analytics/storage/local-storage.ts +76 -0
- package/src/analytics/types.ts +30 -0
- package/src/analytics/typings/browser-snippet.d.ts +7 -0
- package/src/analytics/typings/ua-parser.d.ts +4 -0
- package/src/analytics/utils/platform.ts +9 -0
- package/src/analytics/version.ts +1 -0
- package/src/experiment/experimentClient.ts +987 -0
- package/src/experiment/factory.ts +86 -0
- package/src/experiment/gen/version.ts +2 -0
- package/src/experiment/index.ts +14 -0
- package/src/experiment/integration/NativeExperimentReactNativeClient.ts +25 -0
- package/src/experiment/integration/connector.ts +82 -0
- package/src/experiment/integration/default.ts +107 -0
- package/src/experiment/logger/ampLogger.ts +76 -0
- package/src/experiment/logger/consoleLogger.ts +54 -0
- package/src/experiment/storage/cache.ts +271 -0
- package/src/experiment/storage/local-storage.ts +23 -0
- package/src/experiment/stubClient.ts +61 -0
- package/src/experiment/transport/http.ts +105 -0
- package/src/experiment/types/client.ts +38 -0
- package/src/experiment/types/config.ts +210 -0
- package/src/experiment/types/exposure.ts +107 -0
- package/src/experiment/types/logger.ts +71 -0
- package/src/experiment/types/source.ts +52 -0
- package/src/experiment/types/storage.ts +6 -0
- package/src/experiment/types/transport.ts +14 -0
- package/src/experiment/types/user.ts +132 -0
- package/src/experiment/types/variant.ts +36 -0
- package/src/experiment/util/backoff.ts +67 -0
- package/src/experiment/util/base64.ts +20 -0
- package/src/experiment/util/convert.ts +78 -0
- package/src/experiment/util/index.ts +23 -0
- package/src/experiment/util/platform.ts +9 -0
- package/src/experiment/util/randomstring.ts +12 -0
- package/src/experiment/util/userSessionExposureTracker.ts +47 -0
- package/src/index.ts +66 -0
- package/src/index.web.ts +19 -0
- package/src/native/context.ts +73 -0
- package/src/native/http.ts +77 -0
- package/src/native/hybrid.ts +32 -0
- package/src/native/storage.ts +107 -0
|
@@ -0,0 +1,792 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ExperimentClient = void 0;
|
|
7
|
+
var _experimentCore = require("@amplitude/experiment-core");
|
|
8
|
+
var _version = require("./gen/version");
|
|
9
|
+
var _connector = require("./integration/connector");
|
|
10
|
+
var _default = require("./integration/default");
|
|
11
|
+
var _ampLogger = require("./logger/ampLogger");
|
|
12
|
+
var _consoleLogger = require("./logger/consoleLogger");
|
|
13
|
+
var _cache = require("./storage/cache");
|
|
14
|
+
var _localStorage = require("./storage/local-storage");
|
|
15
|
+
var _http = require("./transport/http");
|
|
16
|
+
var _config = require("./types/config");
|
|
17
|
+
var _logger = require("./types/logger");
|
|
18
|
+
var _source = require("./types/source");
|
|
19
|
+
var _util = require("./util");
|
|
20
|
+
var _backoff = require("./util/backoff");
|
|
21
|
+
var _convert = require("./util/convert");
|
|
22
|
+
var _userSessionExposureTracker = require("./util/userSessionExposureTracker");
|
|
23
|
+
/**
|
|
24
|
+
* @packageDocumentation
|
|
25
|
+
* @module experiment-react-native-client
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
// Configs which have been removed from the public API.
|
|
29
|
+
// May be added back in the future.
|
|
30
|
+
const fetchBackoffTimeout = 10000;
|
|
31
|
+
const fetchBackoffAttempts = 8;
|
|
32
|
+
const fetchBackoffMinMillis = 500;
|
|
33
|
+
const fetchBackoffMaxMillis = 10000;
|
|
34
|
+
const fetchBackoffScalar = 1.5;
|
|
35
|
+
const flagPollerIntervalMillis = 60000;
|
|
36
|
+
const euServerUrl = "https://api.lab.eu.amplitude.com";
|
|
37
|
+
const euFlagsServerUrl = "https://flag.lab.eu.amplitude.com";
|
|
38
|
+
/**
|
|
39
|
+
* The default {@link Client} used to fetch variations from Experiment's
|
|
40
|
+
* servers.
|
|
41
|
+
*
|
|
42
|
+
* @category Core Usage
|
|
43
|
+
*/
|
|
44
|
+
class ExperimentClient {
|
|
45
|
+
engine = new _experimentCore.EvaluationEngine();
|
|
46
|
+
user = {};
|
|
47
|
+
poller = new _experimentCore.Poller(() => this.pollFlags(), flagPollerIntervalMillis);
|
|
48
|
+
isRunning = false;
|
|
49
|
+
fetchSequenceNumber = 0;
|
|
50
|
+
storedFetchSequenceNumber = 0;
|
|
51
|
+
stopCallbacks = new Set();
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Creates a new ExperimentClient instance.
|
|
55
|
+
*
|
|
56
|
+
* In most cases you will want to use the `initialize` factory method in
|
|
57
|
+
* {@link Experiment}.
|
|
58
|
+
*
|
|
59
|
+
* @param apiKey The Client key for the Experiment project
|
|
60
|
+
* @param config See {@link ExperimentConfig} for config options
|
|
61
|
+
*/
|
|
62
|
+
constructor(apiKey, config) {
|
|
63
|
+
this.apiKey = apiKey;
|
|
64
|
+
const serverZone = config?.serverZone ?? _config.Defaults.serverZone ?? "US";
|
|
65
|
+
this.config = {
|
|
66
|
+
..._config.Defaults,
|
|
67
|
+
...config,
|
|
68
|
+
debug: config?.debug ?? _config.Defaults.debug ?? false,
|
|
69
|
+
logLevel: config?.logLevel ?? _config.Defaults.logLevel ?? _logger.LogLevel.Error,
|
|
70
|
+
loggerProvider: config?.loggerProvider ?? _config.Defaults.loggerProvider ?? null,
|
|
71
|
+
instanceName: config?.instanceName ?? _config.Defaults.instanceName ?? "$default_instance",
|
|
72
|
+
fallbackVariant: config?.fallbackVariant ?? _config.Defaults.fallbackVariant ?? {},
|
|
73
|
+
initialVariants: config?.initialVariants ?? _config.Defaults.initialVariants ?? {},
|
|
74
|
+
source: config?.source ?? _config.Defaults.source ?? _source.Source.LocalStorage,
|
|
75
|
+
serverZone,
|
|
76
|
+
serverUrl: config?.serverUrl ?? (serverZone === "EU" ? euServerUrl : _config.Defaults.serverUrl ?? "https://api.lab.amplitude.com"),
|
|
77
|
+
flagsServerUrl: config?.flagsServerUrl ?? (serverZone === "EU" ? euFlagsServerUrl : _config.Defaults.flagsServerUrl ?? "https://flag.lab.amplitude.com"),
|
|
78
|
+
fetchTimeoutMillis: config?.fetchTimeoutMillis ?? _config.Defaults.fetchTimeoutMillis ?? 10000,
|
|
79
|
+
retryFetchOnFailure: config?.retryFetchOnFailure ?? _config.Defaults.retryFetchOnFailure ?? true,
|
|
80
|
+
automaticExposureTracking: config?.automaticExposureTracking ?? _config.Defaults.automaticExposureTracking ?? true,
|
|
81
|
+
pollOnStart: config?.pollOnStart ?? _config.Defaults.pollOnStart ?? true,
|
|
82
|
+
fetchOnStart: config?.fetchOnStart ?? _config.Defaults.fetchOnStart ?? true,
|
|
83
|
+
automaticFetchOnAmplitudeIdentityChange: config?.automaticFetchOnAmplitudeIdentityChange ?? _config.Defaults.automaticFetchOnAmplitudeIdentityChange ?? false,
|
|
84
|
+
userProvider: config?.userProvider ?? _config.Defaults.userProvider ?? null,
|
|
85
|
+
exposureTrackingProvider: config?.exposureTrackingProvider ?? _config.Defaults.exposureTrackingProvider ?? null,
|
|
86
|
+
httpClient: config?.httpClient ?? _config.Defaults.httpClient ?? _http.FetchHttpClient,
|
|
87
|
+
storage: config?.storage ?? _config.Defaults.storage ?? null
|
|
88
|
+
};
|
|
89
|
+
this.logger = new _ampLogger.AmpLogger(this.config.loggerProvider || new _consoleLogger.ConsoleLogger(), ExperimentClient.getLogLevel(this.config));
|
|
90
|
+
this.defaultUserProvider = new _default.DefaultUserProvider(this.config.userProvider);
|
|
91
|
+
if (this.config.exposureTrackingProvider) {
|
|
92
|
+
this.userSessionExposureTracker = new _userSessionExposureTracker.UserSessionExposureTracker(this.config.exposureTrackingProvider);
|
|
93
|
+
}
|
|
94
|
+
// Setup Remote APIs
|
|
95
|
+
const httpClient = new _http.WrapperClient(this.config.httpClient || _http.FetchHttpClient);
|
|
96
|
+
this.flagApi = new _experimentCore.SdkFlagApi(this.apiKey, this.config.flagsServerUrl, httpClient);
|
|
97
|
+
this.evaluationApi = new _experimentCore.SdkEvaluationApi(this.apiKey, this.config.serverUrl, httpClient);
|
|
98
|
+
// Storage & Caching
|
|
99
|
+
const storage = this.config.storage || new _localStorage.MemoryStorage();
|
|
100
|
+
this.variants = (0, _cache.getVariantStorage)(this.apiKey, this.config.instanceName, storage);
|
|
101
|
+
this.flags = (0, _cache.getFlagStorage)(this.apiKey, this.config.instanceName, storage);
|
|
102
|
+
if (this.config.initialFlags) {
|
|
103
|
+
try {
|
|
104
|
+
this.initialFlags = JSON.parse(this.config.initialFlags);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
this.logger.warn(error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
this.fetchVariantsOptions = (0, _cache.getVariantsOptionsStorage)(this.apiKey, this.config.instanceName, storage);
|
|
110
|
+
this.flagsAndVariantsLoadedPromise = [this.flags.load(this.convertInitialFlagsForStorage()), this.variants.load(), this.fetchVariantsOptions.load()];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Call to ensure the completion of the loading variants and flags from localStorage upon initialization.
|
|
115
|
+
*/
|
|
116
|
+
async cacheReady() {
|
|
117
|
+
await Promise.all(this.flagsAndVariantsLoadedPromise);
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Start the SDK by getting flag configurations from the server and fetching
|
|
123
|
+
* variants for the user. The promise returned by this function resolves when
|
|
124
|
+
* local flag configurations have been updated, and the {@link fetch()}
|
|
125
|
+
* result has been received (if the request was made).
|
|
126
|
+
*
|
|
127
|
+
* To force this function not to fetch variants, set the {@link fetchOnStart}
|
|
128
|
+
* configuration option to `false` when initializing the SDK.
|
|
129
|
+
*
|
|
130
|
+
* Finally, this function will start polling for flag configurations at a
|
|
131
|
+
* fixed interval. To disable polling, set the {@link pollOnStart}
|
|
132
|
+
* configuration option to `false` on initialization.
|
|
133
|
+
*
|
|
134
|
+
* @param user The user to set in the SDK.
|
|
135
|
+
* @see fetchOnStart
|
|
136
|
+
* @see pollOnStart
|
|
137
|
+
* @see fetch
|
|
138
|
+
* @see variant
|
|
139
|
+
*/
|
|
140
|
+
async start(user) {
|
|
141
|
+
if (this.isRunning) {
|
|
142
|
+
return;
|
|
143
|
+
} else {
|
|
144
|
+
this.isRunning = true;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
this.defaultUserProvider.start();
|
|
148
|
+
this.setUser(user ?? {});
|
|
149
|
+
const flagsReadyPromise = this.doFlags();
|
|
150
|
+
const fetchOnStart = this.config.fetchOnStart ?? true;
|
|
151
|
+
if (fetchOnStart) {
|
|
152
|
+
await Promise.all([this.fetch(user), flagsReadyPromise]);
|
|
153
|
+
} else {
|
|
154
|
+
await flagsReadyPromise;
|
|
155
|
+
}
|
|
156
|
+
if (this.config.pollOnStart) {
|
|
157
|
+
this.poller.start();
|
|
158
|
+
}
|
|
159
|
+
} catch (e) {
|
|
160
|
+
this.stop();
|
|
161
|
+
throw e;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Stop background polling and retry work started by the client.
|
|
167
|
+
*/
|
|
168
|
+
stop() {
|
|
169
|
+
this.stopRetries();
|
|
170
|
+
this.defaultUserProvider.stop();
|
|
171
|
+
for (const callback of this.stopCallbacks) {
|
|
172
|
+
try {
|
|
173
|
+
callback();
|
|
174
|
+
} catch (e) {
|
|
175
|
+
this.logger.warn(e);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
this.stopCallbacks.clear();
|
|
179
|
+
if (!this.isRunning) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
this.poller.stop();
|
|
183
|
+
this.isRunning = false;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Assign the given user to the SDK and asynchronously fetch all variants
|
|
188
|
+
* from the server. Subsequent calls may omit the user from the argument to
|
|
189
|
+
* use the user from the previous call.
|
|
190
|
+
*
|
|
191
|
+
* If an {@link ExperimentUserProvider} has been set, the argument user will
|
|
192
|
+
* be merged with the provider user, preferring user fields from the argument
|
|
193
|
+
* user and falling back on the provider for fields which are null or
|
|
194
|
+
* undefined.
|
|
195
|
+
*
|
|
196
|
+
* If configured, fetch retries the request in the background on failure.
|
|
197
|
+
* Variants received from a successful retry are stored in local storage for
|
|
198
|
+
* access.
|
|
199
|
+
*
|
|
200
|
+
* If you are using the `initialVariants` config option to preload this SDK
|
|
201
|
+
* from the server, you generally do not need to call `fetch`.
|
|
202
|
+
*
|
|
203
|
+
* @param user The user to fetch variants for.
|
|
204
|
+
* @param options Options for this specific fetch call.
|
|
205
|
+
* @returns Promise that resolves when the request for variants completes.
|
|
206
|
+
* @see ExperimentUser
|
|
207
|
+
* @see ExperimentUserProvider
|
|
208
|
+
*/
|
|
209
|
+
async fetch(user = this.user, options) {
|
|
210
|
+
const fetchUser = user ?? this.user;
|
|
211
|
+
this.setUser(fetchUser);
|
|
212
|
+
try {
|
|
213
|
+
await this.fetchWithRetries(fetchUser, options);
|
|
214
|
+
} catch (e) {
|
|
215
|
+
this.logger.warn(e);
|
|
216
|
+
}
|
|
217
|
+
return this;
|
|
218
|
+
}
|
|
219
|
+
async fetchOrThrow(user = this.user, options) {
|
|
220
|
+
const fetchUser = user ?? this.user;
|
|
221
|
+
this.setUser(fetchUser);
|
|
222
|
+
await this.fetchWithRetries(fetchUser, options);
|
|
223
|
+
return this;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Returns the variant for the provided key.
|
|
228
|
+
*
|
|
229
|
+
* Access the variant from {@link Source}, falling back on the given
|
|
230
|
+
* fallback, then the configured fallbackVariant.
|
|
231
|
+
*
|
|
232
|
+
* If an {@link ExposureTrackingProvider} is configured and trackExposure is
|
|
233
|
+
* true, this function will call the provider with an {@link Exposure}.
|
|
234
|
+
* The exposure event does not count towards your event volume within Amplitude.
|
|
235
|
+
*
|
|
236
|
+
* @param key The key to get the variant for.
|
|
237
|
+
* @param fallback The highest priority fallback.
|
|
238
|
+
* @see ExperimentConfig
|
|
239
|
+
* @see ExposureTrackingProvider
|
|
240
|
+
*/
|
|
241
|
+
variant(key, fallback) {
|
|
242
|
+
if (!this.apiKey) {
|
|
243
|
+
return {
|
|
244
|
+
value: undefined
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
const sourceVariant = this.variantAndSource(key, fallback);
|
|
248
|
+
if (this.config.automaticExposureTracking) {
|
|
249
|
+
this.exposureInternal(key, sourceVariant);
|
|
250
|
+
}
|
|
251
|
+
this.logger.debug(`[Experiment] variant for ${key} is ${sourceVariant.variant?.value}`);
|
|
252
|
+
return sourceVariant.variant || {};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Track an exposure event for the variant associated with the flag/experiment
|
|
257
|
+
* {@link key}.
|
|
258
|
+
*
|
|
259
|
+
* This method requires that an {@link ExposureTrackingProvider} be
|
|
260
|
+
* configured when this client is initialized, either manually, or through the
|
|
261
|
+
* Amplitude Analytics SDK integration from set up using
|
|
262
|
+
* {@link Experiment.initializeWithAmplitudeAnalytics}.
|
|
263
|
+
*
|
|
264
|
+
* @param key The flag/experiment key to track an exposure for.
|
|
265
|
+
*/
|
|
266
|
+
exposure(key) {
|
|
267
|
+
const sourceVariant = this.variantAndSource(key);
|
|
268
|
+
this.exposureInternal(key, sourceVariant);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Returns all variants for the user.
|
|
273
|
+
*
|
|
274
|
+
* The primary source of variants is based on the
|
|
275
|
+
* {@link Source} configured in the {@link ExperimentConfig}.
|
|
276
|
+
*
|
|
277
|
+
* @see Source
|
|
278
|
+
* @see ExperimentConfig
|
|
279
|
+
*/
|
|
280
|
+
all() {
|
|
281
|
+
if (!this.apiKey) {
|
|
282
|
+
return {};
|
|
283
|
+
}
|
|
284
|
+
const evaluatedVariants = this.evaluate();
|
|
285
|
+
for (const flagKey in evaluatedVariants) {
|
|
286
|
+
const flag = this.flags.get(flagKey);
|
|
287
|
+
if (!(0, _util.isLocalEvaluationMode)(flag)) {
|
|
288
|
+
delete evaluatedVariants[flagKey];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
...this.secondaryVariants(),
|
|
293
|
+
...this.sourceVariants(),
|
|
294
|
+
...evaluatedVariants
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Clear all variants in the cache and storage.
|
|
300
|
+
*/
|
|
301
|
+
clear() {
|
|
302
|
+
this.variants.clear();
|
|
303
|
+
void this.variants.store().catch(e => this.logger.warn(e));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Get a copy of the internal {@link ExperimentUser} object if it is set.
|
|
308
|
+
*
|
|
309
|
+
* @returns a copy of the internal user object if set.
|
|
310
|
+
*/
|
|
311
|
+
getUser() {
|
|
312
|
+
if (!this.user) {
|
|
313
|
+
return {};
|
|
314
|
+
}
|
|
315
|
+
if (this.user?.user_properties) {
|
|
316
|
+
const userPropertiesCopy = {
|
|
317
|
+
...this.user.user_properties
|
|
318
|
+
};
|
|
319
|
+
return {
|
|
320
|
+
...this.user,
|
|
321
|
+
user_properties: userPropertiesCopy
|
|
322
|
+
};
|
|
323
|
+
} else {
|
|
324
|
+
return {
|
|
325
|
+
...this.user
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Copy in and set the user within the experiment client.
|
|
332
|
+
*
|
|
333
|
+
* @param user the user to set within the experiment client.
|
|
334
|
+
*/
|
|
335
|
+
setUser(user) {
|
|
336
|
+
if (!user) {
|
|
337
|
+
this.user = {};
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
if (this.user?.user_properties) {
|
|
341
|
+
const userPropertiesCopy = {
|
|
342
|
+
...user.user_properties
|
|
343
|
+
};
|
|
344
|
+
this.user = {
|
|
345
|
+
...user,
|
|
346
|
+
user_properties: userPropertiesCopy
|
|
347
|
+
};
|
|
348
|
+
} else {
|
|
349
|
+
this.user = {
|
|
350
|
+
...user
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Get the user provider set by {@link setUserProvider} or null if the user
|
|
357
|
+
* provider has not been set.
|
|
358
|
+
*
|
|
359
|
+
* @returns The user provider set by {@link setUserProvider} or null.
|
|
360
|
+
* @deprecated use ExperimentConfig.userProvider instead
|
|
361
|
+
*/
|
|
362
|
+
getUserProvider() {
|
|
363
|
+
return this.defaultUserProvider;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Sets a user provider that will inject identity information into the user
|
|
368
|
+
* for {@link fetch()} requests. The user provider will only set user fields
|
|
369
|
+
* in outgoing requests which are null or undefined.
|
|
370
|
+
*
|
|
371
|
+
* See {@link ExperimentUserProvider} for more details
|
|
372
|
+
* @param userProvider
|
|
373
|
+
* @deprecated use ExperimentConfig.userProvider instead
|
|
374
|
+
*/
|
|
375
|
+
setUserProvider(userProvider) {
|
|
376
|
+
this.defaultUserProvider.baseProvider = userProvider;
|
|
377
|
+
return this;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Enables or disables tracking of assignment events when fetching variants.
|
|
382
|
+
* @param doTrack Whether to track assignment events.
|
|
383
|
+
*/
|
|
384
|
+
async setTracksAssignment(doTrack) {
|
|
385
|
+
this.fetchVariantsOptions.put({
|
|
386
|
+
...this.fetchVariantsOptions.get(),
|
|
387
|
+
trackingOption: doTrack ? "track" : "no-track"
|
|
388
|
+
});
|
|
389
|
+
await this.fetchVariantsOptions.store();
|
|
390
|
+
}
|
|
391
|
+
addStopCallback(callback) {
|
|
392
|
+
this.stopCallbacks.add(callback);
|
|
393
|
+
}
|
|
394
|
+
fetchOnIdentityChange() {
|
|
395
|
+
void this.fetch().catch(e => this.logger.warn(e));
|
|
396
|
+
}
|
|
397
|
+
convertInitialFlagsForStorage() {
|
|
398
|
+
if (this.initialFlags) {
|
|
399
|
+
const flagsMap = {};
|
|
400
|
+
this.initialFlags.forEach(flag => {
|
|
401
|
+
flagsMap[flag.key] = flag;
|
|
402
|
+
});
|
|
403
|
+
return flagsMap;
|
|
404
|
+
}
|
|
405
|
+
return {};
|
|
406
|
+
}
|
|
407
|
+
mergeInitialFlagsWithStorage() {
|
|
408
|
+
if (this.initialFlags) {
|
|
409
|
+
this.initialFlags.forEach(flag => {
|
|
410
|
+
if (!this.flags.get(flag.key)) {
|
|
411
|
+
this.flags.put(flag.key, flag);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
evaluate(flagKeys) {
|
|
417
|
+
const user = this.addContextSync(this.user);
|
|
418
|
+
const flags = (0, _experimentCore.topologicalSort)(this.flags.getAll(), flagKeys);
|
|
419
|
+
const context = (0, _convert.convertUserToContext)(user);
|
|
420
|
+
const evaluationVariants = this.engine.evaluate(context, flags);
|
|
421
|
+
const variants = {};
|
|
422
|
+
for (const flagKey of Object.keys(evaluationVariants)) {
|
|
423
|
+
variants[flagKey] = (0, _convert.convertEvaluationVariantToVariant)(evaluationVariants[flagKey]);
|
|
424
|
+
}
|
|
425
|
+
return variants;
|
|
426
|
+
}
|
|
427
|
+
variantAndSource(key, fallback) {
|
|
428
|
+
let sourceVariant = {};
|
|
429
|
+
if (this.config.source === _source.Source.LocalStorage) {
|
|
430
|
+
sourceVariant = this.localStorageVariantAndSource(key, fallback);
|
|
431
|
+
} else if (this.config.source === _source.Source.InitialVariants) {
|
|
432
|
+
sourceVariant = this.initialVariantsVariantAndSource(key, fallback);
|
|
433
|
+
}
|
|
434
|
+
const flag = this.flags.get(key);
|
|
435
|
+
if (flag && ((0, _util.isLocalEvaluationMode)(flag) || !sourceVariant.variant)) {
|
|
436
|
+
sourceVariant = this.localEvaluationVariantAndSource(key, flag, fallback);
|
|
437
|
+
}
|
|
438
|
+
return sourceVariant;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* This function assumes the flag exists and is local evaluation mode. For
|
|
443
|
+
* local evaluation, fallback order goes:
|
|
444
|
+
*
|
|
445
|
+
* 1. Local evaluation
|
|
446
|
+
* 2. Inline function fallback
|
|
447
|
+
* 3. Initial variants
|
|
448
|
+
* 4. Config fallback
|
|
449
|
+
*
|
|
450
|
+
* If there is a default variant and no fallback, return the default variant.
|
|
451
|
+
*/
|
|
452
|
+
localEvaluationVariantAndSource(key, flag, fallback) {
|
|
453
|
+
let defaultSourceVariant = {};
|
|
454
|
+
// Local evaluation
|
|
455
|
+
const variant = this.evaluate([flag.key])[key];
|
|
456
|
+
const source = _source.VariantSource.LocalEvaluation;
|
|
457
|
+
const isLocalEvaluationDefault = variant?.metadata?.default;
|
|
458
|
+
if (!(0, _util.isNullOrUndefined)(variant) && !isLocalEvaluationDefault) {
|
|
459
|
+
return {
|
|
460
|
+
variant: (0, _convert.convertVariant)(variant),
|
|
461
|
+
source: source,
|
|
462
|
+
hasDefaultVariant: false
|
|
463
|
+
};
|
|
464
|
+
} else if (isLocalEvaluationDefault) {
|
|
465
|
+
defaultSourceVariant = {
|
|
466
|
+
variant: (0, _convert.convertVariant)(variant),
|
|
467
|
+
source: source,
|
|
468
|
+
hasDefaultVariant: true
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
// Inline fallback
|
|
472
|
+
if (!(0, _util.isNullOrUndefined)(fallback)) {
|
|
473
|
+
return {
|
|
474
|
+
variant: (0, _convert.convertVariant)(fallback),
|
|
475
|
+
source: _source.VariantSource.FallbackInline,
|
|
476
|
+
hasDefaultVariant: defaultSourceVariant.hasDefaultVariant
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
// Initial variants
|
|
480
|
+
const initialVariant = this.config.initialVariants[key];
|
|
481
|
+
if (!(0, _util.isNullOrUndefined)(initialVariant)) {
|
|
482
|
+
return {
|
|
483
|
+
variant: (0, _convert.convertVariant)(initialVariant),
|
|
484
|
+
source: _source.VariantSource.SecondaryInitialVariants,
|
|
485
|
+
hasDefaultVariant: defaultSourceVariant.hasDefaultVariant
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
// Configured fallback, or default variant
|
|
489
|
+
const fallbackVariant = (0, _convert.convertVariant)(this.config.fallbackVariant);
|
|
490
|
+
const fallbackSourceVariant = {
|
|
491
|
+
variant: fallbackVariant,
|
|
492
|
+
source: _source.VariantSource.FallbackConfig,
|
|
493
|
+
hasDefaultVariant: defaultSourceVariant.hasDefaultVariant
|
|
494
|
+
};
|
|
495
|
+
if (!(0, _util.isNullUndefinedOrEmpty)(fallbackVariant)) {
|
|
496
|
+
return fallbackSourceVariant;
|
|
497
|
+
}
|
|
498
|
+
return defaultSourceVariant;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* For Source.LocalStorage, fallback order goes:
|
|
503
|
+
*
|
|
504
|
+
* 1. Local Storage
|
|
505
|
+
* 2. Inline function fallback
|
|
506
|
+
* 3. InitialFlags
|
|
507
|
+
* 4. Config fallback
|
|
508
|
+
*
|
|
509
|
+
* If there is a default variant and no fallback, return the default variant.
|
|
510
|
+
*/
|
|
511
|
+
localStorageVariantAndSource(key, fallback) {
|
|
512
|
+
let defaultSourceVariant = {};
|
|
513
|
+
// Local storage
|
|
514
|
+
const localStorageVariant = this.variants.get(key);
|
|
515
|
+
const isLocalStorageDefault = localStorageVariant?.metadata?.default;
|
|
516
|
+
if (!(0, _util.isNullOrUndefined)(localStorageVariant) && !isLocalStorageDefault) {
|
|
517
|
+
return {
|
|
518
|
+
variant: (0, _convert.convertVariant)(localStorageVariant),
|
|
519
|
+
source: _source.VariantSource.LocalStorage,
|
|
520
|
+
hasDefaultVariant: false
|
|
521
|
+
};
|
|
522
|
+
} else if (isLocalStorageDefault) {
|
|
523
|
+
defaultSourceVariant = {
|
|
524
|
+
variant: (0, _convert.convertVariant)(localStorageVariant),
|
|
525
|
+
source: _source.VariantSource.LocalStorage,
|
|
526
|
+
hasDefaultVariant: true
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
// Inline fallback
|
|
530
|
+
if (!(0, _util.isNullOrUndefined)(fallback)) {
|
|
531
|
+
return {
|
|
532
|
+
variant: (0, _convert.convertVariant)(fallback),
|
|
533
|
+
source: _source.VariantSource.FallbackInline,
|
|
534
|
+
hasDefaultVariant: defaultSourceVariant.hasDefaultVariant
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
// Initial variants
|
|
538
|
+
const initialVariant = this.config.initialVariants[key];
|
|
539
|
+
if (!(0, _util.isNullOrUndefined)(initialVariant)) {
|
|
540
|
+
return {
|
|
541
|
+
variant: (0, _convert.convertVariant)(initialVariant),
|
|
542
|
+
source: _source.VariantSource.SecondaryInitialVariants,
|
|
543
|
+
hasDefaultVariant: defaultSourceVariant.hasDefaultVariant
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
// Configured fallback, or default variant
|
|
547
|
+
const fallbackVariant = (0, _convert.convertVariant)(this.config.fallbackVariant);
|
|
548
|
+
const fallbackSourceVariant = {
|
|
549
|
+
variant: fallbackVariant,
|
|
550
|
+
source: _source.VariantSource.FallbackConfig,
|
|
551
|
+
hasDefaultVariant: defaultSourceVariant.hasDefaultVariant
|
|
552
|
+
};
|
|
553
|
+
if (!(0, _util.isNullUndefinedOrEmpty)(fallbackVariant)) {
|
|
554
|
+
return fallbackSourceVariant;
|
|
555
|
+
}
|
|
556
|
+
return defaultSourceVariant;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* For Source.InitialVariants, fallback order goes:
|
|
561
|
+
*
|
|
562
|
+
* 1. Initial variants
|
|
563
|
+
* 2. Local storage
|
|
564
|
+
* 3. Inline function fallback
|
|
565
|
+
* 4. Config fallback
|
|
566
|
+
*
|
|
567
|
+
* If there is a default variant and no fallback, return the default variant.
|
|
568
|
+
*/
|
|
569
|
+
initialVariantsVariantAndSource(key, fallback) {
|
|
570
|
+
let defaultSourceVariant = {};
|
|
571
|
+
// Initial variants
|
|
572
|
+
const initialVariantsVariant = this.config.initialVariants[key];
|
|
573
|
+
if (!(0, _util.isNullOrUndefined)(initialVariantsVariant)) {
|
|
574
|
+
return {
|
|
575
|
+
variant: (0, _convert.convertVariant)(initialVariantsVariant),
|
|
576
|
+
source: _source.VariantSource.InitialVariants,
|
|
577
|
+
hasDefaultVariant: false
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
// Local storage
|
|
581
|
+
const localStorageVariant = this.variants.get(key);
|
|
582
|
+
const isLocalStorageDefault = localStorageVariant?.metadata?.default;
|
|
583
|
+
if (!(0, _util.isNullOrUndefined)(localStorageVariant) && !isLocalStorageDefault) {
|
|
584
|
+
return {
|
|
585
|
+
variant: (0, _convert.convertVariant)(localStorageVariant),
|
|
586
|
+
source: _source.VariantSource.LocalStorage,
|
|
587
|
+
hasDefaultVariant: false
|
|
588
|
+
};
|
|
589
|
+
} else if (isLocalStorageDefault) {
|
|
590
|
+
defaultSourceVariant = {
|
|
591
|
+
variant: (0, _convert.convertVariant)(localStorageVariant),
|
|
592
|
+
source: _source.VariantSource.LocalStorage,
|
|
593
|
+
hasDefaultVariant: true
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
// Inline fallback
|
|
597
|
+
if (!(0, _util.isNullOrUndefined)(fallback)) {
|
|
598
|
+
return {
|
|
599
|
+
variant: (0, _convert.convertVariant)(fallback),
|
|
600
|
+
source: _source.VariantSource.FallbackInline,
|
|
601
|
+
hasDefaultVariant: defaultSourceVariant.hasDefaultVariant
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
// Configured fallback, or default variant
|
|
605
|
+
const fallbackVariant = (0, _convert.convertVariant)(this.config.fallbackVariant);
|
|
606
|
+
const fallbackSourceVariant = {
|
|
607
|
+
variant: fallbackVariant,
|
|
608
|
+
source: _source.VariantSource.FallbackConfig,
|
|
609
|
+
hasDefaultVariant: defaultSourceVariant.hasDefaultVariant
|
|
610
|
+
};
|
|
611
|
+
if (!(0, _util.isNullUndefinedOrEmpty)(fallbackVariant)) {
|
|
612
|
+
return fallbackSourceVariant;
|
|
613
|
+
}
|
|
614
|
+
return defaultSourceVariant;
|
|
615
|
+
}
|
|
616
|
+
async fetchInternal(user, timeoutMillis, retry, options) {
|
|
617
|
+
// Don't even try to fetch variants if API key is not set
|
|
618
|
+
if (!this.apiKey) {
|
|
619
|
+
throw Error("Experiment API key is empty");
|
|
620
|
+
}
|
|
621
|
+
this.logger.debug(`[Experiment] Fetch all: retry=${retry}`);
|
|
622
|
+
|
|
623
|
+
// Proactively cancel retries if active in order to avoid unnecessary API
|
|
624
|
+
// requests. A new failure will restart the retries.
|
|
625
|
+
if (retry) {
|
|
626
|
+
this.stopRetries();
|
|
627
|
+
}
|
|
628
|
+
const sequenceNumber = ++this.fetchSequenceNumber;
|
|
629
|
+
try {
|
|
630
|
+
const variants = await this.doFetch(user, timeoutMillis, options);
|
|
631
|
+
await this.storeVariants(variants, sequenceNumber, options);
|
|
632
|
+
return variants;
|
|
633
|
+
} catch (e) {
|
|
634
|
+
if (retry && this.shouldRetryFetch(e)) {
|
|
635
|
+
this.startRetries(user, options);
|
|
636
|
+
}
|
|
637
|
+
throw e;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
async fetchWithRetries(user, options) {
|
|
641
|
+
return await this.fetchInternal(user, this.config.fetchTimeoutMillis, this.config.retryFetchOnFailure, options);
|
|
642
|
+
}
|
|
643
|
+
async doFetch(user, timeoutMillis, options) {
|
|
644
|
+
user = await this.addContextOrWait(user, 10000);
|
|
645
|
+
this.logger.debug("[Experiment] Fetch variants for user: ", user);
|
|
646
|
+
const results = await this.evaluationApi.getVariants(user, {
|
|
647
|
+
...this.fetchVariantsOptions.get(),
|
|
648
|
+
timeoutMillis: timeoutMillis,
|
|
649
|
+
flagKeys: options?.flagKeys
|
|
650
|
+
});
|
|
651
|
+
const variants = {};
|
|
652
|
+
for (const key of Object.keys(results)) {
|
|
653
|
+
variants[key] = (0, _convert.convertEvaluationVariantToVariant)(results[key]);
|
|
654
|
+
}
|
|
655
|
+
this.logger.debug("[Experiment] Received variants: ", variants);
|
|
656
|
+
return variants;
|
|
657
|
+
}
|
|
658
|
+
async doFlags() {
|
|
659
|
+
const flags = await this.flagApi.getFlags({
|
|
660
|
+
libraryName: "experiment-js-client",
|
|
661
|
+
libraryVersion: _version.version,
|
|
662
|
+
timeoutMillis: this.config.fetchTimeoutMillis
|
|
663
|
+
});
|
|
664
|
+
this.flags.clear();
|
|
665
|
+
this.flags.putAll(flags);
|
|
666
|
+
await this.flags.store();
|
|
667
|
+
this.mergeInitialFlagsWithStorage();
|
|
668
|
+
}
|
|
669
|
+
async pollFlags() {
|
|
670
|
+
try {
|
|
671
|
+
await this.doFlags();
|
|
672
|
+
} catch (e) {
|
|
673
|
+
this.logger.warn(e);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
async storeVariants(variants, sequenceNumber, options) {
|
|
677
|
+
if (sequenceNumber <= this.storedFetchSequenceNumber) {
|
|
678
|
+
this.logger.debug(`[Experiment] Ignoring stale fetch response (sequence ${sequenceNumber} <= ${this.storedFetchSequenceNumber})`);
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
let failedFlagKeys = options?.flagKeys ? options.flagKeys : [];
|
|
682
|
+
if (failedFlagKeys.length === 0) {
|
|
683
|
+
this.variants.clear();
|
|
684
|
+
}
|
|
685
|
+
for (const key in variants) {
|
|
686
|
+
failedFlagKeys = failedFlagKeys.filter(flagKey => flagKey !== key);
|
|
687
|
+
this.variants.put(key, variants[key]);
|
|
688
|
+
}
|
|
689
|
+
for (const key in failedFlagKeys) {
|
|
690
|
+
this.variants.remove(key);
|
|
691
|
+
}
|
|
692
|
+
await this.variants.store();
|
|
693
|
+
this.storedFetchSequenceNumber = sequenceNumber;
|
|
694
|
+
this.logger.debug("[Experiment] Stored variants: ", variants);
|
|
695
|
+
}
|
|
696
|
+
startRetries(user, options) {
|
|
697
|
+
this.logger.debug("[Experiment] Retry fetch");
|
|
698
|
+
this.retriesBackoff = new _backoff.Backoff(fetchBackoffAttempts, fetchBackoffMinMillis, fetchBackoffMaxMillis, fetchBackoffScalar);
|
|
699
|
+
this.retriesBackoff.start(async () => {
|
|
700
|
+
await this.fetchInternal(user, fetchBackoffTimeout, false, options);
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
stopRetries() {
|
|
704
|
+
if (this.retriesBackoff != null) {
|
|
705
|
+
this.retriesBackoff.cancel();
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
addContextSync(user) {
|
|
709
|
+
const providedUser = this.defaultUserProvider.getUserSync();
|
|
710
|
+
return this.mergeContext(user, providedUser);
|
|
711
|
+
}
|
|
712
|
+
async addContext(user) {
|
|
713
|
+
const providedUser = await this.defaultUserProvider.getUser();
|
|
714
|
+
return this.mergeContext(user, providedUser);
|
|
715
|
+
}
|
|
716
|
+
async addContextOrWait(user, ms) {
|
|
717
|
+
const baseProvider = this.defaultUserProvider.baseProvider;
|
|
718
|
+
if (baseProvider instanceof _connector.ConnectorUserProvider) {
|
|
719
|
+
await baseProvider.identityReady(ms);
|
|
720
|
+
}
|
|
721
|
+
return this.addContext(user);
|
|
722
|
+
}
|
|
723
|
+
mergeContext(user, providedUser) {
|
|
724
|
+
const mergedUserProperties = {
|
|
725
|
+
...user?.user_properties,
|
|
726
|
+
...providedUser?.user_properties
|
|
727
|
+
};
|
|
728
|
+
return {
|
|
729
|
+
library: `experiment-react-native-client/${_version.version}`,
|
|
730
|
+
...providedUser,
|
|
731
|
+
...user,
|
|
732
|
+
user_properties: mergedUserProperties
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
sourceVariants() {
|
|
736
|
+
if (this.config.source === _source.Source.LocalStorage) {
|
|
737
|
+
return this.variants.getAll();
|
|
738
|
+
} else if (this.config.source === _source.Source.InitialVariants) {
|
|
739
|
+
return this.config.initialVariants;
|
|
740
|
+
}
|
|
741
|
+
return {};
|
|
742
|
+
}
|
|
743
|
+
secondaryVariants() {
|
|
744
|
+
if (this.config.source === _source.Source.LocalStorage) {
|
|
745
|
+
return this.config.initialVariants;
|
|
746
|
+
} else if (this.config.source === _source.Source.InitialVariants) {
|
|
747
|
+
return this.variants.getAll();
|
|
748
|
+
}
|
|
749
|
+
return {};
|
|
750
|
+
}
|
|
751
|
+
exposureInternal(key, sourceVariant) {
|
|
752
|
+
const exposure = {
|
|
753
|
+
flag_key: key
|
|
754
|
+
};
|
|
755
|
+
// Do not track exposure for fallback variants that are not associated with
|
|
756
|
+
// a default variant.
|
|
757
|
+
const fallback = (0, _source.isFallback)(sourceVariant.source);
|
|
758
|
+
if (fallback && !sourceVariant.hasDefaultVariant) {
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
if (sourceVariant.variant?.expKey) {
|
|
762
|
+
exposure.experiment_key = sourceVariant.variant?.expKey;
|
|
763
|
+
}
|
|
764
|
+
const metadata = sourceVariant.variant?.metadata;
|
|
765
|
+
if (!fallback && !metadata?.default) {
|
|
766
|
+
if (sourceVariant.variant?.key) {
|
|
767
|
+
exposure.variant = sourceVariant.variant.key;
|
|
768
|
+
} else if (sourceVariant.variant?.value) {
|
|
769
|
+
exposure.variant = sourceVariant.variant.value;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
if (metadata) exposure.metadata = metadata;
|
|
773
|
+
const user = this.addContextSync(this.getUser());
|
|
774
|
+
this.userSessionExposureTracker?.track(exposure, user);
|
|
775
|
+
}
|
|
776
|
+
static getLogLevel(config) {
|
|
777
|
+
// Backwards compatibility: if debug flag is set to true, use Debug level
|
|
778
|
+
if (config.debug === true) {
|
|
779
|
+
return _logger.LogLevel.Debug;
|
|
780
|
+
}
|
|
781
|
+
// Otherwise use the configured logLevel or default to Warn
|
|
782
|
+
return config.logLevel ?? _logger.LogLevel.Warn;
|
|
783
|
+
}
|
|
784
|
+
shouldRetryFetch(e) {
|
|
785
|
+
if (e instanceof _experimentCore.FetchError) {
|
|
786
|
+
return e.statusCode < 400 || e.statusCode >= 500 || e.statusCode === 429;
|
|
787
|
+
}
|
|
788
|
+
return true;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
exports.ExperimentClient = ExperimentClient;
|
|
792
|
+
//# sourceMappingURL=experimentClient.js.map
|