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,271 @@
|
|
|
1
|
+
import { EvaluationFlag, GetVariantsOptions } from "@amplitude/experiment-core";
|
|
2
|
+
|
|
3
|
+
import { Storage } from "../types/storage";
|
|
4
|
+
import { Variant } from "../types/variant";
|
|
5
|
+
|
|
6
|
+
export const getVariantStorage = (
|
|
7
|
+
deploymentKey: string,
|
|
8
|
+
instanceName: string,
|
|
9
|
+
storage: Storage,
|
|
10
|
+
): LoadStoreCache<Variant> => {
|
|
11
|
+
const namespace = getNamespace(deploymentKey, instanceName);
|
|
12
|
+
const legacyNamespace = getLegacyNamespace(deploymentKey, instanceName);
|
|
13
|
+
return new LoadStoreCache<Variant>(
|
|
14
|
+
namespace,
|
|
15
|
+
storage,
|
|
16
|
+
transformVariantFromStorage,
|
|
17
|
+
[legacyNamespace],
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const getFlagStorage = (
|
|
22
|
+
deploymentKey: string,
|
|
23
|
+
instanceName: string,
|
|
24
|
+
storage: Storage,
|
|
25
|
+
): LoadStoreCache<EvaluationFlag> => {
|
|
26
|
+
const namespace = `${getNamespace(deploymentKey, instanceName)}-flags`;
|
|
27
|
+
const legacyNamespace = `${getLegacyNamespace(
|
|
28
|
+
deploymentKey,
|
|
29
|
+
instanceName,
|
|
30
|
+
)}-flags`;
|
|
31
|
+
return new LoadStoreCache<EvaluationFlag>(namespace, storage, undefined, [
|
|
32
|
+
legacyNamespace,
|
|
33
|
+
]);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const getVariantsOptionsStorage = (
|
|
37
|
+
deploymentKey: string,
|
|
38
|
+
instanceName: string,
|
|
39
|
+
storage: Storage,
|
|
40
|
+
): SingleValueStoreCache<GetVariantsOptions> => {
|
|
41
|
+
const namespace = `${getNamespace(
|
|
42
|
+
deploymentKey,
|
|
43
|
+
instanceName,
|
|
44
|
+
)}-variants-options`;
|
|
45
|
+
const legacyNamespace = `${getLegacyNamespace(
|
|
46
|
+
deploymentKey,
|
|
47
|
+
instanceName,
|
|
48
|
+
)}-variants-options`;
|
|
49
|
+
return new SingleValueStoreCache<GetVariantsOptions>(namespace, storage, [
|
|
50
|
+
legacyNamespace,
|
|
51
|
+
]);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const getNamespace = (deploymentKey: string, instanceName: string): string => {
|
|
55
|
+
return `amp-exp-${instanceName}-${hashString(deploymentKey)}`;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const getLegacyNamespace = (
|
|
59
|
+
deploymentKey: string,
|
|
60
|
+
instanceName: string,
|
|
61
|
+
): string => {
|
|
62
|
+
const truncatedDeployment = deploymentKey.substring(deploymentKey.length - 6);
|
|
63
|
+
return `amp-exp-${instanceName}-${truncatedDeployment}`;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const hashString = (value: string): string => {
|
|
67
|
+
let hash = 2166136261;
|
|
68
|
+
for (let i = 0; i < value.length; i++) {
|
|
69
|
+
hash ^= value.charCodeAt(i);
|
|
70
|
+
hash = Math.imul(hash, 16777619);
|
|
71
|
+
}
|
|
72
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export class SingleValueStoreCache<V> {
|
|
76
|
+
private readonly namespace: string;
|
|
77
|
+
private readonly legacyNamespaces: string[];
|
|
78
|
+
private readonly storage: Storage;
|
|
79
|
+
private value: V | undefined;
|
|
80
|
+
|
|
81
|
+
constructor(
|
|
82
|
+
namespace: string,
|
|
83
|
+
storage: Storage,
|
|
84
|
+
legacyNamespaces: string[] = [],
|
|
85
|
+
) {
|
|
86
|
+
this.namespace = namespace;
|
|
87
|
+
this.legacyNamespaces = legacyNamespaces;
|
|
88
|
+
this.storage = storage;
|
|
89
|
+
this.value = this.get();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public get(): V | undefined {
|
|
93
|
+
return this.value;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public put(value: V): void {
|
|
97
|
+
this.value = value;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public async load(): Promise<void> {
|
|
101
|
+
let value = await this.storage.get(this.namespace);
|
|
102
|
+
for (const legacyNamespace of this.legacyNamespaces) {
|
|
103
|
+
if (value) {
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
value = await this.storage.get(legacyNamespace);
|
|
107
|
+
}
|
|
108
|
+
if (value) {
|
|
109
|
+
try {
|
|
110
|
+
this.value = JSON.parse(value);
|
|
111
|
+
} catch {
|
|
112
|
+
this.value = undefined;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public async store(): Promise<void> {
|
|
118
|
+
if (this.value === undefined) {
|
|
119
|
+
// Delete the key if the value is undefined
|
|
120
|
+
await this.storage.delete(this.namespace);
|
|
121
|
+
} else {
|
|
122
|
+
// Also store false or null values
|
|
123
|
+
await this.storage.put(this.namespace, JSON.stringify(this.value));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export class LoadStoreCache<V> {
|
|
129
|
+
private readonly namespace: string;
|
|
130
|
+
private readonly legacyNamespaces: string[];
|
|
131
|
+
private readonly storage: Storage;
|
|
132
|
+
private readonly transformer?: (value: unknown) => V | undefined;
|
|
133
|
+
private cache: Record<string, V> = {};
|
|
134
|
+
|
|
135
|
+
constructor(
|
|
136
|
+
namespace: string,
|
|
137
|
+
storage: Storage,
|
|
138
|
+
transformer?: (value: unknown) => V | undefined,
|
|
139
|
+
legacyNamespaces: string[] = [],
|
|
140
|
+
) {
|
|
141
|
+
this.namespace = namespace;
|
|
142
|
+
this.legacyNamespaces = legacyNamespaces;
|
|
143
|
+
this.storage = storage;
|
|
144
|
+
this.transformer = transformer;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public get(key: string): V | undefined {
|
|
148
|
+
return this.cache[key];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public getAll(): Record<string, V> {
|
|
152
|
+
return { ...this.cache };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public put(key: string, value: V): void {
|
|
156
|
+
this.cache[key] = value;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
public putAll(values: Record<string, V>): void {
|
|
160
|
+
for (const key of Object.keys(values)) {
|
|
161
|
+
this.cache[key] = values[key];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
public remove(key: string): void {
|
|
166
|
+
delete this.cache[key];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public clear(): void {
|
|
170
|
+
this.cache = {};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public async load(initialValues?: Record<string, V>): Promise<void> {
|
|
174
|
+
let rawValues = await this.storage.get(this.namespace);
|
|
175
|
+
for (const legacyNamespace of this.legacyNamespaces) {
|
|
176
|
+
if (rawValues) {
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
rawValues = await this.storage.get(legacyNamespace);
|
|
180
|
+
}
|
|
181
|
+
let jsonValues: Record<string, unknown> = {};
|
|
182
|
+
if (!rawValues) {
|
|
183
|
+
this.clear();
|
|
184
|
+
if (initialValues) {
|
|
185
|
+
this.putAll(initialValues);
|
|
186
|
+
}
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
jsonValues = (JSON.parse(rawValues) as Record<string, unknown>) || {};
|
|
191
|
+
} catch {
|
|
192
|
+
this.clear();
|
|
193
|
+
if (initialValues) {
|
|
194
|
+
this.putAll(initialValues);
|
|
195
|
+
}
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const values: Record<string, V> = {};
|
|
199
|
+
for (const key of Object.keys(jsonValues)) {
|
|
200
|
+
try {
|
|
201
|
+
const value = this.transformer
|
|
202
|
+
? this.transformer(jsonValues[key])
|
|
203
|
+
: (jsonValues[key] as V);
|
|
204
|
+
if (value !== undefined) {
|
|
205
|
+
values[key] = value;
|
|
206
|
+
}
|
|
207
|
+
} catch {
|
|
208
|
+
// Do nothing
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
this.clear();
|
|
212
|
+
if (initialValues) {
|
|
213
|
+
this.putAll(initialValues);
|
|
214
|
+
}
|
|
215
|
+
this.putAll(values);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
public async store(values: Record<string, V> = this.cache): Promise<void> {
|
|
219
|
+
await this.storage.put(this.namespace, JSON.stringify(values));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export const transformVariantFromStorage = (
|
|
224
|
+
storageValue: unknown,
|
|
225
|
+
): Variant | undefined => {
|
|
226
|
+
if (typeof storageValue === "string") {
|
|
227
|
+
// From v0 string format
|
|
228
|
+
return {
|
|
229
|
+
key: storageValue,
|
|
230
|
+
value: storageValue,
|
|
231
|
+
};
|
|
232
|
+
} else if (typeof storageValue === "object" && storageValue !== null) {
|
|
233
|
+
// From v1 or v2 object format
|
|
234
|
+
const variantRecord = storageValue as Record<string, unknown>;
|
|
235
|
+
const key = variantRecord.key;
|
|
236
|
+
const value = variantRecord.value;
|
|
237
|
+
const payload = variantRecord.payload;
|
|
238
|
+
const rawMetadata = variantRecord.metadata;
|
|
239
|
+
let metadata =
|
|
240
|
+
rawMetadata && typeof rawMetadata === "object"
|
|
241
|
+
? ({ ...rawMetadata } as Record<string, unknown>)
|
|
242
|
+
: undefined;
|
|
243
|
+
let experimentKey =
|
|
244
|
+
typeof variantRecord.expKey === "string"
|
|
245
|
+
? variantRecord.expKey
|
|
246
|
+
: undefined;
|
|
247
|
+
const metadataExperimentKey =
|
|
248
|
+
metadata && typeof metadata.experimentKey === "string"
|
|
249
|
+
? metadata.experimentKey
|
|
250
|
+
: undefined;
|
|
251
|
+
|
|
252
|
+
if (metadataExperimentKey) {
|
|
253
|
+
experimentKey = metadataExperimentKey;
|
|
254
|
+
} else if (experimentKey) {
|
|
255
|
+
metadata = metadata || {};
|
|
256
|
+
metadata.experimentKey = experimentKey;
|
|
257
|
+
}
|
|
258
|
+
const variant: Variant = {};
|
|
259
|
+
if (typeof key === "string") {
|
|
260
|
+
variant.key = key;
|
|
261
|
+
} else if (typeof value === "string") {
|
|
262
|
+
variant.key = value;
|
|
263
|
+
}
|
|
264
|
+
if (typeof value === "string") variant.value = value;
|
|
265
|
+
if (metadata) variant.metadata = metadata;
|
|
266
|
+
if (payload) variant.payload = payload;
|
|
267
|
+
if (experimentKey) variant.expKey = experimentKey;
|
|
268
|
+
return variant;
|
|
269
|
+
}
|
|
270
|
+
return undefined;
|
|
271
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Storage } from "../types/storage";
|
|
2
|
+
|
|
3
|
+
export class MemoryStorage implements Storage {
|
|
4
|
+
private static readonly memoryStorage = new Map<string, string>();
|
|
5
|
+
|
|
6
|
+
async get(key: string): Promise<string | null> {
|
|
7
|
+
return MemoryStorage.memoryStorage.get(key) ?? null;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async put(key: string, value: string): Promise<void> {
|
|
11
|
+
MemoryStorage.memoryStorage.set(key, value);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async delete(key: string): Promise<void> {
|
|
15
|
+
MemoryStorage.memoryStorage.delete(key);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async reset(): Promise<void> {
|
|
19
|
+
MemoryStorage.memoryStorage.clear();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class LocalStorage extends MemoryStorage {}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Client, FetchOptions } from "./types/client";
|
|
2
|
+
import { Defaults } from "./types/config";
|
|
3
|
+
import { ExperimentUser, ExperimentUserProvider } from "./types/user";
|
|
4
|
+
import { Variant, Variants } from "./types/variant";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A stub {@link Client} implementation that does nothing for all methods
|
|
8
|
+
*/
|
|
9
|
+
export class StubExperimentClient implements Client {
|
|
10
|
+
public getUser(): ExperimentUser {
|
|
11
|
+
return {};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public async start(_user?: ExperimentUser): Promise<void> {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public stop(): void {}
|
|
19
|
+
|
|
20
|
+
public setUser(_user: ExperimentUser): void {}
|
|
21
|
+
|
|
22
|
+
public async fetch(
|
|
23
|
+
_user?: ExperimentUser,
|
|
24
|
+
_options?: FetchOptions,
|
|
25
|
+
): Promise<StubExperimentClient> {
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public async fetchOrThrow(
|
|
30
|
+
_user?: ExperimentUser,
|
|
31
|
+
_options?: FetchOptions,
|
|
32
|
+
): Promise<StubExperimentClient> {
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public getUserProvider(): ExperimentUserProvider {
|
|
37
|
+
return {
|
|
38
|
+
async getUser(): Promise<ExperimentUser> {
|
|
39
|
+
return {};
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public setUserProvider(
|
|
45
|
+
_userProvider: ExperimentUserProvider,
|
|
46
|
+
): StubExperimentClient {
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public variant(_key: string, _fallback?: string | Variant): Variant {
|
|
51
|
+
return Defaults.fallbackVariant ?? {};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public all(): Variants {
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public clear(): void {}
|
|
59
|
+
|
|
60
|
+
public exposure(_key: string): void {}
|
|
61
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
safeGlobal,
|
|
8
|
+
HttpClient as CoreHttpClient,
|
|
9
|
+
HttpRequest,
|
|
10
|
+
HttpResponse,
|
|
11
|
+
} from "@amplitude/experiment-core";
|
|
12
|
+
import unfetch from "unfetch";
|
|
13
|
+
|
|
14
|
+
import { HttpClient, SimpleResponse } from "../types/transport";
|
|
15
|
+
|
|
16
|
+
const getFetch = () => safeGlobal.fetch || unfetch;
|
|
17
|
+
|
|
18
|
+
type AbortControllerLike = {
|
|
19
|
+
signal: AbortSignal;
|
|
20
|
+
abort(): void;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type GlobalScopeWithAbortController = typeof globalThis & {
|
|
24
|
+
AbortController?: new () => AbortControllerLike;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const getAbortController = (): AbortControllerLike | undefined => {
|
|
28
|
+
const scope = safeGlobal as GlobalScopeWithAbortController;
|
|
29
|
+
return typeof scope.AbortController === "function"
|
|
30
|
+
? new scope.AbortController()
|
|
31
|
+
: undefined;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const timeout = (
|
|
35
|
+
promise: Promise<SimpleResponse>,
|
|
36
|
+
timeoutMillis?: number,
|
|
37
|
+
abortController?: AbortControllerLike,
|
|
38
|
+
): Promise<SimpleResponse> => {
|
|
39
|
+
if (timeoutMillis == null || timeoutMillis <= 0) {
|
|
40
|
+
return promise;
|
|
41
|
+
}
|
|
42
|
+
return new Promise(function (resolve, reject) {
|
|
43
|
+
const timeoutHandle = safeGlobal.setTimeout(function () {
|
|
44
|
+
abortController?.abort();
|
|
45
|
+
reject(Error("Request timeout after " + timeoutMillis + " milliseconds"));
|
|
46
|
+
}, timeoutMillis);
|
|
47
|
+
promise.then(
|
|
48
|
+
(value) => {
|
|
49
|
+
safeGlobal.clearTimeout(timeoutHandle);
|
|
50
|
+
resolve(value);
|
|
51
|
+
},
|
|
52
|
+
(error) => {
|
|
53
|
+
safeGlobal.clearTimeout(timeoutHandle);
|
|
54
|
+
reject(error);
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const _request = (
|
|
61
|
+
requestUrl: string,
|
|
62
|
+
method: string,
|
|
63
|
+
headers: Record<string, string>,
|
|
64
|
+
data: string,
|
|
65
|
+
timeoutMillis?: number,
|
|
66
|
+
): Promise<SimpleResponse> => {
|
|
67
|
+
const abortController = getAbortController();
|
|
68
|
+
const call = async () => {
|
|
69
|
+
const response = await getFetch()(requestUrl, {
|
|
70
|
+
method: method,
|
|
71
|
+
headers: headers,
|
|
72
|
+
body: data,
|
|
73
|
+
signal: abortController?.signal,
|
|
74
|
+
});
|
|
75
|
+
const simpleResponse: SimpleResponse = {
|
|
76
|
+
status: response.status,
|
|
77
|
+
body: await response.text(),
|
|
78
|
+
};
|
|
79
|
+
return simpleResponse;
|
|
80
|
+
};
|
|
81
|
+
return timeout(call(), timeoutMillis, abortController);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Wrap the exposed HttpClient in a CoreClient implementation to work with
|
|
86
|
+
* FlagsApi and EvaluationApi.
|
|
87
|
+
*/
|
|
88
|
+
export class WrapperClient implements CoreHttpClient {
|
|
89
|
+
private readonly client: HttpClient;
|
|
90
|
+
constructor(client: HttpClient) {
|
|
91
|
+
this.client = client;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async request(request: HttpRequest): Promise<HttpResponse> {
|
|
95
|
+
return await this.client.request(
|
|
96
|
+
request.requestUrl,
|
|
97
|
+
request.method,
|
|
98
|
+
request.headers,
|
|
99
|
+
null,
|
|
100
|
+
request.timeoutMillis,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const FetchHttpClient: HttpClient = { request: _request };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ExperimentUser, ExperimentUserProvider } from "./user";
|
|
2
|
+
import { Variant, Variants } from "./variant";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Interface for the main client.
|
|
6
|
+
* @category Core Usage
|
|
7
|
+
*/
|
|
8
|
+
export interface Client {
|
|
9
|
+
start(user?: ExperimentUser): Promise<void>;
|
|
10
|
+
stop(): void;
|
|
11
|
+
fetch(user?: ExperimentUser, options?: FetchOptions): Promise<Client>;
|
|
12
|
+
fetchOrThrow(user?: ExperimentUser, options?: FetchOptions): Promise<Client>;
|
|
13
|
+
variant(key: string, fallback?: string | Variant): Variant;
|
|
14
|
+
all(): Variants;
|
|
15
|
+
clear(): void;
|
|
16
|
+
exposure(key: string): void;
|
|
17
|
+
getUser(): ExperimentUser;
|
|
18
|
+
setUser(user: ExperimentUser): void;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated use ExperimentConfig.userProvider instead
|
|
22
|
+
*/
|
|
23
|
+
getUserProvider(): ExperimentUserProvider;
|
|
24
|
+
/**
|
|
25
|
+
* @deprecated use ExperimentConfig.userProvider instead
|
|
26
|
+
*/
|
|
27
|
+
setUserProvider(userProvider: ExperimentUserProvider): Client;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Options to modify the behavior of a remote evaluation fetch request.
|
|
32
|
+
*/
|
|
33
|
+
export type FetchOptions = {
|
|
34
|
+
/**
|
|
35
|
+
* Specific flag keys to evaluate and set variants for.
|
|
36
|
+
*/
|
|
37
|
+
flagKeys?: string[];
|
|
38
|
+
};
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { nitroHttpClient } from "../../native/http";
|
|
2
|
+
import { NitroMemoryStorage } from "../../native/storage";
|
|
3
|
+
|
|
4
|
+
import { ExposureTrackingProvider } from "./exposure";
|
|
5
|
+
import { Logger, LogLevel } from "./logger";
|
|
6
|
+
import { Source } from "./source";
|
|
7
|
+
import { Storage } from "./storage";
|
|
8
|
+
import { HttpClient } from "./transport";
|
|
9
|
+
import { ExperimentUserProvider } from "./user";
|
|
10
|
+
import { Variant, Variants } from "./variant";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @category Configuration
|
|
14
|
+
*/
|
|
15
|
+
export interface ExperimentConfig {
|
|
16
|
+
/**
|
|
17
|
+
* Debug all assignment requests in the UI Debugger and log additional
|
|
18
|
+
* information to the console. This should be false for production builds.
|
|
19
|
+
* @deprecated Use logLevel instead. When debug is true, it sets logLevel to Debug.
|
|
20
|
+
*/
|
|
21
|
+
debug?: boolean;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The minimum log level to output. Messages below this level will be ignored.
|
|
25
|
+
* Supported levels: Disable, Error, Warn, Info, Debug, Verbose.
|
|
26
|
+
* If the deprecated debug flag is set to true, this will be set to Debug.
|
|
27
|
+
*/
|
|
28
|
+
logLevel?: LogLevel;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Custom logger implementation. If not provided, a default ConsoleLogger will be used.
|
|
32
|
+
* The logger must implement the Logger interface with methods for error, warn, info, debug, and verbose.
|
|
33
|
+
*/
|
|
34
|
+
loggerProvider?: Logger | null;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The name of the instance being initialized. Used for initializing separate
|
|
38
|
+
* instances of experiment or linking the experiment SDK to a specific
|
|
39
|
+
* instance of the amplitude analytics SDK.
|
|
40
|
+
*/
|
|
41
|
+
instanceName?: string;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The default fallback variant for all {@link ExperimentClient.variant}
|
|
45
|
+
* calls.
|
|
46
|
+
*/
|
|
47
|
+
fallbackVariant?: Variant;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Initial values for variants. This is useful for bootstrapping the
|
|
51
|
+
* client with fallbacks and values evaluated from server-side rendering.
|
|
52
|
+
* @see Variants
|
|
53
|
+
*/
|
|
54
|
+
initialVariants?: Variants;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Initial values for flags. This is useful for bootstrapping the
|
|
58
|
+
* client with fallbacks for flag configs.
|
|
59
|
+
*/
|
|
60
|
+
initialFlags?: string;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Determines the primary source of variants and variants before falling back.
|
|
64
|
+
* @see Source
|
|
65
|
+
*/
|
|
66
|
+
source?: Source;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The domain from which to request variants using remote evaluation.
|
|
70
|
+
*/
|
|
71
|
+
serverUrl?: string;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The domain to request flag configurations used in local evaluation from.
|
|
75
|
+
*/
|
|
76
|
+
flagsServerUrl?: string;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The amplitude data center to fetch flags and variants from. If set,
|
|
80
|
+
* automatically sets the {@link serverUrl} and {@link flagsServerUrl}
|
|
81
|
+
* configurations.
|
|
82
|
+
*/
|
|
83
|
+
serverZone?: "US" | "EU";
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The request timeout, in milliseconds, when fetching variants.
|
|
87
|
+
*/
|
|
88
|
+
fetchTimeoutMillis?: number;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Set to true to retry fetch requests in the background if the initial
|
|
92
|
+
* requests fails or times out.
|
|
93
|
+
*/
|
|
94
|
+
retryFetchOnFailure?: boolean;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* If true, automatically tracks exposure events though the
|
|
98
|
+
* `ExperimentAnalyticsProvider`. If no analytics provider is set, this
|
|
99
|
+
* option does nothing.
|
|
100
|
+
*/
|
|
101
|
+
automaticExposureTracking?: boolean;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Enable or disable local evaluation flag configuration polling on `start()`.
|
|
105
|
+
*/
|
|
106
|
+
pollOnStart?: boolean;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Explicitly enable or disable calling {@link fetch()} on {@link start()}:
|
|
110
|
+
*
|
|
111
|
+
* - `true`: fetch will always be called on start.
|
|
112
|
+
* - `false`: fetch will never be called on start.
|
|
113
|
+
* - `undefined`: fetch will always be called on start.
|
|
114
|
+
*/
|
|
115
|
+
fetchOnStart?: boolean;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* This config only matters if you are using the amplitude analytics SDK
|
|
119
|
+
* integration initialized by calling
|
|
120
|
+
* `Experiment.initializeWithAmplitudeAnalytics()`.
|
|
121
|
+
*
|
|
122
|
+
* If true, the `ExperimentClient` will automatically fetch variants when the
|
|
123
|
+
* user's identity changes. The user's identity includes user_id, device_id
|
|
124
|
+
* and any user properties which are `set`, `unset` or `clearAll`ed via a call
|
|
125
|
+
* to `identify()`.
|
|
126
|
+
*
|
|
127
|
+
* Note: Non-idempotent identify operations `setOnce`, `add`, `append`, and
|
|
128
|
+
* `prepend` are not counted towards the user identity changing.
|
|
129
|
+
*/
|
|
130
|
+
automaticFetchOnAmplitudeIdentityChange?: boolean;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Sets a user provider that will inject identity information into the user
|
|
134
|
+
* for {@link fetch()} requests. The user provider will only set user fields
|
|
135
|
+
* in outgoing requests which are null or undefined.
|
|
136
|
+
*
|
|
137
|
+
* See {@link ExperimentUserProvider} for more details
|
|
138
|
+
*/
|
|
139
|
+
userProvider?: ExperimentUserProvider | null;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Provides the ability to track exposure events through a 3rd party analytics
|
|
143
|
+
* implementation.
|
|
144
|
+
*/
|
|
145
|
+
exposureTrackingProvider?: ExposureTrackingProvider | null;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* (Advanced) Use your own http client.
|
|
149
|
+
*/
|
|
150
|
+
httpClient?: HttpClient;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* (Advanced) Use your own storage implementation.
|
|
154
|
+
* If not provided, the client will use the built-in shared memory storage implementation.
|
|
155
|
+
*/
|
|
156
|
+
storage?: Storage | null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
Defaults for Experiment Config options
|
|
161
|
+
|
|
162
|
+
| **Option** | **Default** |
|
|
163
|
+
|------------------|-----------------------------------|
|
|
164
|
+
| **debug** | `false` |
|
|
165
|
+
| **logLevel** | `LogLevel.Error` |
|
|
166
|
+
| **logger** | `null` (ConsoleLogger will be used) |
|
|
167
|
+
| **instanceName** | `$default_instance` |
|
|
168
|
+
| **fallbackVariant** | `null` |
|
|
169
|
+
| **initialVariants** | `null` |
|
|
170
|
+
| **initialFlags** | `undefined` |
|
|
171
|
+
| **source** | `Source.LocalStorage` |
|
|
172
|
+
| **serverUrl** | `"https://api.lab.amplitude.com"` |
|
|
173
|
+
| **flagsServerUrl** | `"https://flag.lab.amplitude.com"` |
|
|
174
|
+
| **serverZone** | `"US"` |
|
|
175
|
+
| **assignmentTimeoutMillis** | `10000` |
|
|
176
|
+
| **retryFailedAssignment** | `true` |
|
|
177
|
+
| **automaticExposureTracking** | `true` |
|
|
178
|
+
| **pollOnStart** | `true` |
|
|
179
|
+
| **fetchOnStart** | `true` |
|
|
180
|
+
| **automaticFetchOnAmplitudeIdentityChange** | `false` |
|
|
181
|
+
| **userProvider** | `null` |
|
|
182
|
+
| **analyticsProvider** | `null` |
|
|
183
|
+
| **exposureTrackingProvider** | `null` |
|
|
184
|
+
|
|
185
|
+
*
|
|
186
|
+
* @category Configuration
|
|
187
|
+
*/
|
|
188
|
+
export const Defaults: ExperimentConfig = {
|
|
189
|
+
debug: false,
|
|
190
|
+
logLevel: LogLevel.Error,
|
|
191
|
+
loggerProvider: null,
|
|
192
|
+
instanceName: "$default_instance",
|
|
193
|
+
fallbackVariant: {},
|
|
194
|
+
initialVariants: {},
|
|
195
|
+
initialFlags: undefined,
|
|
196
|
+
source: Source.LocalStorage,
|
|
197
|
+
serverUrl: "https://api.lab.amplitude.com",
|
|
198
|
+
flagsServerUrl: "https://flag.lab.amplitude.com",
|
|
199
|
+
serverZone: "US",
|
|
200
|
+
fetchTimeoutMillis: 10000,
|
|
201
|
+
retryFetchOnFailure: true,
|
|
202
|
+
automaticExposureTracking: true,
|
|
203
|
+
pollOnStart: true,
|
|
204
|
+
fetchOnStart: true,
|
|
205
|
+
automaticFetchOnAmplitudeIdentityChange: false,
|
|
206
|
+
userProvider: null,
|
|
207
|
+
exposureTrackingProvider: null,
|
|
208
|
+
httpClient: nitroHttpClient,
|
|
209
|
+
storage: new NitroMemoryStorage("experiment"),
|
|
210
|
+
};
|