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