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,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event object for tracking exposures to Amplitude Experiment.
|
|
3
|
+
*
|
|
4
|
+
* This object contains all the required information to send an `$exposure`
|
|
5
|
+
* event through any SDK or CDP to experiment.
|
|
6
|
+
*
|
|
7
|
+
* The resulting exposure event must follow the following definition:
|
|
8
|
+
* ```
|
|
9
|
+
* {
|
|
10
|
+
* "event_type": "$exposure",
|
|
11
|
+
* "event_properties": {
|
|
12
|
+
* "flag_key": "<flagKey>",
|
|
13
|
+
* "variant": "<variant>",
|
|
14
|
+
* "experiment_key": "<expKey>"
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Where `<flagKey>`, `<variant>`, and `<expKey>` are the {@link flag_key},
|
|
20
|
+
* {@link variant}, and {@link experiment_key} variant members on this type:
|
|
21
|
+
*
|
|
22
|
+
* For example, if you're using Segment for analytics:
|
|
23
|
+
*
|
|
24
|
+
* ```
|
|
25
|
+
* analytics.track('$exposure', exposure)
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export type Exposure = {
|
|
29
|
+
/**
|
|
30
|
+
* (Required) The key for the flag the user was exposed to.
|
|
31
|
+
*/
|
|
32
|
+
flag_key: string;
|
|
33
|
+
/**
|
|
34
|
+
* (Optional) The variant the user was exposed to. If null or missing, the
|
|
35
|
+
* event will not be persisted, and will unset the user property.
|
|
36
|
+
*/
|
|
37
|
+
variant?: string;
|
|
38
|
+
/**
|
|
39
|
+
* (Optional) The experiment key used to differentiate between multiple
|
|
40
|
+
* experiments associated with the same flag.
|
|
41
|
+
*/
|
|
42
|
+
experiment_key?: string;
|
|
43
|
+
/**
|
|
44
|
+
* (Optional) Flag, segment, and variant metadata produced as a result of
|
|
45
|
+
* evaluation for the user. Used for system purposes.
|
|
46
|
+
*/
|
|
47
|
+
metadata?: Record<string, unknown>;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Interface for enabling tracking {@link Exposure}s through the
|
|
52
|
+
* {@link ExperimentClient}.
|
|
53
|
+
*
|
|
54
|
+
* If you're using the Amplitude Analytics SDK for tracking you do not need
|
|
55
|
+
* to implement this interface. Simply initialize experiment using the
|
|
56
|
+
* {@link Experiment.initializeWithAmplitudeAnalytics} function.
|
|
57
|
+
*
|
|
58
|
+
* If you're using a 3rd party analytics implementation then you'll need to
|
|
59
|
+
* implement the sending of the analytics event yourself. The implementation
|
|
60
|
+
* should result in the following event getting sent to amplitude:
|
|
61
|
+
*
|
|
62
|
+
* ```
|
|
63
|
+
* {
|
|
64
|
+
* "event_type": "$exposure",
|
|
65
|
+
* "event_properties": {
|
|
66
|
+
* "flag_key": "<flagKey>",
|
|
67
|
+
* "variant": "<variant>",
|
|
68
|
+
* "experiment_key": "<expKey>"
|
|
69
|
+
* }
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* For example, if you're using Segment for analytics:
|
|
74
|
+
*
|
|
75
|
+
* ```
|
|
76
|
+
* analytics.track('$exposure', exposure)
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export interface ExposureTrackingProvider {
|
|
80
|
+
/**
|
|
81
|
+
* Called when the {@link ExperimentClient} intends to track an exposure event;
|
|
82
|
+
* either when {@link ExperimentClient.variant} serves a variant (and
|
|
83
|
+
* {@link ExperimentConfig.automaticExposureTracking} is `true`) or if
|
|
84
|
+
* {@link ExperimentClient.exposure} is called.
|
|
85
|
+
*
|
|
86
|
+
* The implementation should result in the following event getting sent to
|
|
87
|
+
* amplitude:
|
|
88
|
+
*
|
|
89
|
+
* ```
|
|
90
|
+
* {
|
|
91
|
+
* "event_type": "$exposure",
|
|
92
|
+
* "event_properties": {
|
|
93
|
+
* "flag_key": "<flagKey>",
|
|
94
|
+
* "variant": "<variant>",
|
|
95
|
+
* "experiment_key": "<expKey>"
|
|
96
|
+
* }
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* For example, if you're using Segment for analytics:
|
|
101
|
+
*
|
|
102
|
+
* ```
|
|
103
|
+
* analytics.track('$exposure', exposure)
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
track(exposure: Exposure): void;
|
|
107
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log level enumeration for controlling logging verbosity.
|
|
3
|
+
* @category Logging
|
|
4
|
+
*/
|
|
5
|
+
export enum LogLevel {
|
|
6
|
+
/**
|
|
7
|
+
* Disable all logging
|
|
8
|
+
*/
|
|
9
|
+
Disable = 0,
|
|
10
|
+
/**
|
|
11
|
+
* Error level logging - only critical errors
|
|
12
|
+
*/
|
|
13
|
+
Error = 1,
|
|
14
|
+
/**
|
|
15
|
+
* Warning level logging - errors and warnings
|
|
16
|
+
*/
|
|
17
|
+
Warn = 2,
|
|
18
|
+
/**
|
|
19
|
+
* Info level logging - errors, warnings, and informational messages
|
|
20
|
+
*/
|
|
21
|
+
Info = 3,
|
|
22
|
+
/**
|
|
23
|
+
* Debug level logging - errors, warnings, info, and debug messages
|
|
24
|
+
*/
|
|
25
|
+
Debug = 4,
|
|
26
|
+
/**
|
|
27
|
+
* Verbose level logging - all messages including verbose details
|
|
28
|
+
*/
|
|
29
|
+
Verbose = 5,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Logger interface that can be implemented to provide custom logging.
|
|
34
|
+
* @category Logging
|
|
35
|
+
*/
|
|
36
|
+
export interface Logger {
|
|
37
|
+
/**
|
|
38
|
+
* Log an error message
|
|
39
|
+
* @param message The message to log
|
|
40
|
+
* @param optionalParams Additional parameters to log
|
|
41
|
+
*/
|
|
42
|
+
error(message?: any, ...optionalParams: any[]): void;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Log a warning message
|
|
46
|
+
* @param message The message to log
|
|
47
|
+
* @param optionalParams Additional parameters to log
|
|
48
|
+
*/
|
|
49
|
+
warn(message?: any, ...optionalParams: any[]): void;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Log an informational message
|
|
53
|
+
* @param message The message to log
|
|
54
|
+
* @param optionalParams Additional parameters to log
|
|
55
|
+
*/
|
|
56
|
+
info(message?: any, ...optionalParams: any[]): void;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Log a debug message
|
|
60
|
+
* @param message The message to log
|
|
61
|
+
* @param optionalParams Additional parameters to log
|
|
62
|
+
*/
|
|
63
|
+
debug(message?: any, ...optionalParams: any[]): void;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Log a verbose message
|
|
67
|
+
* @param message The message to log
|
|
68
|
+
* @param optionalParams Additional parameters to log
|
|
69
|
+
*/
|
|
70
|
+
verbose(message?: any, ...optionalParams: any[]): void;
|
|
71
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines the primary source of variants before falling back.
|
|
3
|
+
*
|
|
4
|
+
* @category Source
|
|
5
|
+
*/
|
|
6
|
+
export enum Source {
|
|
7
|
+
/**
|
|
8
|
+
* The default way to source variants within your application. Before the
|
|
9
|
+
* assignments are fetched, `getVariant(s)` will fallback to local storage
|
|
10
|
+
* first, then `initialVariants` if local storage is empty. This option
|
|
11
|
+
* effectively falls back to an assignment fetched previously.
|
|
12
|
+
*/
|
|
13
|
+
LocalStorage = "localStorage",
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* This bootstrap option is used primarily for servers-side rendering using an
|
|
17
|
+
* Experiment server SDK. This bootstrap option always prefers the config
|
|
18
|
+
* `initialVariants` over data in local storage, even if variants are fetched
|
|
19
|
+
* successfully and stored locally.
|
|
20
|
+
*/
|
|
21
|
+
InitialVariants = "initialVariants",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Indicates from which source the variant() function determines the variant
|
|
26
|
+
*
|
|
27
|
+
* @category Source
|
|
28
|
+
*/
|
|
29
|
+
export enum VariantSource {
|
|
30
|
+
LocalStorage = "storage",
|
|
31
|
+
InitialVariants = "initial",
|
|
32
|
+
SecondaryLocalStorage = "secondary-storage",
|
|
33
|
+
SecondaryInitialVariants = "secondary-initial",
|
|
34
|
+
FallbackInline = "fallback-inline",
|
|
35
|
+
FallbackConfig = "fallback-config",
|
|
36
|
+
LocalEvaluation = "local-evaluation",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Returns true if the VariantSource is one of the fallbacks (inline or config)
|
|
41
|
+
*
|
|
42
|
+
* @param source a {@link VariantSource}
|
|
43
|
+
* @returns true if source is {@link VariantSource.FallbackInline} or {@link VariantSource.FallbackConfig}
|
|
44
|
+
*/
|
|
45
|
+
export const isFallback = (source: VariantSource | undefined): boolean => {
|
|
46
|
+
return (
|
|
47
|
+
!source ||
|
|
48
|
+
source === VariantSource.FallbackInline ||
|
|
49
|
+
source === VariantSource.FallbackConfig ||
|
|
50
|
+
source === VariantSource.SecondaryInitialVariants
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface SimpleResponse {
|
|
2
|
+
status: number;
|
|
3
|
+
body: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface HttpClient {
|
|
7
|
+
request(
|
|
8
|
+
requestUrl: string,
|
|
9
|
+
method: string,
|
|
10
|
+
headers: Record<string, string>,
|
|
11
|
+
data: string | null,
|
|
12
|
+
timeoutMillis?: number,
|
|
13
|
+
): Promise<SimpleResponse>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines a user context for evaluation.
|
|
3
|
+
* `device_id` and `user_id` are used for identity resolution.
|
|
4
|
+
* All other predefined fields and user properties are used for
|
|
5
|
+
* rule based user targeting.
|
|
6
|
+
* @category Types
|
|
7
|
+
*/
|
|
8
|
+
export type ExperimentUser = {
|
|
9
|
+
/**
|
|
10
|
+
* Device ID for associating with an identity in Amplitude
|
|
11
|
+
*/
|
|
12
|
+
device_id?: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* User ID for associating with an identity in Amplitude
|
|
16
|
+
*/
|
|
17
|
+
user_id?: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Predefined field, can be manually provided
|
|
21
|
+
*/
|
|
22
|
+
country?: string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Predefined field, can be manually provided
|
|
26
|
+
*/
|
|
27
|
+
city?: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Predefined field, can be manually provided
|
|
31
|
+
*/
|
|
32
|
+
region?: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Predefined field, can be manually provided
|
|
36
|
+
*/
|
|
37
|
+
dma?: string;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Predefined field, auto populated via a ExperimentUserProvider
|
|
41
|
+
* or can be manually provided
|
|
42
|
+
*/
|
|
43
|
+
language?: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Predefined field, auto populated via a ExperimentUserProvider
|
|
47
|
+
* or can be manually provided
|
|
48
|
+
*/
|
|
49
|
+
platform?: string;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Predefined field, auto populated via a ExperimentUserProvider
|
|
53
|
+
* or can be manually provided
|
|
54
|
+
*/
|
|
55
|
+
version?: string;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Predefined field, auto populated via a ExperimentUserProvider
|
|
59
|
+
* or can be manually provided
|
|
60
|
+
*/
|
|
61
|
+
os?: string;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Predefined field, auto populated via a ExperimentUserProvider
|
|
65
|
+
* or can be manually provided
|
|
66
|
+
*/
|
|
67
|
+
device_model?: string;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Predefined field, auto populated via a ExperimentUserProvider
|
|
71
|
+
* or can be manually provided
|
|
72
|
+
*/
|
|
73
|
+
device_brand?: string;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Predefined field, auto populated via a ExperimentUserProvider
|
|
77
|
+
* or can be manually provided
|
|
78
|
+
*/
|
|
79
|
+
device_manufacturer?: string;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Predefined field, can be manually provided
|
|
83
|
+
*/
|
|
84
|
+
carrier?: string;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Predefined field, auto populated, can be manually overridden
|
|
88
|
+
*/
|
|
89
|
+
library?: string;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Predefined field, can be manually provided
|
|
93
|
+
*/
|
|
94
|
+
ip_address?: string;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Custom user properties
|
|
98
|
+
*/
|
|
99
|
+
user_properties?: {
|
|
100
|
+
[propertyName: string]:
|
|
101
|
+
| string
|
|
102
|
+
| number
|
|
103
|
+
| boolean
|
|
104
|
+
| (string | number | boolean)[];
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
groups?: {
|
|
108
|
+
[groupType: string]: string[];
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
group_properties?: {
|
|
112
|
+
[groupType: string]: {
|
|
113
|
+
[groupName: string]: {
|
|
114
|
+
[propertyName: string]:
|
|
115
|
+
| string
|
|
116
|
+
| number
|
|
117
|
+
| boolean
|
|
118
|
+
| (string | number | boolean)[];
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* An ExperimentUserProvider injects information into the {@link ExperimentUser}
|
|
126
|
+
* object before sending a request to the server. This can be used to pass
|
|
127
|
+
* identity (deviceId and userId), or other platform specific context.
|
|
128
|
+
* @category Provider
|
|
129
|
+
*/
|
|
130
|
+
export interface ExperimentUserProvider {
|
|
131
|
+
getUser(): Promise<ExperimentUser>;
|
|
132
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category Types
|
|
3
|
+
*/
|
|
4
|
+
export type Variant = {
|
|
5
|
+
/**
|
|
6
|
+
* The key of the variant.
|
|
7
|
+
*/
|
|
8
|
+
key?: string;
|
|
9
|
+
/**
|
|
10
|
+
* The value of the variant.
|
|
11
|
+
*/
|
|
12
|
+
value?: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The attached payload, if any.
|
|
16
|
+
*/
|
|
17
|
+
payload?: any;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The experiment key. Used to distinguish two experiments associated with the same flag.
|
|
21
|
+
*/
|
|
22
|
+
expKey?: string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Flag, segment, and variant metadata produced as a result of
|
|
26
|
+
* evaluation for the user. Used for system purposes.
|
|
27
|
+
*/
|
|
28
|
+
metadata?: Record<string, unknown>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @category Types
|
|
33
|
+
*/
|
|
34
|
+
export type Variants = {
|
|
35
|
+
[key: string]: Variant;
|
|
36
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { safeGlobal } from "@amplitude/experiment-core";
|
|
2
|
+
|
|
3
|
+
export class Backoff {
|
|
4
|
+
private readonly attempts: number;
|
|
5
|
+
private readonly min: number;
|
|
6
|
+
private readonly max: number;
|
|
7
|
+
private readonly scalar: number;
|
|
8
|
+
|
|
9
|
+
private started = false;
|
|
10
|
+
private done = false;
|
|
11
|
+
|
|
12
|
+
private timeoutHandle: ReturnType<typeof safeGlobal.setTimeout> | undefined;
|
|
13
|
+
|
|
14
|
+
public constructor(
|
|
15
|
+
attempts: number,
|
|
16
|
+
min: number,
|
|
17
|
+
max: number,
|
|
18
|
+
scalar: number,
|
|
19
|
+
) {
|
|
20
|
+
this.attempts = attempts;
|
|
21
|
+
this.min = min;
|
|
22
|
+
this.max = max;
|
|
23
|
+
this.scalar = scalar;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public start(fn: () => Promise<void>): void {
|
|
27
|
+
if (!this.started) {
|
|
28
|
+
this.started = true;
|
|
29
|
+
} else {
|
|
30
|
+
throw Error("Backoff already started");
|
|
31
|
+
}
|
|
32
|
+
this.backoff(fn, 0, this.min);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public cancel(): void {
|
|
36
|
+
this.done = true;
|
|
37
|
+
if (this.timeoutHandle != null) {
|
|
38
|
+
safeGlobal.clearTimeout(this.timeoutHandle);
|
|
39
|
+
this.timeoutHandle = undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private backoff(
|
|
44
|
+
fn: () => Promise<void>,
|
|
45
|
+
attempt: number,
|
|
46
|
+
delay: number,
|
|
47
|
+
): void {
|
|
48
|
+
if (this.done) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.timeoutHandle = safeGlobal.setTimeout(async () => {
|
|
52
|
+
try {
|
|
53
|
+
this.timeoutHandle = undefined;
|
|
54
|
+
await fn();
|
|
55
|
+
this.done = true;
|
|
56
|
+
} catch (e) {
|
|
57
|
+
const nextAttempt = attempt + 1;
|
|
58
|
+
if (!this.done && nextAttempt < this.attempts) {
|
|
59
|
+
const nextDelay = Math.min(delay * this.scalar, this.max);
|
|
60
|
+
this.backoff(fn, nextAttempt, nextDelay);
|
|
61
|
+
} else {
|
|
62
|
+
this.done = true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}, delay);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as base64 from "base64-js";
|
|
2
|
+
|
|
3
|
+
export const stringToUtf8Array = (s: string): number[] => {
|
|
4
|
+
const utf8 = unescape(encodeURIComponent(s));
|
|
5
|
+
const arr = [];
|
|
6
|
+
for (let i = 0; i < utf8.length; i++) {
|
|
7
|
+
arr.push(utf8.charCodeAt(i));
|
|
8
|
+
}
|
|
9
|
+
return arr;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const urlSafeBase64Encode = (s: string): string => {
|
|
13
|
+
const base64encoded = base64.fromByteArray(
|
|
14
|
+
new Uint8Array(stringToUtf8Array(s)),
|
|
15
|
+
);
|
|
16
|
+
return base64encoded
|
|
17
|
+
.replace(/[=]/g, "")
|
|
18
|
+
.replace(/\+/g, "-")
|
|
19
|
+
.replace(/\//g, "_");
|
|
20
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { EvaluationVariant } from "@amplitude/experiment-core";
|
|
2
|
+
|
|
3
|
+
import { ExperimentUser } from "../types/user";
|
|
4
|
+
import { Variant } from "../types/variant";
|
|
5
|
+
|
|
6
|
+
export const convertUserToContext = (
|
|
7
|
+
user: ExperimentUser | undefined,
|
|
8
|
+
): Record<string, unknown> => {
|
|
9
|
+
if (!user) {
|
|
10
|
+
return {};
|
|
11
|
+
}
|
|
12
|
+
const contextUser: ExperimentUser = { ...user };
|
|
13
|
+
const context: Record<string, unknown> = { user: contextUser };
|
|
14
|
+
const groups: Record<string, Record<string, unknown>> = {};
|
|
15
|
+
if (!user.groups) {
|
|
16
|
+
return context;
|
|
17
|
+
}
|
|
18
|
+
for (const groupType of Object.keys(user.groups)) {
|
|
19
|
+
const groupNames: string[] = user.groups[groupType] ?? [];
|
|
20
|
+
if (groupNames.length > 0 && groupNames[0]) {
|
|
21
|
+
const groupName = groupNames[0];
|
|
22
|
+
const groupNameMap: Record<string, unknown> = {
|
|
23
|
+
group_name: groupName,
|
|
24
|
+
};
|
|
25
|
+
// Check for group properties
|
|
26
|
+
const groupProperties = user.group_properties?.[groupType]?.[groupName];
|
|
27
|
+
if (groupProperties && Object.keys(groupProperties).length > 0) {
|
|
28
|
+
groupNameMap["group_properties"] = groupProperties;
|
|
29
|
+
}
|
|
30
|
+
groups[groupType] = groupNameMap;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (Object.keys(groups).length > 0) {
|
|
34
|
+
context["groups"] = groups;
|
|
35
|
+
}
|
|
36
|
+
delete contextUser.groups;
|
|
37
|
+
delete contextUser.group_properties;
|
|
38
|
+
return context;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const convertVariant = (
|
|
42
|
+
value: string | Variant | undefined,
|
|
43
|
+
): Variant => {
|
|
44
|
+
if (value === null || value === undefined) {
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
if (typeof value === "string") {
|
|
48
|
+
return {
|
|
49
|
+
key: value,
|
|
50
|
+
value: value,
|
|
51
|
+
};
|
|
52
|
+
} else {
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const convertEvaluationVariantToVariant = (
|
|
58
|
+
evaluationVariant: EvaluationVariant,
|
|
59
|
+
): Variant => {
|
|
60
|
+
if (!evaluationVariant) {
|
|
61
|
+
return {};
|
|
62
|
+
}
|
|
63
|
+
let experimentKey: string | undefined;
|
|
64
|
+
if (evaluationVariant.metadata) {
|
|
65
|
+
const metadataExperimentKey = evaluationVariant.metadata["experimentKey"];
|
|
66
|
+
if (typeof metadataExperimentKey === "string") {
|
|
67
|
+
experimentKey = metadataExperimentKey;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const variant: Variant = {};
|
|
71
|
+
if (evaluationVariant.key) variant.key = evaluationVariant.key;
|
|
72
|
+
if (evaluationVariant.value)
|
|
73
|
+
variant.value = evaluationVariant.value as string;
|
|
74
|
+
if (evaluationVariant.payload) variant.payload = evaluationVariant.payload;
|
|
75
|
+
if (experimentKey) variant.expKey = experimentKey;
|
|
76
|
+
if (evaluationVariant.metadata) variant.metadata = evaluationVariant.metadata;
|
|
77
|
+
return variant;
|
|
78
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { EvaluationFlag } from "@amplitude/experiment-core";
|
|
2
|
+
|
|
3
|
+
export const isNullOrUndefined = (value: unknown): boolean => {
|
|
4
|
+
return value === null || value === undefined;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const isNullUndefinedOrEmpty = (value: unknown): boolean => {
|
|
8
|
+
if (isNullOrUndefined(value)) return true;
|
|
9
|
+
if (value === null || typeof value !== "object") return false;
|
|
10
|
+
return Object.keys(value).length === 0;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const isLocalEvaluationMode = (
|
|
14
|
+
flag: EvaluationFlag | undefined,
|
|
15
|
+
): boolean => {
|
|
16
|
+
return flag?.metadata?.evaluationMode === "local";
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const isRemoteEvaluationMode = (
|
|
20
|
+
flag: EvaluationFlag | undefined,
|
|
21
|
+
): boolean => {
|
|
22
|
+
return flag?.metadata?.evaluationMode === "remote";
|
|
23
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
2
|
+
|
|
3
|
+
export const randomString = (
|
|
4
|
+
length: number,
|
|
5
|
+
alphabet: string = CHARS,
|
|
6
|
+
): string => {
|
|
7
|
+
let str = "";
|
|
8
|
+
for (let i = 0; i < length; ++i) {
|
|
9
|
+
str += alphabet.charAt(Math.floor(Math.random() * alphabet.length));
|
|
10
|
+
}
|
|
11
|
+
return str;
|
|
12
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Exposure, ExposureTrackingProvider } from "../types/exposure";
|
|
2
|
+
import { ExperimentUser } from "../types/user";
|
|
3
|
+
|
|
4
|
+
interface Identity {
|
|
5
|
+
userId?: string;
|
|
6
|
+
deviceId?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A wrapper for an exposure tracking provider which only sends one exposure event per
|
|
11
|
+
* flag, per variant, per user session. When the user identity (userId or deviceId) changes,
|
|
12
|
+
* the tracking cache is reset to ensure exposures are tracked for the new user session.
|
|
13
|
+
*/
|
|
14
|
+
export class UserSessionExposureTracker {
|
|
15
|
+
private readonly exposureTrackingProvider: ExposureTrackingProvider;
|
|
16
|
+
private tracked: Record<string, string | undefined> = {};
|
|
17
|
+
private identity: Identity = {};
|
|
18
|
+
|
|
19
|
+
constructor(exposureTrackingProvider: ExposureTrackingProvider) {
|
|
20
|
+
this.exposureTrackingProvider = exposureTrackingProvider;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
track(exposure: Exposure, user?: ExperimentUser): void {
|
|
24
|
+
const newIdentity: Identity = {
|
|
25
|
+
userId: user?.user_id,
|
|
26
|
+
deviceId: user?.device_id,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
if (!this.identityEquals(this.identity, newIdentity)) {
|
|
30
|
+
this.tracked = {};
|
|
31
|
+
}
|
|
32
|
+
this.identity = newIdentity;
|
|
33
|
+
|
|
34
|
+
const hasTrackedFlag = exposure.flag_key in this.tracked;
|
|
35
|
+
const trackedVariant = this.tracked[exposure.flag_key];
|
|
36
|
+
if (hasTrackedFlag && trackedVariant === exposure.variant) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.tracked[exposure.flag_key] = exposure.variant;
|
|
41
|
+
this.exposureTrackingProvider.track(exposure);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private identityEquals(id1: Identity, id2: Identity): boolean {
|
|
45
|
+
return id1.userId === id2.userId && id1.deviceId === id2.deviceId;
|
|
46
|
+
}
|
|
47
|
+
}
|