@nathanclaire/edge-telemetry-sdk 3.0.0 → 4.0.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 (298) hide show
  1. package/README.md +831 -186
  2. package/dist/appLifecycle-CECgRVu_.cjs +2 -0
  3. package/dist/appLifecycle-CECgRVu_.cjs.map +1 -0
  4. package/dist/appLifecycle-DQErzJIR.js +22 -0
  5. package/dist/appLifecycle-DQErzJIR.js.map +1 -0
  6. package/dist/batch-CwoO7noL.js +56 -0
  7. package/dist/batch-CwoO7noL.js.map +1 -0
  8. package/dist/batch-DNu8Xr9T.cjs +2 -0
  9. package/dist/batch-DNu8Xr9T.cjs.map +1 -0
  10. package/dist/crashCapture-BOJ8nSAZ.cjs +4 -0
  11. package/dist/crashCapture-BOJ8nSAZ.cjs.map +1 -0
  12. package/dist/crashCapture-BW8WuyaU.js +70 -0
  13. package/dist/crashCapture-BW8WuyaU.js.map +1 -0
  14. package/dist/crashHandler.web-8F_k2veo.js +29 -0
  15. package/dist/crashHandler.web-8F_k2veo.js.map +1 -0
  16. package/dist/crashHandler.web-CWmF56mJ.cjs +2 -0
  17. package/dist/crashHandler.web-CWmF56mJ.cjs.map +1 -0
  18. package/dist/crashHandlerNative.native-C2kSikDt.cjs +2 -0
  19. package/dist/crashHandlerNative.native-C2kSikDt.cjs.map +1 -0
  20. package/dist/crashHandlerNative.native-FupMnr1U.js +39 -0
  21. package/dist/crashHandlerNative.native-FupMnr1U.js.map +1 -0
  22. package/dist/deviceInfo.native-BJ-3Jj1T.js +53 -0
  23. package/dist/deviceInfo.native-BJ-3Jj1T.js.map +1 -0
  24. package/dist/deviceInfo.native-BoeTZcD6.cjs +2 -0
  25. package/dist/deviceInfo.native-BoeTZcD6.cjs.map +1 -0
  26. package/dist/deviceInfo.web-3L3IDQQA.cjs +2 -0
  27. package/dist/deviceInfo.web-3L3IDQQA.cjs.map +1 -0
  28. package/dist/deviceInfo.web-BFB1-pcA.js +41 -0
  29. package/dist/deviceInfo.web-BFB1-pcA.js.map +1 -0
  30. package/dist/frameTracker-CHG6sIx9.cjs +2 -0
  31. package/dist/frameTracker-CHG6sIx9.cjs.map +1 -0
  32. package/dist/frameTracker-DdB8W_kC.js +54 -0
  33. package/dist/frameTracker-DdB8W_kC.js.map +1 -0
  34. package/dist/httpAttributes-BrrtM8zh.js +70 -0
  35. package/dist/httpAttributes-BrrtM8zh.js.map +1 -0
  36. package/dist/httpAttributes-D0m6UID7.cjs +2 -0
  37. package/dist/httpAttributes-D0m6UID7.cjs.map +1 -0
  38. package/dist/index-BtLlV1HA.js +57 -0
  39. package/dist/index-BtLlV1HA.js.map +1 -0
  40. package/dist/{deviceInfo.native-D2k0LDhI.js → index-C2XQ-EYw.js} +362 -411
  41. package/dist/index-C2XQ-EYw.js.map +1 -0
  42. package/dist/index-CXsVZY35.cjs +2 -0
  43. package/dist/index-CXsVZY35.cjs.map +1 -0
  44. package/dist/index-DLquF88M.cjs +2 -0
  45. package/dist/index-DLquF88M.cjs.map +1 -0
  46. package/dist/index.native.cjs +1 -1
  47. package/dist/index.native.cjs.map +1 -1
  48. package/dist/index.native.js +94 -59
  49. package/dist/index.native.js.map +1 -1
  50. package/dist/index.web.cjs +1 -1
  51. package/dist/index.web.cjs.map +1 -1
  52. package/dist/index.web.js +88 -33
  53. package/dist/index.web.js.map +1 -1
  54. package/dist/interactionWeb.web-Bl_cZlgh.cjs +2 -0
  55. package/dist/interactionWeb.web-Bl_cZlgh.cjs.map +1 -0
  56. package/dist/interactionWeb.web-CJAviVQ7.js +109 -0
  57. package/dist/interactionWeb.web-CJAviVQ7.js.map +1 -0
  58. package/dist/interceptFetchWeb.web-T88kO-bE.cjs +2 -0
  59. package/dist/interceptFetchWeb.web-T88kO-bE.cjs.map +1 -0
  60. package/dist/interceptFetchWeb.web-UXC2Lb6X.js +61 -0
  61. package/dist/interceptFetchWeb.web-UXC2Lb6X.js.map +1 -0
  62. package/dist/interceptHttpNative.native-BVpFuoNB.cjs +2 -0
  63. package/dist/interceptHttpNative.native-BVpFuoNB.cjs.map +1 -0
  64. package/dist/interceptHttpNative.native-rX-lPNST.js +18 -0
  65. package/dist/interceptHttpNative.native-rX-lPNST.js.map +1 -0
  66. package/dist/loadingTime-Bhomd9qq.cjs +2 -0
  67. package/dist/loadingTime-Bhomd9qq.cjs.map +1 -0
  68. package/dist/loadingTime-ZkYvFijA.js +70 -0
  69. package/dist/loadingTime-ZkYvFijA.js.map +1 -0
  70. package/dist/memoryNative.native-C42h9SjK.js +54 -0
  71. package/dist/memoryNative.native-C42h9SjK.js.map +1 -0
  72. package/dist/memoryNative.native-CA-7w9w1.cjs +2 -0
  73. package/dist/memoryNative.native-CA-7w9w1.cjs.map +1 -0
  74. package/dist/memoryStore-BIGZmmfD.cjs +2 -0
  75. package/dist/memoryStore-BIGZmmfD.cjs.map +1 -0
  76. package/dist/memoryStore-F5I-GQKM.js +193 -0
  77. package/dist/memoryStore-F5I-GQKM.js.map +1 -0
  78. package/dist/nativeSender-CfQaRuDK.cjs +2 -0
  79. package/dist/nativeSender-CfQaRuDK.cjs.map +1 -0
  80. package/dist/nativeSender-pgVSIv-X.js +59 -0
  81. package/dist/nativeSender-pgVSIv-X.js.map +1 -0
  82. package/dist/navigationRef-BzYbs8cm.js +28 -0
  83. package/dist/navigationRef-BzYbs8cm.js.map +1 -0
  84. package/dist/navigationRef-C-_qhb43.cjs +2 -0
  85. package/dist/navigationRef-C-_qhb43.cjs.map +1 -0
  86. package/dist/{navigationTracker-Cts68dgG.js → navigationTracker-BmywA_Bg.js} +4 -4
  87. package/dist/navigationTracker-BmywA_Bg.js.map +1 -0
  88. package/dist/navigationTracker-HkwVyywz.cjs +2 -0
  89. package/dist/navigationTracker-HkwVyywz.cjs.map +1 -0
  90. package/dist/navigationWeb.web-CW_z7Ca4.cjs +2 -0
  91. package/dist/navigationWeb.web-CW_z7Ca4.cjs.map +1 -0
  92. package/dist/navigationWeb.web-CcwgKuIZ.js +55 -0
  93. package/dist/navigationWeb.web-CcwgKuIZ.js.map +1 -0
  94. package/dist/{networkInfo.native-BK5fpAOL.js → networkInfo.native-CGrx9cnH.js} +15 -15
  95. package/dist/{networkInfo.native-BK5fpAOL.js.map → networkInfo.native-CGrx9cnH.js.map} +1 -1
  96. package/dist/{networkInfo.native-cxuw93Uy.cjs → networkInfo.native-YVySdv3S.cjs} +2 -2
  97. package/dist/{networkInfo.native-cxuw93Uy.cjs.map → networkInfo.native-YVySdv3S.cjs.map} +1 -1
  98. package/dist/{networkInfo.web-twcNn_hc.js → networkInfo.web-B2YlLNsI.js} +3 -3
  99. package/dist/networkInfo.web-B2YlLNsI.js.map +1 -0
  100. package/dist/networkInfo.web-PltJTHsy.cjs +2 -0
  101. package/dist/networkInfo.web-PltJTHsy.cjs.map +1 -0
  102. package/dist/runtimeReady.native-Bh7EcYmK.js +14 -0
  103. package/dist/runtimeReady.native-Bh7EcYmK.js.map +1 -0
  104. package/dist/runtimeReady.native-jUmuE1lV.cjs +2 -0
  105. package/dist/runtimeReady.native-jUmuE1lV.cjs.map +1 -0
  106. package/dist/runtimeReady.web-C8fdIbVR.js +25 -0
  107. package/dist/runtimeReady.web-C8fdIbVR.js.map +1 -0
  108. package/dist/runtimeReady.web-DHW682RN.cjs +2 -0
  109. package/dist/runtimeReady.web-DHW682RN.cjs.map +1 -0
  110. package/dist/seedRuntimeReady-BKwkBEAF.cjs +2 -0
  111. package/dist/seedRuntimeReady-BKwkBEAF.cjs.map +1 -0
  112. package/dist/seedRuntimeReady-Cz8nOKoo.js +10 -0
  113. package/dist/seedRuntimeReady-Cz8nOKoo.js.map +1 -0
  114. package/dist/src/adapters/appLifecycle.d.ts +8 -1
  115. package/dist/src/adapters/batch.d.ts +2 -0
  116. package/dist/src/adapters/crashCapture.d.ts +38 -9
  117. package/dist/src/adapters/failedEvents.d.ts +43 -0
  118. package/dist/src/adapters/frameAggregate.d.ts +8 -3
  119. package/dist/src/adapters/frameTracker.d.ts +30 -0
  120. package/dist/src/adapters/httpAttributes.d.ts +18 -0
  121. package/dist/src/adapters/loadingTime.d.ts +67 -0
  122. package/dist/src/adapters/native/interceptHttpNative.native.d.ts +18 -0
  123. package/dist/src/adapters/native/memoryNative.native.d.ts +15 -11
  124. package/dist/src/adapters/native/runtimeReady.native.d.ts +1 -0
  125. package/dist/src/adapters/native/store.native.d.ts +10 -0
  126. package/dist/src/adapters/nativeSender.d.ts +2 -2
  127. package/dist/src/adapters/navigationRef.d.ts +21 -0
  128. package/dist/src/adapters/navigationTracker.d.ts +1 -1
  129. package/dist/src/adapters/screenTiming.d.ts +8 -2
  130. package/dist/src/adapters/seedRuntimeReady.d.ts +8 -0
  131. package/dist/src/adapters/traceHeader.d.ts +33 -0
  132. package/dist/src/adapters/traceManager.d.ts +131 -0
  133. package/dist/src/adapters/uiInteraction.d.ts +111 -0
  134. package/dist/src/adapters/viewManager.d.ts +161 -0
  135. package/dist/src/adapters/viewport.d.ts +15 -0
  136. package/dist/src/adapters/web/interactionWeb.web.d.ts +36 -0
  137. package/dist/src/adapters/web/interceptFetchWeb.web.d.ts +3 -11
  138. package/dist/src/adapters/web/navigationWeb.web.d.ts +10 -0
  139. package/dist/src/adapters/web/runtimeReady.web.d.ts +5 -0
  140. package/dist/src/adapters/web/store.web.d.ts +12 -0
  141. package/dist/src/adapters/web/webVitals.web.d.ts +49 -0
  142. package/dist/src/adapters/webSender.d.ts +2 -2
  143. package/dist/src/adapters/webVitals.d.ts +25 -0
  144. package/dist/src/adapters/xhrIntercept.d.ts +53 -0
  145. package/dist/src/core/beforeSend.d.ts +20 -0
  146. package/dist/src/core/debug.d.ts +7 -0
  147. package/dist/src/core/memoryStore.d.ts +23 -0
  148. package/dist/src/core/store.d.ts +41 -0
  149. package/dist/src/core/telemetry.d.ts +305 -35
  150. package/dist/src/core/userProfile.d.ts +12 -0
  151. package/dist/src/core/utils/json.d.ts +7 -0
  152. package/dist/src/core/utils/uuid.d.ts +10 -1
  153. package/dist/src/createTelemetry.native.d.ts +7 -0
  154. package/dist/src/createTelemetry.web.d.ts +7 -0
  155. package/dist/src/index.base.d.ts +17 -1
  156. package/dist/src/index.native.d.ts +46 -9
  157. package/dist/src/index.web.d.ts +33 -2
  158. package/dist/store.native-BYBJcy6o.js +32 -0
  159. package/dist/store.native-BYBJcy6o.js.map +1 -0
  160. package/dist/store.native-TPqXngmF.cjs +2 -0
  161. package/dist/store.native-TPqXngmF.cjs.map +1 -0
  162. package/dist/store.web-CvqqN-_Z.cjs +2 -0
  163. package/dist/store.web-CvqqN-_Z.cjs.map +1 -0
  164. package/dist/store.web-DJAlN0nc.js +31 -0
  165. package/dist/store.web-DJAlN0nc.js.map +1 -0
  166. package/dist/telemetry-ByDJIz_9.js +1280 -0
  167. package/dist/telemetry-ByDJIz_9.js.map +1 -0
  168. package/dist/telemetry-CrU7i1Jc.cjs +2 -0
  169. package/dist/telemetry-CrU7i1Jc.cjs.map +1 -0
  170. package/dist/uiInteraction-CdzvEI1p.cjs +2 -0
  171. package/dist/uiInteraction-CdzvEI1p.cjs.map +1 -0
  172. package/dist/uiInteraction-DAqxxz0q.js +104 -0
  173. package/dist/uiInteraction-DAqxxz0q.js.map +1 -0
  174. package/dist/viewport-Dd85GUNO.cjs +2 -0
  175. package/dist/viewport-Dd85GUNO.cjs.map +1 -0
  176. package/dist/viewport-Dzmt5QwK.js +15 -0
  177. package/dist/viewport-Dzmt5QwK.js.map +1 -0
  178. package/dist/web-vitals.attribution-CVCPiX-h.cjs +2 -0
  179. package/dist/web-vitals.attribution-CVCPiX-h.cjs.map +1 -0
  180. package/dist/web-vitals.attribution-xw9N5MKQ.js +488 -0
  181. package/dist/web-vitals.attribution-xw9N5MKQ.js.map +1 -0
  182. package/dist/webSender-BIwslfpT.js +63 -0
  183. package/dist/webSender-BIwslfpT.js.map +1 -0
  184. package/dist/webSender-CVtE4sOF.cjs +2 -0
  185. package/dist/webSender-CVtE4sOF.cjs.map +1 -0
  186. package/dist/webVitals.web-CNIpsKlA.js +85 -0
  187. package/dist/webVitals.web-CNIpsKlA.js.map +1 -0
  188. package/dist/webVitals.web-DpWJ-iYp.cjs +2 -0
  189. package/dist/webVitals.web-DpWJ-iYp.cjs.map +1 -0
  190. package/dist/xhrIntercept-BADex6Cq.cjs +2 -0
  191. package/dist/xhrIntercept-BADex6Cq.cjs.map +1 -0
  192. package/dist/xhrIntercept-BNiA41Mj.js +53 -0
  193. package/dist/xhrIntercept-BNiA41Mj.js.map +1 -0
  194. package/docs/migration-v4.md +190 -0
  195. package/package.json +12 -4
  196. package/dist/appLifecycle-Cynw0kAv.js +0 -14
  197. package/dist/appLifecycle-Cynw0kAv.js.map +0 -1
  198. package/dist/appLifecycle-DvJIt7ym.cjs +0 -2
  199. package/dist/appLifecycle-DvJIt7ym.cjs.map +0 -1
  200. package/dist/batch-CLBFgYPC.cjs +0 -2
  201. package/dist/batch-CLBFgYPC.cjs.map +0 -1
  202. package/dist/batch-DLG_gtOm.js +0 -12
  203. package/dist/batch-DLG_gtOm.js.map +0 -1
  204. package/dist/crashCapture-BYTM4FLC.cjs +0 -2
  205. package/dist/crashCapture-BYTM4FLC.cjs.map +0 -1
  206. package/dist/crashCapture-D_rkkBVa.js +0 -31
  207. package/dist/crashCapture-D_rkkBVa.js.map +0 -1
  208. package/dist/crashHandler.web-BSxDpFTo.cjs +0 -2
  209. package/dist/crashHandler.web-BSxDpFTo.cjs.map +0 -1
  210. package/dist/crashHandler.web-D59bmhg9.js +0 -32
  211. package/dist/crashHandler.web-D59bmhg9.js.map +0 -1
  212. package/dist/crashHandlerNative.native-DeAFze4E.cjs +0 -2
  213. package/dist/crashHandlerNative.native-DeAFze4E.cjs.map +0 -1
  214. package/dist/crashHandlerNative.native-d7qJkzA6.js +0 -41
  215. package/dist/crashHandlerNative.native-d7qJkzA6.js.map +0 -1
  216. package/dist/debug-DsvQ9y3W.js +0 -68
  217. package/dist/debug-DsvQ9y3W.js.map +0 -1
  218. package/dist/debug-rnOOxFpN.cjs +0 -2
  219. package/dist/debug-rnOOxFpN.cjs.map +0 -1
  220. package/dist/deviceInfo.native-7hbRYixR.cjs +0 -2
  221. package/dist/deviceInfo.native-7hbRYixR.cjs.map +0 -1
  222. package/dist/deviceInfo.native-D2k0LDhI.js.map +0 -1
  223. package/dist/deviceInfo.web-ByNAlEJh.cjs +0 -2
  224. package/dist/deviceInfo.web-ByNAlEJh.cjs.map +0 -1
  225. package/dist/deviceInfo.web-DzQyEku6.js +0 -40
  226. package/dist/deviceInfo.web-DzQyEku6.js.map +0 -1
  227. package/dist/frameAggregate-C_HoVFcK.cjs +0 -2
  228. package/dist/frameAggregate-C_HoVFcK.cjs.map +0 -1
  229. package/dist/frameAggregate-Cwh1juw1.js +0 -17
  230. package/dist/frameAggregate-Cwh1juw1.js.map +0 -1
  231. package/dist/frameDropsNative.native-CP7zrXDf.js +0 -23
  232. package/dist/frameDropsNative.native-CP7zrXDf.js.map +0 -1
  233. package/dist/frameDropsNative.native-DKqEDqip.cjs +0 -2
  234. package/dist/frameDropsNative.native-DKqEDqip.cjs.map +0 -1
  235. package/dist/frameDropsWeb.web-C9Lt3Fuj.js +0 -22
  236. package/dist/frameDropsWeb.web-C9Lt3Fuj.js.map +0 -1
  237. package/dist/frameDropsWeb.web-azpwQCUz.cjs +0 -2
  238. package/dist/frameDropsWeb.web-azpwQCUz.cjs.map +0 -1
  239. package/dist/httpAttributes-BV50UKQU.js +0 -19
  240. package/dist/httpAttributes-BV50UKQU.js.map +0 -1
  241. package/dist/httpAttributes-xXOD9trQ.cjs +0 -2
  242. package/dist/httpAttributes-xXOD9trQ.cjs.map +0 -1
  243. package/dist/interaction-CH8yoY5-.js +0 -23
  244. package/dist/interaction-CH8yoY5-.js.map +0 -1
  245. package/dist/interaction-DcNFBW7a.cjs +0 -2
  246. package/dist/interaction-DcNFBW7a.cjs.map +0 -1
  247. package/dist/interceptFetchNative.native-VlhtMG-U.js +0 -49
  248. package/dist/interceptFetchNative.native-VlhtMG-U.js.map +0 -1
  249. package/dist/interceptFetchNative.native-jEAldH14.cjs +0 -2
  250. package/dist/interceptFetchNative.native-jEAldH14.cjs.map +0 -1
  251. package/dist/interceptFetchWeb.web-DFzZliik.cjs +0 -2
  252. package/dist/interceptFetchWeb.web-DFzZliik.cjs.map +0 -1
  253. package/dist/interceptFetchWeb.web-DfsMfoRP.js +0 -77
  254. package/dist/interceptFetchWeb.web-DfsMfoRP.js.map +0 -1
  255. package/dist/memoryNative.native-BWLh2S9L.js +0 -48
  256. package/dist/memoryNative.native-BWLh2S9L.js.map +0 -1
  257. package/dist/memoryNative.native-DCXSOd4Q.cjs +0 -2
  258. package/dist/memoryNative.native-DCXSOd4Q.cjs.map +0 -1
  259. package/dist/memoryWeb.web-B3YuV-cB.js +0 -48
  260. package/dist/memoryWeb.web-B3YuV-cB.js.map +0 -1
  261. package/dist/memoryWeb.web-CheXAcJn.cjs +0 -2
  262. package/dist/memoryWeb.web-CheXAcJn.cjs.map +0 -1
  263. package/dist/nativeSender-BE_mzw_S.js +0 -70
  264. package/dist/nativeSender-BE_mzw_S.js.map +0 -1
  265. package/dist/nativeSender-DyAUGY7c.cjs +0 -2
  266. package/dist/nativeSender-DyAUGY7c.cjs.map +0 -1
  267. package/dist/navigationNative.native-3tO5JxSd.cjs +0 -2
  268. package/dist/navigationNative.native-3tO5JxSd.cjs.map +0 -1
  269. package/dist/navigationNative.native-BUCGPQX2.js +0 -25
  270. package/dist/navigationNative.native-BUCGPQX2.js.map +0 -1
  271. package/dist/navigationTracker-B2GMwyKk.cjs +0 -2
  272. package/dist/navigationTracker-B2GMwyKk.cjs.map +0 -1
  273. package/dist/navigationTracker-Cts68dgG.js.map +0 -1
  274. package/dist/navigationWeb.web-B0necr5j.cjs +0 -2
  275. package/dist/navigationWeb.web-B0necr5j.cjs.map +0 -1
  276. package/dist/navigationWeb.web-CORzE_Id.js +0 -46
  277. package/dist/navigationWeb.web-CORzE_Id.js.map +0 -1
  278. package/dist/networkInfo.web-DJmw1sNK.cjs +0 -2
  279. package/dist/networkInfo.web-DJmw1sNK.cjs.map +0 -1
  280. package/dist/networkInfo.web-twcNn_hc.js.map +0 -1
  281. package/dist/src/adapters/interaction.d.ts +0 -17
  282. package/dist/src/adapters/native/frameDropsNative.native.d.ts +0 -16
  283. package/dist/src/adapters/native/interceptFetchNative.native.d.ts +0 -23
  284. package/dist/src/adapters/native/navigationNative.native.d.ts +0 -12
  285. package/dist/src/adapters/web/frameDropsWeb.web.d.ts +0 -16
  286. package/dist/src/adapters/web/memoryWeb.web.d.ts +0 -26
  287. package/dist/telemetry-Co4MYdwa.cjs +0 -2
  288. package/dist/telemetry-Co4MYdwa.cjs.map +0 -1
  289. package/dist/telemetry-KI0x4gzC.js +0 -389
  290. package/dist/telemetry-KI0x4gzC.js.map +0 -1
  291. package/dist/v4-BysszJq8.js +0 -31
  292. package/dist/v4-BysszJq8.js.map +0 -1
  293. package/dist/v4-CqdK_b8Y.cjs +0 -2
  294. package/dist/v4-CqdK_b8Y.cjs.map +0 -1
  295. package/dist/webSender-B27tmT1w.js +0 -42
  296. package/dist/webSender-B27tmT1w.js.map +0 -1
  297. package/dist/webSender-BWi4x1df.cjs +0 -2
  298. package/dist/webSender-BWi4x1df.cjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"nativeSender-DyAUGY7c.cjs","sources":["../src/adapters/nativeSender.ts"],"sourcesContent":["import { debug } from \"../core/debug\";\nimport type { TelemetryEvent, Sender } from \"../core/telemetry\";\nimport AsyncStorage from \"@react-native-async-storage/async-storage\";\nimport { buildBatch } from \"./batch\";\n\nconst DEFAULT_ENDPOINT = \"https://your.telemetry.endpoint/collect\";\nconst STORAGE_KEY = \"telemetry_failed_events\";\n\nasync function persistFailed(events: TelemetryEvent[]) {\n const existing = JSON.parse((await AsyncStorage.getItem(STORAGE_KEY)) || \"[]\");\n await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify([...existing, ...events]));\n}\n\n// ⬇️ Helper: send with retries (exponential backoff + jitter)\nasync function sendWithRetry(endpoint: string, apiKey: string | undefined, events: TelemetryEvent[], retryCount: number = 3) {\n let attempts = 0;\n let lastError: any;\n\n while (attempts < retryCount) {\n try {\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(apiKey ? { \"X-API-Key\": apiKey } : {}),\n },\n body: buildBatch(events),\n });\n\n if (!res.ok) {\n\n debug.warn(\"Telemetry send failed with status:\", res.status);\n throw new Error(`Telemetry send failed: ${res.status}`);\n }\n\n debug.log(\"Telemetry send succeeded, events sent:\", events.length ?? 0);\n\n return; // ✅ success\n } catch (err) {\n lastError = err;\n attempts++;\n if (attempts < retryCount) {\n // ⬇️ exponential backoff with jitter\n await new Promise(res =>\n setTimeout(res, 500 * 2 ** attempts + Math.random() * 200)\n );\n }\n }\n }\n\n // ❌ after retries still failed\n throw lastError;\n}\n\nexport function nativeSender(endpoint: string = DEFAULT_ENDPOINT, apiKey?: string): Sender {\n return {\n async send(events) {\n // Retry + backoff here; persistence on final failure is the core flush()'s\n // job via onFailure() — kept single, so a failed batch isn't persisted twice.\n await sendWithRetry(endpoint, apiKey, events);\n },\n async onFailure(events) {\n await persistFailed(events);\n },\n async replayFailed() {\n debug.log(\"Telemetry replayFailedNative launched\");\n debug.log(\"AsyncStorage available methods:\", Object.keys(AsyncStorage));\n const stored = JSON.parse((await AsyncStorage.getItem(STORAGE_KEY)) || \"[]\");\n if (stored.length > 0) {\n debug.log(\"Replaying failed events, count:\", stored.length);\n await AsyncStorage.removeItem(STORAGE_KEY);\n debug.log(\"Failed events removed from storage, attempting to resend\");\n try {\n await sendWithRetry(endpoint, apiKey, stored);\n } catch (err) {\n // If replay fails again, re-store\n await persistFailed(stored);\n throw err;\n }\n }\n },\n };\n}\n\n// Recover failed events on app start\nexport async function replayFailedNative(endpoint: string = DEFAULT_ENDPOINT, apiKey?: string) {\n debug.log(\"Telemetry replayFailedNative launched\");\n debug.log(\"AsyncStorage available methods:\", Object.keys(AsyncStorage));\n const stored = JSON.parse((await AsyncStorage.getItem(STORAGE_KEY)) || \"[]\");\n if (stored.length > 0) {\n await AsyncStorage.removeItem(STORAGE_KEY);\n try {\n debug.log(\"Replaying failed events, count:\", stored.length);\n debug.log(\"Failed events removed from storage, attempting to resend\");\n await sendWithRetry(endpoint, apiKey, stored);\n } catch (err) {\n // If replay fails again, re-store\n debug.warn(\"Telemetry replay failed Native Sender class:\", err);\n await persistFailed(stored);\n throw err;\n }\n }\n}\n\n"],"names":["DEFAULT_ENDPOINT","STORAGE_KEY","persistFailed","events","existing","AsyncStorage","sendWithRetry","endpoint","apiKey","retryCount","attempts","lastError","res","buildBatch","debug","err","nativeSender","stored","replayFailedNative"],"mappings":"iNAKMA,EAAmB,0CACnBC,EAAc,0BAEpB,eAAeC,EAAcC,EAA0B,CACnD,MAAMC,EAAW,KAAK,MAAO,MAAMC,EAAa,QAAQJ,CAAW,GAAM,IAAI,EAC7E,MAAMI,EAAa,QAAQJ,EAAa,KAAK,UAAU,CAAC,GAAGG,EAAU,GAAGD,CAAM,CAAC,CAAC,CACpF,CAGA,eAAeG,EAAcC,EAAkBC,EAA4BL,EAA0BM,EAAqB,EAAG,CACzH,IAAIC,EAAW,EACXC,EAEJ,KAAOD,EAAWD,GACd,GAAI,CACA,MAAMG,EAAM,MAAM,MAAML,EAAU,CAC9B,OAAQ,OACR,QAAS,CACL,eAAgB,mBAChB,GAAIC,EAAS,CAAE,YAAaA,GAAW,CAAA,CAAC,EAE5C,KAAMK,EAAAA,WAAWV,CAAM,CAAA,CAC1B,EAED,GAAI,CAACS,EAAI,GAELE,MAAAA,EAAAA,MAAM,KAAK,qCAAsCF,EAAI,MAAM,EACrD,IAAI,MAAM,0BAA0BA,EAAI,MAAM,EAAE,EAG1DE,EAAAA,MAAM,IAAI,yCAA0CX,EAAO,QAAU,CAAC,EAEtE,MACJ,OAASY,EAAK,CACVJ,EAAYI,EACZL,IACIA,EAAWD,GAEX,MAAM,IAAI,QAAQG,GACd,WAAWA,EAAK,IAAM,GAAKF,EAAW,KAAK,OAAA,EAAW,GAAG,CAAA,CAGrE,CAIJ,MAAMC,CACV,CAEO,SAASK,EAAaT,EAAmBP,EAAkBQ,EAAyB,CACvF,MAAO,CACH,MAAM,KAAKL,EAAQ,CAGf,MAAMG,EAAcC,EAAUC,EAAQL,CAAM,CAChD,EACA,MAAM,UAAUA,EAAQ,CACpB,MAAMD,EAAcC,CAAM,CAC9B,EACA,MAAM,cAAe,CACjBW,EAAAA,MAAM,IAAI,uCAAuC,EACjDA,EAAAA,MAAM,IAAI,kCAAmC,OAAO,KAAKT,CAAY,CAAC,EACtE,MAAMY,EAAS,KAAK,MAAO,MAAMZ,EAAa,QAAQJ,CAAW,GAAM,IAAI,EAC3E,GAAIgB,EAAO,OAAS,EAAG,CACnBH,EAAAA,MAAM,IAAI,kCAAmCG,EAAO,MAAM,EAC1D,MAAMZ,EAAa,WAAWJ,CAAW,EACzCa,EAAAA,MAAM,IAAI,0DAA0D,EACpE,GAAI,CACA,MAAMR,EAAcC,EAAUC,EAAQS,CAAM,CAChD,OAASF,EAAK,CAEV,YAAMb,EAAce,CAAM,EACpBF,CACV,CACJ,CACJ,CAAA,CAER,CAGA,eAAsBG,EAAmBX,EAAmBP,EAAkBQ,EAAiB,CAC3FM,EAAAA,MAAM,IAAI,uCAAuC,EACjDA,EAAAA,MAAM,IAAI,kCAAmC,OAAO,KAAKT,CAAY,CAAC,EACtE,MAAMY,EAAS,KAAK,MAAO,MAAMZ,EAAa,QAAQJ,CAAW,GAAM,IAAI,EAC3E,GAAIgB,EAAO,OAAS,EAAG,CACnB,MAAMZ,EAAa,WAAWJ,CAAW,EACzC,GAAI,CACAa,EAAAA,MAAM,IAAI,kCAAmCG,EAAO,MAAM,EAC1DH,EAAAA,MAAM,IAAI,0DAA0D,EACpE,MAAMR,EAAcC,EAAUC,EAAQS,CAAM,CAChD,OAASF,EAAK,CAEVD,MAAAA,QAAM,KAAK,+CAAgDC,CAAG,EAC9D,MAAMb,EAAce,CAAM,EACpBF,CACV,CACJ,CACJ"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./debug-rnOOxFpN.cjs"),a=require("./navigationTracker-B2GMwyKk.cjs");class i{constructor(t){this.tracker=new a.NavigationTracker(t)}attach(t){t&&(r.debug.log("NavigationTrackerNative: attaching to navigationRef"),t.addListener("state",()=>{const e=this.getActiveRouteName(t.getCurrentRoute());e&&e!==this.currentRoute&&(r.debug.log(`NavigationTrackerNative: route changed to ${e}`),this.tracker.recordRouteChange(this.currentRoute??"init",e),this.currentRoute=e)}))}getActiveRouteName(t){if(!t)return"unknown";if(t.state){const e=t.state.routes[t.state.index];return this.getActiveRouteName(e)}return t.name}}exports.NavigationTrackerNative=i;
2
- //# sourceMappingURL=navigationNative.native-3tO5JxSd.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigationNative.native-3tO5JxSd.cjs","sources":["../src/adapters/native/navigationNative.native.ts"],"sourcesContent":["import { debug } from \"../../core/debug\";\nimport { Telemetry } from \"../../core/telemetry\";\nimport { NavigationTracker } from \"../navigationTracker\";\n\n/**\n * Hook into React Navigation events\n * Usage: pass your navigationContainerRef\n */\nexport class NavigationTrackerNative {\n private tracker: NavigationTracker;\n private currentRoute?: string;\n\n constructor(telemetry: Telemetry) {\n this.tracker = new NavigationTracker(telemetry);\n }\n\n attach(navigationRef: any) {\n if (!navigationRef) return;\n\n debug.log(\"NavigationTrackerNative: attaching to navigationRef\");\n navigationRef.addListener(\"state\", () => {\n const route = this.getActiveRouteName(navigationRef.getCurrentRoute());\n if (route && route !== this.currentRoute) {\n\n debug.log(`NavigationTrackerNative: route changed to ${route}`);\n this.tracker.recordRouteChange(this.currentRoute ?? \"init\", route);\n this.currentRoute = route;\n }\n });\n }\n\n private getActiveRouteName(route: any): string {\n if (!route) return \"unknown\";\n if (route.state) {\n const nested = route.state.routes[route.state.index];\n return this.getActiveRouteName(nested);\n }\n return route.name;\n }\n}\n"],"names":["NavigationTrackerNative","telemetry","NavigationTracker","navigationRef","debug","route","nested"],"mappings":"sKAQO,MAAMA,CAAwB,CAIjC,YAAYC,EAAsB,CAC9B,KAAK,QAAU,IAAIC,EAAAA,kBAAkBD,CAAS,CAClD,CAEA,OAAOE,EAAoB,CAClBA,IAELC,EAAAA,MAAM,IAAI,qDAAqD,EAC/DD,EAAc,YAAY,QAAS,IAAM,CACrC,MAAME,EAAQ,KAAK,mBAAmBF,EAAc,iBAAiB,EACjEE,GAASA,IAAU,KAAK,eAExBD,EAAAA,MAAM,IAAI,6CAA6CC,CAAK,EAAE,EAC9D,KAAK,QAAQ,kBAAkB,KAAK,cAAgB,OAAQA,CAAK,EACjE,KAAK,aAAeA,EAE5B,CAAC,EACL,CAEQ,mBAAmBA,EAAoB,CAC3C,GAAI,CAACA,EAAO,MAAO,UACnB,GAAIA,EAAM,MAAO,CACb,MAAMC,EAASD,EAAM,MAAM,OAAOA,EAAM,MAAM,KAAK,EACnD,OAAO,KAAK,mBAAmBC,CAAM,CACzC,CACA,OAAOD,EAAM,IACjB,CACJ"}
@@ -1,25 +0,0 @@
1
- import { d as r } from "./debug-DsvQ9y3W.js";
2
- import { N as a } from "./navigationTracker-Cts68dgG.js";
3
- class c {
4
- constructor(t) {
5
- this.tracker = new a(t);
6
- }
7
- attach(t) {
8
- t && (r.log("NavigationTrackerNative: attaching to navigationRef"), t.addListener("state", () => {
9
- const e = this.getActiveRouteName(t.getCurrentRoute());
10
- e && e !== this.currentRoute && (r.log(`NavigationTrackerNative: route changed to ${e}`), this.tracker.recordRouteChange(this.currentRoute ?? "init", e), this.currentRoute = e);
11
- }));
12
- }
13
- getActiveRouteName(t) {
14
- if (!t) return "unknown";
15
- if (t.state) {
16
- const e = t.state.routes[t.state.index];
17
- return this.getActiveRouteName(e);
18
- }
19
- return t.name;
20
- }
21
- }
22
- export {
23
- c as NavigationTrackerNative
24
- };
25
- //# sourceMappingURL=navigationNative.native-BUCGPQX2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigationNative.native-BUCGPQX2.js","sources":["../src/adapters/native/navigationNative.native.ts"],"sourcesContent":["import { debug } from \"../../core/debug\";\nimport { Telemetry } from \"../../core/telemetry\";\nimport { NavigationTracker } from \"../navigationTracker\";\n\n/**\n * Hook into React Navigation events\n * Usage: pass your navigationContainerRef\n */\nexport class NavigationTrackerNative {\n private tracker: NavigationTracker;\n private currentRoute?: string;\n\n constructor(telemetry: Telemetry) {\n this.tracker = new NavigationTracker(telemetry);\n }\n\n attach(navigationRef: any) {\n if (!navigationRef) return;\n\n debug.log(\"NavigationTrackerNative: attaching to navigationRef\");\n navigationRef.addListener(\"state\", () => {\n const route = this.getActiveRouteName(navigationRef.getCurrentRoute());\n if (route && route !== this.currentRoute) {\n\n debug.log(`NavigationTrackerNative: route changed to ${route}`);\n this.tracker.recordRouteChange(this.currentRoute ?? \"init\", route);\n this.currentRoute = route;\n }\n });\n }\n\n private getActiveRouteName(route: any): string {\n if (!route) return \"unknown\";\n if (route.state) {\n const nested = route.state.routes[route.state.index];\n return this.getActiveRouteName(nested);\n }\n return route.name;\n }\n}\n"],"names":["NavigationTrackerNative","telemetry","NavigationTracker","navigationRef","debug","route","nested"],"mappings":";;AAQO,MAAMA,EAAwB;AAAA,EAIjC,YAAYC,GAAsB;AAC9B,SAAK,UAAU,IAAIC,EAAkBD,CAAS;AAAA,EAClD;AAAA,EAEA,OAAOE,GAAoB;AACvB,IAAKA,MAELC,EAAM,IAAI,qDAAqD,GAC/DD,EAAc,YAAY,SAAS,MAAM;AACrC,YAAME,IAAQ,KAAK,mBAAmBF,EAAc,iBAAiB;AACrE,MAAIE,KAASA,MAAU,KAAK,iBAExBD,EAAM,IAAI,6CAA6CC,CAAK,EAAE,GAC9D,KAAK,QAAQ,kBAAkB,KAAK,gBAAgB,QAAQA,CAAK,GACjE,KAAK,eAAeA;AAAA,IAE5B,CAAC;AAAA,EACL;AAAA,EAEQ,mBAAmBA,GAAoB;AAC3C,QAAI,CAACA,EAAO,QAAO;AACnB,QAAIA,EAAM,OAAO;AACb,YAAMC,IAASD,EAAM,MAAM,OAAOA,EAAM,MAAM,KAAK;AACnD,aAAO,KAAK,mBAAmBC,CAAM;AAAA,IACzC;AACA,WAAOD,EAAM;AAAA,EACjB;AACJ;"}
@@ -1,2 +0,0 @@
1
- "use strict";class a{constructor(t){this.telemetry=t}recordRouteChange(t,e){this.telemetry.log("navigation",{"navigation.from_screen":t,"navigation.to_screen":e,"navigation.method":"push","navigation.route_type":"screen"})}}exports.NavigationTracker=a;
2
- //# sourceMappingURL=navigationTracker-B2GMwyKk.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigationTracker-B2GMwyKk.cjs","sources":["../src/adapters/navigationTracker.ts"],"sourcesContent":["import { Telemetry } from \"../core/telemetry\";\n\nexport class NavigationTracker {\n private telemetry: Telemetry;\n\n constructor(telemetry: Telemetry) {\n this.telemetry = telemetry;\n }\n\n // Route change → v3 `navigation`. Baseline keys follow the reference/Angular shape;\n // iOS (screen/previous_screen/type/kind) reconciliation is OPEN (see additions ledger).\n recordRouteChange(from: string, to: string) {\n this.telemetry.log(\"navigation\", {\n \"navigation.from_screen\": from,\n \"navigation.to_screen\": to,\n \"navigation.method\": \"push\",\n \"navigation.route_type\": \"screen\",\n });\n }\n}\n"],"names":["NavigationTracker","telemetry","from","to"],"mappings":"aAEO,MAAMA,CAAkB,CAG3B,YAAYC,EAAsB,CAC9B,KAAK,UAAYA,CACrB,CAIA,kBAAkBC,EAAcC,EAAY,CACxC,KAAK,UAAU,IAAI,aAAc,CAC7B,yBAA0BD,EAC1B,uBAAwBC,EACxB,oBAAqB,OACrB,wBAAyB,QAAA,CAC5B,CACL,CACJ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigationTracker-Cts68dgG.js","sources":["../src/adapters/navigationTracker.ts"],"sourcesContent":["import { Telemetry } from \"../core/telemetry\";\n\nexport class NavigationTracker {\n private telemetry: Telemetry;\n\n constructor(telemetry: Telemetry) {\n this.telemetry = telemetry;\n }\n\n // Route change → v3 `navigation`. Baseline keys follow the reference/Angular shape;\n // iOS (screen/previous_screen/type/kind) reconciliation is OPEN (see additions ledger).\n recordRouteChange(from: string, to: string) {\n this.telemetry.log(\"navigation\", {\n \"navigation.from_screen\": from,\n \"navigation.to_screen\": to,\n \"navigation.method\": \"push\",\n \"navigation.route_type\": \"screen\",\n });\n }\n}\n"],"names":["NavigationTracker","telemetry","from","to"],"mappings":"AAEO,MAAMA,EAAkB;AAAA,EAG3B,YAAYC,GAAsB;AAC9B,SAAK,YAAYA;AAAA,EACrB;AAAA;AAAA;AAAA,EAIA,kBAAkBC,GAAcC,GAAY;AACxC,SAAK,UAAU,IAAI,cAAc;AAAA,MAC7B,0BAA0BD;AAAA,MAC1B,wBAAwBC;AAAA,MACxB,qBAAqB;AAAA,MACrB,yBAAyB;AAAA,IAAA,CAC5B;AAAA,EACL;AACJ;"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("./navigationTracker-B2GMwyKk.cjs");class s{constructor(t){this.telemetry=t,this.tracker=new n.NavigationTracker(t),this.currentPath=""}start(){return new Promise(t=>{this.currentPath=window.location.pathname+window.location.search,this.patchHistory(),this.listenPopState(),t()})}patchHistory(){const t=history.pushState.bind(history),o=history.replaceState.bind(history),i=()=>{const e=window.location.pathname+window.location.search;this.tracker.recordRouteChange(this.currentPath,e),this.currentPath=e};history.pushState=((e,a,r)=>{t(e,a,r),i()}),history.replaceState=((e,a,r)=>{o(e,a,r),i()})}listenPopState(){window.addEventListener("popstate",()=>{const t=window.location.pathname+window.location.search;this.tracker.recordRouteChange(this.currentPath,t),this.currentPath=t})}}exports.NavigationTrackerWeb=s;
2
- //# sourceMappingURL=navigationWeb.web-B0necr5j.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigationWeb.web-B0necr5j.cjs","sources":["../src/adapters/web/navigationWeb.web.ts"],"sourcesContent":["import { Telemetry } from \"../../core/telemetry\";\nimport { NavigationTracker } from \"../navigationTracker\";\n\n/**\n * Tracks navigation route changes in web environments by patching\n * history API methods and listening to popstate events.\n * Logs route transitions using an internal NavigationTracker instance.\n */\nexport class NavigationTrackerWeb {\n private tracker: NavigationTracker;\n private currentPath: string;\n\n constructor(private telemetry: Telemetry) {\n this.tracker = new NavigationTracker(telemetry);\n this.currentPath = \"\"; // Will be initialized on start\n }\n\n /**\n * Initializes tracking by patching history methods and listening\n * to popstate events. Should be called once after instantiation.\n *\n * @returns Promise<void> resolves immediately after setup\n */\n start(): Promise<void> {\n return new Promise((resolve) => {\n this.currentPath = window.location.pathname + window.location.search;\n this.patchHistory();\n this.listenPopState();\n resolve();\n });\n }\n\n /**\n * Patches history.pushState and history.replaceState to intercept\n * route changes and notify the NavigationTracker.\n */\n private patchHistory(): void {\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n const handleChange = () => {\n const newPath = window.location.pathname + window.location.search;\n this.tracker.recordRouteChange(this.currentPath, newPath);\n this.currentPath = newPath;\n };\n\n history.pushState = (\n (data: any, unused: string, url?: string | URL | null) => {\n origPush(data, unused, url);\n handleChange();\n }\n ) as typeof history.pushState;\n\n history.replaceState = (\n (data: any, unused: string, url?: string | URL | null) => {\n origReplace(data, unused, url);\n handleChange();\n }\n ) as typeof history.replaceState;\n }\n\n /**\n * Sets up an event listener for popstate events (back/forward navigation)\n * to detect route changes triggered by browser controls.\n */\n private listenPopState(): void {\n window.addEventListener(\"popstate\", () => {\n const newPath = window.location.pathname + window.location.search;\n this.tracker.recordRouteChange(this.currentPath, newPath);\n this.currentPath = newPath;\n });\n }\n}\n"],"names":["NavigationTrackerWeb","telemetry","NavigationTracker","resolve","origPush","origReplace","handleChange","newPath","data","unused","url"],"mappings":"oIAQO,MAAMA,CAAqB,CAI9B,YAAoBC,EAAsB,CAAtB,KAAA,UAAAA,EAChB,KAAK,QAAU,IAAIC,EAAAA,kBAAkBD,CAAS,EAC9C,KAAK,YAAc,EACvB,CAQA,OAAuB,CACnB,OAAO,IAAI,QAASE,GAAY,CAC5B,KAAK,YAAc,OAAO,SAAS,SAAW,OAAO,SAAS,OAC9D,KAAK,aAAA,EACL,KAAK,eAAA,EACLA,EAAA,CACJ,CAAC,CACL,CAMQ,cAAqB,CACzB,MAAMC,EAAW,QAAQ,UAAU,KAAK,OAAO,EACzCC,EAAc,QAAQ,aAAa,KAAK,OAAO,EAE/CC,EAAe,IAAM,CACvB,MAAMC,EAAU,OAAO,SAAS,SAAW,OAAO,SAAS,OAC3D,KAAK,QAAQ,kBAAkB,KAAK,YAAaA,CAAO,EACxD,KAAK,YAAcA,CACvB,EAEA,QAAQ,WACJ,CAACC,EAAWC,EAAgBC,IAA8B,CACtDN,EAASI,EAAMC,EAAQC,CAAG,EAC1BJ,EAAA,CACJ,GAGJ,QAAQ,cACJ,CAACE,EAAWC,EAAgBC,IAA8B,CACtDL,EAAYG,EAAMC,EAAQC,CAAG,EAC7BJ,EAAA,CACJ,EAER,CAMQ,gBAAuB,CAC3B,OAAO,iBAAiB,WAAY,IAAM,CACtC,MAAMC,EAAU,OAAO,SAAS,SAAW,OAAO,SAAS,OAC3D,KAAK,QAAQ,kBAAkB,KAAK,YAAaA,CAAO,EACxD,KAAK,YAAcA,CACvB,CAAC,CACL,CACJ"}
@@ -1,46 +0,0 @@
1
- import { N as n } from "./navigationTracker-Cts68dgG.js";
2
- class c {
3
- constructor(t) {
4
- this.telemetry = t, this.tracker = new n(t), this.currentPath = "";
5
- }
6
- /**
7
- * Initializes tracking by patching history methods and listening
8
- * to popstate events. Should be called once after instantiation.
9
- *
10
- * @returns Promise<void> resolves immediately after setup
11
- */
12
- start() {
13
- return new Promise((t) => {
14
- this.currentPath = window.location.pathname + window.location.search, this.patchHistory(), this.listenPopState(), t();
15
- });
16
- }
17
- /**
18
- * Patches history.pushState and history.replaceState to intercept
19
- * route changes and notify the NavigationTracker.
20
- */
21
- patchHistory() {
22
- const t = history.pushState.bind(history), i = history.replaceState.bind(history), o = () => {
23
- const a = window.location.pathname + window.location.search;
24
- this.tracker.recordRouteChange(this.currentPath, a), this.currentPath = a;
25
- };
26
- history.pushState = ((a, e, r) => {
27
- t(a, e, r), o();
28
- }), history.replaceState = ((a, e, r) => {
29
- i(a, e, r), o();
30
- });
31
- }
32
- /**
33
- * Sets up an event listener for popstate events (back/forward navigation)
34
- * to detect route changes triggered by browser controls.
35
- */
36
- listenPopState() {
37
- window.addEventListener("popstate", () => {
38
- const t = window.location.pathname + window.location.search;
39
- this.tracker.recordRouteChange(this.currentPath, t), this.currentPath = t;
40
- });
41
- }
42
- }
43
- export {
44
- c as NavigationTrackerWeb
45
- };
46
- //# sourceMappingURL=navigationWeb.web-CORzE_Id.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigationWeb.web-CORzE_Id.js","sources":["../src/adapters/web/navigationWeb.web.ts"],"sourcesContent":["import { Telemetry } from \"../../core/telemetry\";\nimport { NavigationTracker } from \"../navigationTracker\";\n\n/**\n * Tracks navigation route changes in web environments by patching\n * history API methods and listening to popstate events.\n * Logs route transitions using an internal NavigationTracker instance.\n */\nexport class NavigationTrackerWeb {\n private tracker: NavigationTracker;\n private currentPath: string;\n\n constructor(private telemetry: Telemetry) {\n this.tracker = new NavigationTracker(telemetry);\n this.currentPath = \"\"; // Will be initialized on start\n }\n\n /**\n * Initializes tracking by patching history methods and listening\n * to popstate events. Should be called once after instantiation.\n *\n * @returns Promise<void> resolves immediately after setup\n */\n start(): Promise<void> {\n return new Promise((resolve) => {\n this.currentPath = window.location.pathname + window.location.search;\n this.patchHistory();\n this.listenPopState();\n resolve();\n });\n }\n\n /**\n * Patches history.pushState and history.replaceState to intercept\n * route changes and notify the NavigationTracker.\n */\n private patchHistory(): void {\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n const handleChange = () => {\n const newPath = window.location.pathname + window.location.search;\n this.tracker.recordRouteChange(this.currentPath, newPath);\n this.currentPath = newPath;\n };\n\n history.pushState = (\n (data: any, unused: string, url?: string | URL | null) => {\n origPush(data, unused, url);\n handleChange();\n }\n ) as typeof history.pushState;\n\n history.replaceState = (\n (data: any, unused: string, url?: string | URL | null) => {\n origReplace(data, unused, url);\n handleChange();\n }\n ) as typeof history.replaceState;\n }\n\n /**\n * Sets up an event listener for popstate events (back/forward navigation)\n * to detect route changes triggered by browser controls.\n */\n private listenPopState(): void {\n window.addEventListener(\"popstate\", () => {\n const newPath = window.location.pathname + window.location.search;\n this.tracker.recordRouteChange(this.currentPath, newPath);\n this.currentPath = newPath;\n });\n }\n}\n"],"names":["NavigationTrackerWeb","telemetry","NavigationTracker","resolve","origPush","origReplace","handleChange","newPath","data","unused","url"],"mappings":";AAQO,MAAMA,EAAqB;AAAA,EAI9B,YAAoBC,GAAsB;AAAtB,SAAA,YAAAA,GAChB,KAAK,UAAU,IAAIC,EAAkBD,CAAS,GAC9C,KAAK,cAAc;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAuB;AACnB,WAAO,IAAI,QAAQ,CAACE,MAAY;AAC5B,WAAK,cAAc,OAAO,SAAS,WAAW,OAAO,SAAS,QAC9D,KAAK,aAAA,GACL,KAAK,eAAA,GACLA,EAAA;AAAA,IACJ,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAqB;AACzB,UAAMC,IAAW,QAAQ,UAAU,KAAK,OAAO,GACzCC,IAAc,QAAQ,aAAa,KAAK,OAAO,GAE/CC,IAAe,MAAM;AACvB,YAAMC,IAAU,OAAO,SAAS,WAAW,OAAO,SAAS;AAC3D,WAAK,QAAQ,kBAAkB,KAAK,aAAaA,CAAO,GACxD,KAAK,cAAcA;AAAA,IACvB;AAEA,YAAQ,aACJ,CAACC,GAAWC,GAAgBC,MAA8B;AACtD,MAAAN,EAASI,GAAMC,GAAQC,CAAG,GAC1BJ,EAAA;AAAA,IACJ,IAGJ,QAAQ,gBACJ,CAACE,GAAWC,GAAgBC,MAA8B;AACtD,MAAAL,EAAYG,GAAMC,GAAQC,CAAG,GAC7BJ,EAAA;AAAA,IACJ;AAAA,EAER;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAuB;AAC3B,WAAO,iBAAiB,YAAY,MAAM;AACtC,YAAMC,IAAU,OAAO,SAAS,WAAW,OAAO,SAAS;AAC3D,WAAK,QAAQ,kBAAkB,KAAK,aAAaA,CAAO,GACxD,KAAK,cAAcA;AAAA,IACvB,CAAC;AAAA,EACL;AACJ;"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./networkChange-CUO1hRLj.cjs");async function e(){return typeof navigator<"u"&&"connection"in navigator?{type:navigator.connection.type||"unknown",isConnected:navigator.onLine}:{type:"unknown",isConnected:typeof navigator<"u"?navigator.onLine:void 0}}class c{constructor(){}async collect(){return e()}async start(t){this.telemetry=t;const o=new r.NetworkChangeEmitter(t),i=await this.collect();o.onSample(i.type);const n=async()=>o.onSample((await e()).type);return(typeof navigator<"u"?navigator.connection:void 0)?.addEventListener?.("change",n),typeof window<"u"&&(window.addEventListener("online",n),window.addEventListener("offline",n)),i}}exports.NetworkInfoTrackerWeb=c;exports.getNetworkInfo=e;
2
- //# sourceMappingURL=networkInfo.web-DJmw1sNK.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"networkInfo.web-DJmw1sNK.cjs","sources":["../src/adapters/web/networkInfo.web.ts"],"sourcesContent":["// adapters/web/networkInfoWeb.web.ts\nimport { NetworkInfo, Telemetry } from \"../../core/telemetry\";\nimport { NetworkChangeEmitter } from \"../networkChange\";\n\n\n\n\nexport async function getNetworkInfo(): Promise<NetworkInfo> {\n if (typeof navigator !== \"undefined\" && \"connection\" in navigator) {\n const conn = (navigator as any).connection;\n return {\n type: conn.type || \"unknown\",\n isConnected: navigator.onLine,\n // downlink: conn.downlink,\n // effectiveType: conn.effectiveType,\n };\n }\n\n // Fallback\n return {\n type: \"unknown\",\n isConnected: typeof navigator !== \"undefined\" ? navigator.onLine : undefined,\n };\n}\n\nexport class NetworkInfoTrackerWeb {\n // constructor(private telemetry: Telemetry) { }\n constructor() { }\n\n async collect(): Promise<NetworkInfo> {\n return getNetworkInfo();\n }\n\n private telemetry!: Telemetry;\n\n async start(telemetry: Telemetry): Promise<NetworkInfo> {\n // collect() feeds the steady-state Context block (no standalone network_info event,\n // ADR-0002). A connectivity *transition* is its own v3 `network_change` event,\n // emitted via the shared NetworkChangeEmitter (lockstep with native).\n this.telemetry = telemetry;\n const changes = new NetworkChangeEmitter(telemetry);\n const info = await this.collect();\n changes.onSample(info.type); // seed baseline so the first real transition emits\n const sample = async () => changes.onSample((await getNetworkInfo()).type);\n\n const conn = typeof navigator !== \"undefined\" ? (navigator as any).connection : undefined;\n conn?.addEventListener?.(\"change\", sample);\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"online\", sample);\n window.addEventListener(\"offline\", sample);\n }\n return info;\n }\n}\n"],"names":["getNetworkInfo","NetworkInfoTrackerWeb","telemetry","changes","NetworkChangeEmitter","info","sample"],"mappings":"gIAOA,eAAsBA,GAAuC,CACzD,OAAI,OAAO,UAAc,KAAe,eAAgB,UAE7C,CACH,KAFU,UAAkB,WAEjB,MAAQ,UACnB,YAAa,UAAU,MAAA,EAOxB,CACH,KAAM,UACN,YAAa,OAAO,UAAc,IAAc,UAAU,OAAS,MAAA,CAE3E,CAEO,MAAMC,CAAsB,CAE/B,aAAc,CAAE,CAEhB,MAAM,SAAgC,CAClC,OAAOD,EAAA,CACX,CAIA,MAAM,MAAME,EAA4C,CAIpD,KAAK,UAAYA,EACjB,MAAMC,EAAU,IAAIC,EAAAA,qBAAqBF,CAAS,EAC5CG,EAAO,MAAM,KAAK,QAAA,EACxBF,EAAQ,SAASE,EAAK,IAAI,EAC1B,MAAMC,EAAS,SAAYH,EAAQ,UAAU,MAAMH,EAAA,GAAkB,IAAI,EAGzE,OADa,OAAO,UAAc,IAAe,UAAkB,WAAa,SAC1E,mBAAmB,SAAUM,CAAM,EACrC,OAAO,OAAW,MAClB,OAAO,iBAAiB,SAAUA,CAAM,EACxC,OAAO,iBAAiB,UAAWA,CAAM,GAEtCD,CACX,CACJ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"networkInfo.web-twcNn_hc.js","sources":["../src/adapters/web/networkInfo.web.ts"],"sourcesContent":["// adapters/web/networkInfoWeb.web.ts\nimport { NetworkInfo, Telemetry } from \"../../core/telemetry\";\nimport { NetworkChangeEmitter } from \"../networkChange\";\n\n\n\n\nexport async function getNetworkInfo(): Promise<NetworkInfo> {\n if (typeof navigator !== \"undefined\" && \"connection\" in navigator) {\n const conn = (navigator as any).connection;\n return {\n type: conn.type || \"unknown\",\n isConnected: navigator.onLine,\n // downlink: conn.downlink,\n // effectiveType: conn.effectiveType,\n };\n }\n\n // Fallback\n return {\n type: \"unknown\",\n isConnected: typeof navigator !== \"undefined\" ? navigator.onLine : undefined,\n };\n}\n\nexport class NetworkInfoTrackerWeb {\n // constructor(private telemetry: Telemetry) { }\n constructor() { }\n\n async collect(): Promise<NetworkInfo> {\n return getNetworkInfo();\n }\n\n private telemetry!: Telemetry;\n\n async start(telemetry: Telemetry): Promise<NetworkInfo> {\n // collect() feeds the steady-state Context block (no standalone network_info event,\n // ADR-0002). A connectivity *transition* is its own v3 `network_change` event,\n // emitted via the shared NetworkChangeEmitter (lockstep with native).\n this.telemetry = telemetry;\n const changes = new NetworkChangeEmitter(telemetry);\n const info = await this.collect();\n changes.onSample(info.type); // seed baseline so the first real transition emits\n const sample = async () => changes.onSample((await getNetworkInfo()).type);\n\n const conn = typeof navigator !== \"undefined\" ? (navigator as any).connection : undefined;\n conn?.addEventListener?.(\"change\", sample);\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"online\", sample);\n window.addEventListener(\"offline\", sample);\n }\n return info;\n }\n}\n"],"names":["getNetworkInfo","NetworkInfoTrackerWeb","telemetry","changes","NetworkChangeEmitter","info","sample"],"mappings":";AAOA,eAAsBA,IAAuC;AACzD,SAAI,OAAO,YAAc,OAAe,gBAAgB,YAE7C;AAAA,IACH,MAFU,UAAkB,WAEjB,QAAQ;AAAA,IACnB,aAAa,UAAU;AAAA;AAAA;AAAA,EAAA,IAOxB;AAAA,IACH,MAAM;AAAA,IACN,aAAa,OAAO,YAAc,MAAc,UAAU,SAAS;AAAA,EAAA;AAE3E;AAEO,MAAMC,EAAsB;AAAA;AAAA,EAE/B,cAAc;AAAA,EAAE;AAAA,EAEhB,MAAM,UAAgC;AAClC,WAAOD,EAAA;AAAA,EACX;AAAA,EAIA,MAAM,MAAME,GAA4C;AAIpD,SAAK,YAAYA;AACjB,UAAMC,IAAU,IAAIC,EAAqBF,CAAS,GAC5CG,IAAO,MAAM,KAAK,QAAA;AACxB,IAAAF,EAAQ,SAASE,EAAK,IAAI;AAC1B,UAAMC,IAAS,YAAYH,EAAQ,UAAU,MAAMH,EAAA,GAAkB,IAAI;AAGzE,YADa,OAAO,YAAc,MAAe,UAAkB,aAAa,SAC1E,mBAAmB,UAAUM,CAAM,GACrC,OAAO,SAAW,QAClB,OAAO,iBAAiB,UAAUA,CAAM,GACxC,OAAO,iBAAiB,WAAWA,CAAM,IAEtCD;AAAA,EACX;AACJ;"}
@@ -1,17 +0,0 @@
1
- import { Telemetry } from '../core/telemetry';
2
- /**
3
- * Best-effort native tap capture → v3 `user.interaction` (#33). No DOM `target_tag`/
4
- * `target_class` — those are web-only; their absence on native is intentional, not an error.
5
- *
6
- * RN has no global tap stream, so `responderProps()` returns a top-level responder-capture
7
- * handler the consumer spreads onto their app root <View>. It records the tap and returns
8
- * false, so it observes the gesture without ever claiming it.
9
- */
10
- export declare class InteractionEmitter {
11
- private telemetry;
12
- constructor(telemetry: Telemetry);
13
- record(type?: string, extra?: Record<string, any>): Promise<void>;
14
- responderProps(): {
15
- onStartShouldSetResponderCapture: () => boolean;
16
- };
17
- }
@@ -1,16 +0,0 @@
1
- import { Telemetry } from '../../core/telemetry';
2
- /**
3
- * Samples frame deltas via requestAnimationFrame and emits an aggregated
4
- * `frame_render_time` metric (max/p95/dropped_count) once per window — instead of one event
5
- * per dropped frame. The metric shape matches the iOS contract (docs/edgerum-contract.md).
6
- */
7
- export declare class FrameDropTrackerNative {
8
- private telemetry;
9
- private targetFPS;
10
- private windowMs;
11
- private lastFrameTime;
12
- private windowStart;
13
- private deltas;
14
- constructor(telemetry: Telemetry, targetFPS?: number, windowMs?: number);
15
- start(): Promise<void>;
16
- }
@@ -1,23 +0,0 @@
1
- import { Telemetry } from '../../core/telemetry';
2
- /**
3
- * Intercepts global `fetch` calls in React Native to log detailed telemetry data
4
- * about network requests, including timing, method, status, payload sizes, and errors.
5
- *
6
- * Use the `start()` method to begin interception.
7
- */
8
- export declare class NetworkTrackerNative {
9
- private telemetry;
10
- private originalFetch;
11
- constructor(telemetry: Telemetry);
12
- /**
13
- * Starts intercepting global fetch requests.
14
- * Wraps `global.fetch` with telemetry logging.
15
- *
16
- * @returns Promise<void> resolves immediately after interception is set up.
17
- */
18
- start(): Promise<void>;
19
- /**
20
- * Restores the original fetch function, removing the interception.
21
- */
22
- stop(): void;
23
- }
@@ -1,12 +0,0 @@
1
- import { Telemetry } from '../../core/telemetry';
2
- /**
3
- * Hook into React Navigation events
4
- * Usage: pass your navigationContainerRef
5
- */
6
- export declare class NavigationTrackerNative {
7
- private tracker;
8
- private currentRoute?;
9
- constructor(telemetry: Telemetry);
10
- attach(navigationRef: any): void;
11
- private getActiveRouteName;
12
- }
@@ -1,16 +0,0 @@
1
- import { Telemetry } from '../../core/telemetry';
2
- /**
3
- * Samples frame deltas via requestAnimationFrame and emits an aggregated
4
- * `frame_render_time` metric (max/p95/dropped_count) once per window — instead of one event
5
- * per dropped frame. The metric shape matches the iOS contract (docs/edgerum-contract.md).
6
- */
7
- export declare class FrameDropTrackerWeb {
8
- private telemetry;
9
- private targetFPS;
10
- private windowMs;
11
- private lastFrameTime;
12
- private windowStart;
13
- private deltas;
14
- constructor(telemetry: Telemetry, targetFPS?: number, windowMs?: number);
15
- start(): Promise<void>;
16
- }
@@ -1,26 +0,0 @@
1
- import { Telemetry } from '../../core/telemetry';
2
- /**
3
- * Logs JavaScript heap memory usage and pressure level at regular intervals
4
- * in browser environments using the Performance API.
5
- */
6
- export declare class TelemetryMemoryUsageWeb {
7
- private telemetry;
8
- private intervalId;
9
- constructor(telemetry: Telemetry);
10
- /**
11
- * Records a memory_usage metric (value = used heap MB) per sample, on the v3 metric path.
12
- */
13
- recordMemoryUsage(): void;
14
- /**
15
- * Starts periodic memory usage logging at the specified interval.
16
- * Returns a Promise that resolves immediately for async compatibility.
17
- *
18
- * @param intervalMs Interval in milliseconds between samples (default 30s)
19
- * @returns Promise<void>
20
- */
21
- start(intervalMs?: number): Promise<void>;
22
- /**
23
- * Stops the periodic memory logging if running.
24
- */
25
- stop(): void;
26
- }
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./debug-rnOOxFpN.cjs"),l=require("./navigationTracker-B2GMwyKk.cjs");class c{constructor(e){this.startTimes=new Map,this.telemetry=e}startScreen(e){this.startTimes.set(e,Date.now()),this.telemetry.currentScreen=e,this.telemetry.log("navigation",{"navigation.from_screen":this.lastScreen??null,"navigation.to_screen":e,"navigation.method":"screen_start","navigation.route_type":"screen"}),this.lastScreen=e}endScreen(e){const t=this.startTimes.get(e);if(!t)return;const s=Date.now()-t;this.startTimes.delete(e),this.telemetry.log("screen.duration",{"screen.name":e,"screen.duration_ms":s,"screen.exit_method":"navigation"})}}class d{constructor(e=20){this.max=e,this.items=[]}add(e){this.items.push(e),this.items.length>this.max&&this.items.shift()}list(){return[...this.items]}toJSON(){return JSON.stringify(this.items)}}function u(h=16){let e="";for(let t=0;t<h;t++)e+=Math.floor(Math.random()*16).toString(16);return e}const f="3.0.0",m="react-native",g=f,v=1800*1e3,w=new Set(["session.started","session.finalized","app_lifecycle","page_load","navigation","screen.duration","http.request","user.interaction","network_change","user.profile.update","custom_event","app.crash","resource_timing","frame_render_time","memory_usage","long_task","LCP","FCP","CLS","INP","TTFB"]);class y{constructor(e){this.queue=[],this.intervalId=null,this.userId=void 0,this.userProfile=void 0,this.eventCount=0,this.breadcrumbs=new d(20),this.sessionSequence=0,this.sessionEventCount=0,this.errorCount=0,this.sender=e?.sender,this.batchSize=e?.batchSize??2,this.flushIntervalMs=e?.flushIntervalMs??1e4,this.endpoint=e?.endpoint,this.platform=e?.platform,this.sessionId=e?.sessionId??this.generateSessionId(),this.userId=e?.userId??this.generateUserId(),this.sessionStart=Date.now(),this.sdkVersion=e?.sdkVersion??g,this.sender?.replayFailed&&this.sender.replayFailed().catch(t=>{r.debug.warn("Telemetry replay failed Telemetry class:",t)}),this.flushIntervalMs>0&&(this.intervalId=setInterval(()=>this.flush().catch(()=>{}),this.flushIntervalMs)),this.navigationTracker=new l.NavigationTracker(this),this.screens=new c(this),this.deviceInfoHandler=e?.deviceInfoHandler??{start:async()=>Promise.resolve(),collect:async()=>Promise.resolve({app:{name:"",version:""},device:{id:"",platform:""}})},this.networkInfoHandler=e?.networkInfoHandler??{start:async()=>Promise.resolve({}),collect:async()=>Promise.resolve({})}}trackErrors(e,t){this.crashHandler=e,e.attach(t).catch(s=>{r.debug.warn("Telemetry crashHandler attach failed:",s)})}getDeviceInfo(e){this.deviceInfoHandler=e,e.start(this).catch(t=>{r.debug.warn("Telemetry deviceInfo tracking start failed:",t)})}getNetworkInfo(e){this.networkInfoHandler=e,e.start(this).catch(t=>{r.debug.warn("Telemetry networkInfoHandler start failed:",t)})}trackFrameDrops(e){this.frameDropsHandler=e,e.start().catch(t=>{r.debug.warn("Telemetry frameDropsHandler start failed:",t)})}trackNetworkRequests(e){this.networkHandler=e,e.start().catch(t=>{r.debug.warn("Telemetry networkHandler start failed:",t)})}trackMemoryUsage(e){this.memoryHandler=e,e.recordMemoryUsage().catch(t=>{r.debug.warn("Telemetry memoryHandler recordMemoryUsage failed:",t)})}autoTrackNavigation(e){this.navigationHandler=e,e?.start().catch(t=>{r.debug.warn("Telemetry navigationHandler start failed:",t)})}generateSessionId(){const e=`session_${Date.now()}_${u(16)}`;return this.platform?`${e}_${this.platform}`:e}setSessionId(e){this.sessionId=e,this.sessionStart=Date.now()}getSessionId(){return this.sessionId}getEndpoint(){return this.endpoint}startNewSession(){this.sessionId=this.generateSessionId(),this.sessionStart=Date.now()}async startSession(){this.lastActivity=Date.now(),await this.log("session.started",{})}async finalizeSession(){await this.log("session.finalized",{"session.duration_ms":Date.now()-this.sessionStart,"session.event_count":this.sessionEventCount,"sdk.error_count":this.errorCount}),await this.flush()}async newSession(){this.sessionId=this.generateSessionId(),this.sessionStart=Date.now(),this.sessionSequence=0,this.sessionEventCount=0,this.errorCount=0,await this.startSession()}async rotateSession(){await this.finalizeSession(),await this.newSession()}setUserId(e){this.userId=e}getUserId(){return this.userId}generateUserId(){return`user_${Date.now()}_${u(16)}`}setUserProfile(e){const t=Date.now(),s=!this.userProfile||e.userId&&e.userId!==this.userProfile.userId;this.userProfile={...this.userProfile,...e,updatedAt:t,...s&&{createdAt:t}},e.userId?this.userId=e.userId:this.userProfile&&!this.userProfile.userId&&(this.userProfile.userId=this.userId||void 0),r.debug.log("Telemetry: User profile updated",this.userProfile)}async identify(e){this.setUserProfile({fullName:e.name,email:e.email,phone:e.phone,avatar:e.avatar,customAttributes:e.customAttributes}),await this.log("user.profile.update",{})}setUserDetails(e){this.setUserProfile(e)}updateUserProfile(e){if(!this.userProfile){this.setUserProfile(e);return}this.userProfile={...this.userProfile,...e,updatedAt:Date.now()},r.debug.log("Telemetry: User profile updated",this.userProfile)}getUserProfile(){return this.userProfile}clearUserProfile(){this.userProfile=void 0,r.debug.log("Telemetry: User profile cleared")}setUserName(e,t,s){this.setUserProfile({fullName:e,firstName:t,lastName:s})}setUserContact(e,t){this.setUserProfile({email:e,phone:t})}async log(e,t){if(this.eventCount++,!e.startsWith("session.")){const o=Date.now();this.lastActivity!==void 0&&o-this.lastActivity>v&&await this.rotateSession(),this.lastActivity=o,this.sessionEventCount++,e==="app.crash"&&this.errorCount++}const s=w.has(e),n=s?e:"custom_event",i=await this.collectContext(t);s||(i["event.name"]=e),n==="app.crash"?i["crash.breadcrumbs"]=this.breadcrumbs.toJSON():this.breadcrumbs.add({name:n,timestamp:new Date().toISOString()});const a={type:"event",eventName:n,timestamp:new Date().toISOString(),attributes:i};this.queue.push(a),r.debug.log("Telemetry queued event:",e,"Queue size:",this.queue.length),r.debug.log("Event attributes:",i),this.queue.length>=this.batchSize&&this.flush()}async collectContext(e){let t={},s={};try{t=await this.deviceInfoHandler?.collect()||{}}catch(i){r.debug.warn("Telemetry: failed to fetch device info",i)}try{s=await this.networkInfoHandler?.collect()||{}}catch(i){r.debug.warn("Telemetry: failed to fetch network info",i)}const n={...this.flattenWithPrefix("",t),...this.flattenWithPrefix("network",s),...this.flattenWithPrefix("",e||{}),"user.id":this.userId??null,"session.id":this.sessionId,"session.start_time":new Date(this.sessionStart).toISOString(),"session.sequence":this.sessionSequence,"sdk.platform":m,"sdk.version":this.sdkVersion};if(this.userProfile){const i={"user.name":this.userProfile.fullName,"user.fullName":this.userProfile.fullName,"user.firstName":this.userProfile.firstName,"user.lastName":this.userProfile.lastName,"user.email":this.userProfile.email,"user.phone":this.userProfile.phone,"user.avatar":this.userProfile.avatar,"user.createdAt":this.userProfile.createdAt,"user.updatedAt":this.userProfile.updatedAt,...this.flattenWithPrefix("user.custom",this.userProfile.customAttributes||{})};Object.entries(i).forEach(([a,o])=>{o!==void 0&&(n[a]=o)})}return n}async logMetric(e,t,s){this.eventCount++;const n=await this.collectContext(s),i={type:"metric",metricName:e,value:t,timestamp:new Date().toISOString(),attributes:n};this.queue.push(i),this.queue.length>=this.batchSize&&this.flush()}flattenWithPrefix(e,t){const s={};for(const n in t){if(!Object.prototype.hasOwnProperty.call(t,n))continue;const i=t[n],a=e?`${e}.${n}`:n;typeof i=="object"&&i!==null&&!Array.isArray(i)?Object.assign(s,this.flattenWithPrefix(a,i)):s[a]=i}return s}recordMetric(e,t,s){return this.logMetric(e,t,s)}async flush(){if(!this.sender||this.queue.length===0)return;const e=this.queue.splice(0,this.batchSize);try{await this.sender.send(e),this.sessionSequence++}catch(t){if(this.sender.onFailure)try{await this.sender.onFailure(e)}catch(s){this.queue.unshift(...e),r.debug.warn("Sender.onFailure failed, requeued events:",s)}else this.queue.unshift(...e);throw r.debug.error("Telemetry flush failed:",t),t}}getQueue(){return[...this.queue]}async shutdown(){this.intervalId&&clearInterval(this.intervalId),await this.flush()}getEventCount(){return this.eventCount}recordRouteChange(e,t){return this.currentScreen=t,this.navigationTracker?.recordRouteChange(e,t)}}exports.Telemetry=y;
2
- //# sourceMappingURL=telemetry-Co4MYdwa.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"telemetry-Co4MYdwa.cjs","sources":["../src/adapters/screenTiming.ts","../src/core/breadcrumbs.ts","../src/core/utils/uuid.ts","../src/core/telemetry.ts"],"sourcesContent":["import { Telemetry } from \"../core/telemetry\";\n\nexport class ScreenTimingTracker {\n private telemetry: Telemetry;\n private startTimes: Map<string, number> = new Map();\n private lastScreen?: string;\n\n constructor(telemetry: Telemetry) {\n this.telemetry = telemetry;\n }\n\n // Screen entry → v3 `navigation` (replaces v2 screen_view). Baseline shape follows the\n // reference/Angular keys; iOS reconciliation is OPEN (see additions ledger).\n startScreen(screen: string) {\n this.startTimes.set(screen, Date.now());\n this.telemetry.currentScreen = screen; // best-effort screen for user.interaction taps (#33)\n this.telemetry.log(\"navigation\", {\n \"navigation.from_screen\": this.lastScreen ?? null,\n \"navigation.to_screen\": screen,\n \"navigation.method\": \"screen_start\",\n \"navigation.route_type\": \"screen\",\n });\n this.lastScreen = screen;\n }\n\n // Screen exit → v3 `screen.duration` with dwell ms (replaces screen_end + performance.screen_duration).\n endScreen(screen: string) {\n const start = this.startTimes.get(screen);\n if (!start) return;\n\n const duration = Date.now() - start;\n this.startTimes.delete(screen);\n\n this.telemetry.log(\"screen.duration\", {\n \"screen.name\": screen,\n \"screen.duration_ms\": duration,\n \"screen.exit_method\": \"navigation\",\n });\n }\n}\n","/**\n * Fixed-size ring buffer of recent actions, attached to `app.crash` as the\n * JSON-stringified `crash.breadcrumbs` (last N, oldest evicted first). See #28.\n */\nexport class BreadcrumbBuffer {\n private items: any[] = [];\n\n constructor(private max = 20) {}\n\n add(item: any): void {\n this.items.push(item);\n if (this.items.length > this.max) this.items.shift();\n }\n\n list(): any[] {\n return [...this.items];\n }\n\n toJSON(): string {\n return JSON.stringify(this.items);\n }\n}\n","// Platform-agnostic id generator. The web/native split was byte-identical, so it's gone.\n// ponytail: Math.random ids are fine for session/user correlation; swap to crypto/uuid\n// (e.g. react-native-get-random-values + uuid) here if collision-resistance ever matters.\nexport function generateId() {\n return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);\n}\n\n// v3 wire contract: ids carry a 16-hex-char (64-bit) random segment.\n// ponytail: Math.random hex is fine for session/user correlation; swap to\n// crypto/SecRandom here if collision-resistance ever matters.\nexport function randomHex(length = 16): string {\n let out = \"\";\n for (let i = 0; i < length; i++) out += Math.floor(Math.random() * 16).toString(16);\n return out;\n}\n","import { debug } from \"./debug\";\nimport { NavigationTracker } from \"../adapters/navigationTracker\";\nimport { ScreenTimingTracker } from \"../adapters/screenTiming\";\nimport { BreadcrumbBuffer } from \"./breadcrumbs\";\nimport { randomHex } from \"./utils/uuid\";\nimport { version as PKG_VERSION } from \"../../package.json\";\n\n// v3 wire contract constants\nconst SDK_PLATFORM = \"react-native\"; // framework identity; device OS lives in device.platform\nconst SDK_VERSION = PKG_VERSION; // sdk.version follows the published package version\nconst SESSION_IDLE_MS = 30 * 60 * 1000; // rotate the session after 30 min of inactivity (iOS ADR-004)\n\n// Names the backend routes. Anything else is remapped to `custom_event` with the\n// original name carried as `event.name`. Includes metric names so the metric path\n// (slice: native metrics) isn't remapped.\nconst ALLOWED_NAMES = new Set<string>([\n \"session.started\", \"session.finalized\", \"app_lifecycle\", \"page_load\", \"navigation\",\n \"screen.duration\", \"http.request\", \"user.interaction\", \"network_change\",\n \"user.profile.update\", \"custom_event\", \"app.crash\",\n \"resource_timing\", \"frame_render_time\", \"memory_usage\", \"long_task\",\n \"LCP\", \"FCP\", \"CLS\", \"INP\", \"TTFB\",\n]);\n\n// Events carry `eventName`; metrics carry `metricName` + numeric `value` (v3 §\"Event vs Metric\").\n// Kept as one loose shape (not a strict union) so callers can read `.eventName` without narrowing;\n// the emit helpers (log / logMetric) set the right fields, and JSON.stringify drops the undefined ones.\nexport type TelemetryEvent = {\n type: 'event' | 'metric';\n eventName?: string;\n metricName?: string;\n value?: number;\n timestamp: string; // ISO 8601 (v3 wire contract) — never ms epoch\n attributes?: Record<string, any>;\n};\n\nexport interface Sender {\n send(events: TelemetryEvent[]): Promise<void>;\n onFailure?(events: TelemetryEvent[]): Promise<void>;\n replayFailed?(): Promise<void>;\n}\n\n\n\nexport interface CrashHandlerOptions {\n captureConsole?: boolean; // funnel console.error/warn into app.crash (default on, opt-out)\n}\n\nexport interface CrashHandler {\n attach(options?: CrashHandlerOptions): Promise<void>;\n}\nexport interface NetworkInfo {\n type?: string; // \"wifi\", \"cellular\", \"ethernet\", \"unknown\", etc.\n isConnected?: boolean;\n}\n\nexport interface WebExtraNetworkInfo {\n type?: string;\n isConnected?: boolean;\n downlink?: number; // Mbps estimate\n effectiveType?: string; // \"4g\", \"3g\", etc.\n}\n\nexport interface NetworkInfoHandler {\n start(telemetry: Telemetry): Promise<NetworkInfo>;\n collect(): Promise<NetworkInfo>;\n}\n\nexport interface DeviceInfoHandler {\n start(telemetry: Telemetry): Promise<void>;\n collect(): Promise<DeviceInfo>;\n}\nexport interface FrameDropsHandler {\n start(): Promise<void>;\n}\n\nexport interface NetworkHandler {\n start(): Promise<void>;\n}\n\nexport interface MemoryHandler {\n recordMemoryUsage(): Promise<void>;\n}\n\nexport interface NavigationHandler {\n start(): Promise<void>;\n}\n\n\nexport interface DeviceInfo {\n app: {\n name: string;\n version: string;\n buildNumber?: string;\n packageName?: string;\n };\n device: {\n id: string;\n platform: string;\n platformVersion?: string;\n model?: string;\n manufacturer?: string;\n brand?: string;\n androidSdk?: string;\n androidRelease?: string;\n fingerprint?: string;\n hardware?: string;\n product?: string;\n iosSystemName?: string;\n iosDeviceName?: string;\n };\n}\n\nexport interface UserProfile {\n userId?: string;\n fullName?: string;\n firstName?: string;\n lastName?: string;\n email?: string;\n phone?: string;\n avatar?: string;\n customAttributes?: Record<string, any>;\n createdAt?: number;\n updatedAt?: number;\n}\n\n\ntype Opts = {\n sender?: Sender;\n batchSize?: number;\n flushIntervalMs?: number;\n endpoint?: string;\n sessionId?: string;\n userId?: string | null;\n sdkVersion?: string;\n platform?: string; // device OS (ios|android|web); forms the device/session id suffix\n deviceInfoHandler?: DeviceInfoHandler;\n networkInfoHandler?: NetworkInfoHandler;\n};\n\n/**\n * Telemetry core: queueing, batching, retries, auto-replay and session/user management.\n * Keeps the external API you already use: log(name, data?), flush(), shutdown().\n */\nexport class Telemetry {\n private queue: TelemetryEvent[] = [];\n private sender?: Sender;\n private batchSize: number;\n private flushIntervalMs: number;\n private intervalId: any = null;\n private endpoint?: string;\n private crashHandler?: CrashHandler;\n private navigationTracker?: NavigationTracker;\n // single screen-tracking API (timed); used by the native screenStart/screenEnd\n public screens: ScreenTimingTracker;\n // last-known screen; best-effort context for user.interaction taps (#33)\n public currentScreen?: string;\n\n private networkInfoHandler: NetworkInfoHandler;\n private deviceInfoHandler: DeviceInfoHandler;\n\n private frameDropsHandler?: FrameDropsHandler;\n private networkHandler?: NetworkHandler;\n private memoryHandler?: MemoryHandler;\n private navigationHandler?: NavigationHandler;\n\n\n // session / user state\n private userId?: string | null = undefined;\n private userProfile?: UserProfile = undefined;\n private sessionId: string;\n private sessionStart: number;\n private sdkVersion: string;\n private platform?: string;\n private eventCount = 0;\n // last-20 action trail, attached to app.crash as crash.breadcrumbs (#28)\n private breadcrumbs = new BreadcrumbBuffer(20);\n // session lifecycle (#29)\n private lastActivity?: number; // last non-session event time; drives 30-min idle rotation\n private sessionSequence = 0; // increments per acknowledged (2xx) batch\n private sessionEventCount = 0; // events this session (journey summary)\n private errorCount = 0; // app.crash count this session (sdk.error_count)\n\n constructor(opts?: Opts) {\n this.sender = opts?.sender;\n this.batchSize = opts?.batchSize ?? 2;\n this.flushIntervalMs = opts?.flushIntervalMs ?? 10000;\n this.endpoint = opts?.endpoint;\n this.platform = opts?.platform; // set before id generation (suffix source)\n\n // start a session\n this.sessionId = opts?.sessionId ?? this.generateSessionId();\n this.userId = opts?.userId ?? this.generateUserId();\n this.sessionStart = Date.now();\n this.sdkVersion = opts?.sdkVersion ?? SDK_VERSION;\n\n // auto replay if supported\n if (this.sender?.replayFailed) {\n // don't block constructor; best-effort\n this.sender.replayFailed().catch((err: any) => {\n debug.warn(\"Telemetry replay failed Telemetry class:\", err);\n });\n }\n\n if (this.flushIntervalMs > 0) {\n this.intervalId = setInterval(() => this.flush().catch(() => { }), this.flushIntervalMs);\n }\n\n this.navigationTracker = new NavigationTracker(this);\n this.screens = new ScreenTimingTracker(this);\n\n this.deviceInfoHandler = opts?.deviceInfoHandler ?? {\n start: async () => Promise.resolve(),\n collect: async () => Promise.resolve({\n app: { name: '', version: '' },\n device: { id: '', platform: '' }\n })\n };\n this.networkInfoHandler = opts?.networkInfoHandler ?? {\n start: async () => Promise.resolve({}),\n collect: async () => Promise.resolve({})\n };\n\n }\n\n // ---------- Session & User APIs ----------\n\n public trackErrors(crashHandler: CrashHandler, options?: CrashHandlerOptions) {\n this.crashHandler = crashHandler;\n void crashHandler.attach(options).catch((err) => {\n debug.warn(\"Telemetry crashHandler attach failed:\", err);\n });\n }\n\n getDeviceInfo(deviceInfoHandler: DeviceInfoHandler) {\n this.deviceInfoHandler = deviceInfoHandler;\n void deviceInfoHandler.start(this).catch((err) => {\n debug.warn(\"Telemetry deviceInfo tracking start failed:\", err);\n });\n }\n\n getNetworkInfo(networkInfoHandler: NetworkInfoHandler) {\n this.networkInfoHandler = networkInfoHandler;\n void networkInfoHandler.start(this).catch((err) => {\n debug.warn(\"Telemetry networkInfoHandler start failed:\", err);\n });\n }\n\n public trackFrameDrops(frameDropsHandler: FrameDropsHandler) {\n this.frameDropsHandler = frameDropsHandler;\n void frameDropsHandler.start().catch((err) => {\n debug.warn(\"Telemetry frameDropsHandler start failed:\", err);\n });\n }\n\n public trackNetworkRequests(networkHandler: NetworkHandler) {\n this.networkHandler = networkHandler;\n void networkHandler.start().catch((err) => {\n debug.warn(\"Telemetry networkHandler start failed:\", err);\n });\n }\n\n public trackMemoryUsage(memoryHandler: MemoryHandler) {\n this.memoryHandler = memoryHandler;\n void memoryHandler.recordMemoryUsage().catch((err) => {\n debug.warn(\"Telemetry memoryHandler recordMemoryUsage failed:\", err);\n });\n }\n\n public autoTrackNavigation(navigationHandler?: NavigationHandler) {\n this.navigationHandler = navigationHandler;\n void navigationHandler?.start().catch((err) => {\n debug.warn(\"Telemetry navigationHandler start failed:\", err);\n });\n }\n\n\n private generateSessionId(): string {\n const base = `session_${Date.now()}_${randomHex(16)}`;\n return this.platform ? `${base}_${this.platform}` : base;\n }\n\n public setSessionId(id: string) {\n this.sessionId = id;\n this.sessionStart = Date.now();\n }\n\n public getSessionId(): string {\n return this.sessionId;\n }\n\n /** Collector endpoint, so fetch/XHR adapters can skip self-capturing the SDK's own POST. */\n public getEndpoint(): string | undefined {\n return this.endpoint;\n }\n\n public startNewSession() {\n this.sessionId = this.generateSessionId();\n this.sessionStart = Date.now();\n }\n\n // ---------- Session lifecycle (#29) ----------\n\n /** Emit session.started for the current session (init / resume). */\n public async startSession() {\n this.lastActivity = Date.now();\n await this.log(\"session.started\", {});\n }\n\n /** Finalize the current session: journey summary + sdk.error_count, then an immediate flush. */\n public async finalizeSession() {\n await this.log(\"session.finalized\", {\n \"session.duration_ms\": Date.now() - this.sessionStart,\n \"session.event_count\": this.sessionEventCount,\n \"sdk.error_count\": this.errorCount,\n });\n await this.flush();\n }\n\n /** Begin a fresh session: new id/start, reset per-session counters, emit session.started. */\n public async newSession() {\n this.sessionId = this.generateSessionId();\n this.sessionStart = Date.now();\n this.sessionSequence = 0;\n this.sessionEventCount = 0;\n this.errorCount = 0;\n await this.startSession();\n }\n\n /** Idle/boundary rotation: finalize the old session then start a fresh one (the pair). */\n public async rotateSession() {\n await this.finalizeSession();\n await this.newSession();\n }\n\n public setUserId(id: string) {\n this.userId = id;\n }\n\n public getUserId(): string | undefined | null {\n return this.userId;\n }\n\n public generateUserId(): string {\n return `user_${Date.now()}_${randomHex(16)}`;\n }\n\n // ---------- User Profile Management ----------\n\n /**\n * Set complete user profile information\n */\n public setUserProfile(profile: Partial<UserProfile>): void {\n const now = Date.now();\n \n // If this is a new profile or userId changed, set createdAt\n const isNewProfile = !this.userProfile || (profile.userId && profile.userId !== this.userProfile.userId);\n \n this.userProfile = {\n ...this.userProfile,\n ...profile,\n updatedAt: now,\n ...(isNewProfile && { createdAt: now })\n };\n\n // Update userId if provided in profile\n if (profile.userId) {\n this.userId = profile.userId;\n } else if (this.userProfile && !this.userProfile.userId) {\n // Set current userId in profile if not provided\n this.userProfile.userId = this.userId || undefined;\n }\n\n debug.log(\"Telemetry: User profile updated\", this.userProfile);\n }\n\n /**\n * EdgeRum-style identify(): attach host-app identity (name/email/phone) to subsequent\n * events and emit one `user.profile.update`. The SDK-owned anonymous `user.id` is\n * preserved — identify never changes it. (#31)\n */\n public async identify(profile: {\n name?: string;\n email?: string;\n phone?: string;\n avatar?: string;\n customAttributes?: Record<string, any>;\n }) {\n this.setUserProfile({\n fullName: profile.name,\n email: profile.email,\n phone: profile.phone,\n avatar: profile.avatar,\n customAttributes: profile.customAttributes,\n });\n await this.log(\"user.profile.update\", {});\n }\n\n /**\n * Set user details with individual parameters\n */\n public setUserDetails(details: {\n fullName?: string;\n firstName?: string;\n lastName?: string;\n email?: string;\n phone?: string;\n avatar?: string;\n customAttributes?: Record<string, any>;\n }): void {\n this.setUserProfile(details);\n }\n\n /**\n * Update specific user profile fields\n */\n public updateUserProfile(updates: Partial<UserProfile>): void {\n if (!this.userProfile) {\n // If no profile exists, create one\n this.setUserProfile(updates);\n return;\n }\n\n this.userProfile = {\n ...this.userProfile,\n ...updates,\n updatedAt: Date.now()\n };\n\n debug.log(\"Telemetry: User profile updated\", this.userProfile);\n }\n\n /**\n * Get current user profile\n */\n public getUserProfile(): UserProfile | undefined {\n return this.userProfile;\n }\n\n /**\n * Clear user profile data\n */\n public clearUserProfile(): void {\n this.userProfile = undefined;\n debug.log(\"Telemetry: User profile cleared\");\n }\n\n /**\n * Set user name (convenience method)\n */\n public setUserName(fullName: string, firstName?: string, lastName?: string): void {\n this.setUserProfile({\n fullName,\n firstName,\n lastName\n });\n }\n\n /**\n * Set user contact info (convenience method)\n */\n public setUserContact(email?: string, phone?: string): void {\n this.setUserProfile({\n email,\n phone\n });\n }\n\n // ---------- Logging APIs ----------\n\n /**\n * Log a named event. Keeps existing signature compatibility.\n * Automatically attaches userId and sessionId to every queued event.\n */\n async log(name: string, data?: Record<string, any>) {\n this.eventCount++;\n\n // Session activity & 30-min idle rotation. Session events don't count as activity\n // (they're emitted *by* the lifecycle), so they never re-trigger rotation.\n if (!name.startsWith('session.')) {\n const now = Date.now();\n if (this.lastActivity !== undefined && now - this.lastActivity > SESSION_IDLE_MS) {\n await this.rotateSession();\n }\n this.lastActivity = now;\n this.sessionEventCount++;\n if (name === 'app.crash') this.errorCount++;\n }\n\n // v3 allowlist: unknown names ship as custom_event, original kept as event.name\n const isAllowed = ALLOWED_NAMES.has(name);\n const eventName = isAllowed ? name : 'custom_event';\n\n const attributes = await this.collectContext(data);\n if (!isAllowed) attributes['event.name'] = name;\n\n // app.crash carries the trail of prior actions; other events extend the trail.\n if (eventName === 'app.crash') {\n attributes['crash.breadcrumbs'] = this.breadcrumbs.toJSON();\n } else {\n this.breadcrumbs.add({ name: eventName, timestamp: new Date().toISOString() });\n }\n\n const e: TelemetryEvent = {\n type: 'event',\n eventName,\n timestamp: new Date().toISOString(),\n attributes,\n };\n\n this.queue.push(e);\n\n debug.log(\"Telemetry queued event:\", name, \"Queue size:\", this.queue.length);\n debug.log(\"Event attributes:\", attributes);\n\n if (this.queue.length >= this.batchSize) {\n void this.flush();\n }\n\n\n }\n\n /**\n * Build the v3 Context block that rides on every event AND metric: the flattened\n * device/network snapshot, the caller's data, identity + session + sdk fields, and the\n * user profile. Shared by log() and logMetric() so both carry the identical iOS-clean set.\n */\n private async collectContext(data?: Record<string, any>): Promise<Record<string, any>> {\n let deviceInfo: Record<string, any> = {};\n let networkInfo: Record<string, any> = {};\n\n try {\n deviceInfo = (await this.deviceInfoHandler?.collect()) || {};\n } catch (err) {\n debug.warn(\"Telemetry: failed to fetch device info\", err);\n }\n\n try {\n networkInfo = (await this.networkInfoHandler?.collect()) || {};\n } catch (err) {\n debug.warn(\"Telemetry: failed to fetch network info\", err);\n }\n\n const attributes: Record<string, any> = {\n // deviceInfo already namespaces its own keys (app.*, device.*) — flatten flat\n ...this.flattenWithPrefix('', deviceInfo),\n ...this.flattenWithPrefix('network', networkInfo),\n ...this.flattenWithPrefix('', data || {}),\n 'user.id': this.userId ?? null,\n 'session.id': this.sessionId,\n 'session.start_time': new Date(this.sessionStart).toISOString(),\n 'session.sequence': this.sessionSequence,\n 'sdk.platform': SDK_PLATFORM,\n 'sdk.version': this.sdkVersion,\n };\n\n if (this.userProfile) {\n const userProfileData = {\n 'user.name': this.userProfile.fullName, // v3 contract key for host identity\n 'user.fullName': this.userProfile.fullName,\n 'user.firstName': this.userProfile.firstName,\n 'user.lastName': this.userProfile.lastName,\n 'user.email': this.userProfile.email,\n 'user.phone': this.userProfile.phone,\n 'user.avatar': this.userProfile.avatar,\n 'user.createdAt': this.userProfile.createdAt,\n 'user.updatedAt': this.userProfile.updatedAt,\n ...this.flattenWithPrefix('user.custom', this.userProfile.customAttributes || {})\n };\n Object.entries(userProfileData).forEach(([key, value]) => {\n if (value !== undefined) attributes[key] = value;\n });\n }\n\n return attributes;\n }\n\n /**\n * Emit a metric on the v3 `type:\"metric\"` path: { type, metricName, value, timestamp, attributes }.\n * Carries the same Context block as events. Metrics are samples, not user actions, so they\n * don't extend the breadcrumb trail and don't count as session activity — a periodic sampler\n * (memory/frames) must not keep a session alive and defeat the 30-min idle rotation.\n */\n async logMetric(metricName: string, value: number, data?: Record<string, any>) {\n this.eventCount++;\n const attributes = await this.collectContext(data);\n\n const m: TelemetryEvent = {\n type: 'metric',\n metricName,\n value,\n timestamp: new Date().toISOString(),\n attributes,\n };\n\n this.queue.push(m);\n if (this.queue.length >= this.batchSize) {\n void this.flush();\n }\n }\n\n private flattenWithPrefix(prefix: string, obj: Record<string, any>): Record<string, any> {\n const result: Record<string, any> = {};\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const prefixedKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n Object.assign(result, this.flattenWithPrefix(prefixedKey, value));\n } else {\n result[prefixedKey] = value;\n }\n }\n\n return result;\n }\n\n\n\n /**\n * Explicit metric helper (optional convenience) — routes through the v3 metric path.\n */\n recordMetric(name: string, value: number, data?: Record<string, any>) {\n return this.logMetric(name, value, data);\n }\n\n // ---------- Flush / Persistence ----------\n\n // Retry + backoff live in the Sender (see sendWithRetry in web/native senders),\n // which is also used by the standalone replay paths. flush() does a single send\n // and, on failure, hands the batch to the sender to persist (or requeues it).\n async flush() {\n if (!this.sender || this.queue.length === 0) return;\n\n // build a batch of up to batchSize\n const toSend = this.queue.splice(0, this.batchSize);\n\n try {\n await this.sender.send(toSend);\n this.sessionSequence++; // acknowledged (2xx) batch — order a session's batches (#29)\n } catch (lastError) {\n if (this.sender.onFailure) {\n try {\n await this.sender.onFailure(toSend);\n } catch (persistErr) {\n // If persistence fails, requeue to avoid data loss\n this.queue.unshift(...toSend);\n debug.warn(\"Sender.onFailure failed, requeued events:\", persistErr);\n }\n } else {\n this.queue.unshift(...toSend);\n }\n\n debug.error(\"Telemetry flush failed:\", lastError);\n throw lastError;\n }\n }\n\n getQueue() {\n return [...this.queue];\n }\n\n async shutdown() {\n if (this.intervalId) clearInterval(this.intervalId);\n await this.flush();\n }\n\n // Screen tracking lives in ScreenTimingTracker (this.screens), the single timed API.\n\n // Expose some internal counters (optional)\n getEventCount() {\n return this.eventCount;\n }\n\n recordRouteChange(from: string, to: string) {\n this.currentScreen = to; // best-effort screen for subsequent taps (#33)\n return this.navigationTracker?.recordRouteChange(from, to);\n }\n\n\n}\n\n"],"names":["ScreenTimingTracker","telemetry","screen","start","duration","BreadcrumbBuffer","max","item","randomHex","length","out","i","SDK_PLATFORM","SDK_VERSION","PKG_VERSION","SESSION_IDLE_MS","ALLOWED_NAMES","Telemetry","opts","err","debug","NavigationTracker","crashHandler","options","deviceInfoHandler","networkInfoHandler","frameDropsHandler","networkHandler","memoryHandler","navigationHandler","base","id","profile","now","isNewProfile","details","updates","fullName","firstName","lastName","email","phone","name","data","isAllowed","eventName","attributes","e","deviceInfo","networkInfo","userProfileData","key","value","metricName","m","prefix","obj","result","prefixedKey","toSend","lastError","persistErr","from","to"],"mappings":"sKAEO,MAAMA,CAAoB,CAK7B,YAAYC,EAAsB,CAHlC,KAAQ,eAAsC,IAI1C,KAAK,UAAYA,CACrB,CAIA,YAAYC,EAAgB,CACxB,KAAK,WAAW,IAAIA,EAAQ,KAAK,KAAK,EACtC,KAAK,UAAU,cAAgBA,EAC/B,KAAK,UAAU,IAAI,aAAc,CAC7B,yBAA0B,KAAK,YAAc,KAC7C,uBAAwBA,EACxB,oBAAqB,eACrB,wBAAyB,QAAA,CAC5B,EACD,KAAK,WAAaA,CACtB,CAGA,UAAUA,EAAgB,CACtB,MAAMC,EAAQ,KAAK,WAAW,IAAID,CAAM,EACxC,GAAI,CAACC,EAAO,OAEZ,MAAMC,EAAW,KAAK,IAAA,EAAQD,EAC9B,KAAK,WAAW,OAAOD,CAAM,EAE7B,KAAK,UAAU,IAAI,kBAAmB,CAClC,cAAeA,EACf,qBAAsBE,EACtB,qBAAsB,YAAA,CACzB,CACL,CACJ,CCnCO,MAAMC,CAAiB,CAG5B,YAAoBC,EAAM,GAAI,CAAV,KAAA,IAAAA,EAFpB,KAAQ,MAAe,CAAA,CAEQ,CAE/B,IAAIC,EAAiB,CACnB,KAAK,MAAM,KAAKA,CAAI,EAChB,KAAK,MAAM,OAAS,KAAK,KAAK,KAAK,MAAM,MAAA,CAC/C,CAEA,MAAc,CACZ,MAAO,CAAC,GAAG,KAAK,KAAK,CACvB,CAEA,QAAiB,CACf,OAAO,KAAK,UAAU,KAAK,KAAK,CAClC,CACF,CCXO,SAASC,EAAUC,EAAS,GAAY,CAC3C,IAAIC,EAAM,GACV,QAASC,EAAI,EAAGA,EAAIF,EAAQE,IAAKD,GAAO,KAAK,MAAM,KAAK,OAAA,EAAW,EAAE,EAAE,SAAS,EAAE,EAClF,OAAOA,CACX,iBCNME,EAAe,eACfC,EAAcC,EACdC,EAAkB,KAAU,IAK5BC,MAAoB,IAAY,CAClC,kBAAmB,oBAAqB,gBAAiB,YAAa,aACtE,kBAAmB,eAAgB,mBAAoB,iBACvD,sBAAuB,eAAgB,YACvC,kBAAmB,oBAAqB,eAAgB,YACxD,MAAO,MAAO,MAAO,MAAO,MAChC,CAAC,EA0HM,MAAMC,CAAU,CAuCnB,YAAYC,EAAa,CAtCzB,KAAQ,MAA0B,CAAA,EAIlC,KAAQ,WAAkB,KAmB1B,KAAQ,OAAyB,OACjC,KAAQ,YAA4B,OAKpC,KAAQ,WAAa,EAErB,KAAQ,YAAc,IAAIb,EAAiB,EAAE,EAG7C,KAAQ,gBAAkB,EAC1B,KAAQ,kBAAoB,EAC5B,KAAQ,WAAa,EAGjB,KAAK,OAASa,GAAM,OACpB,KAAK,UAAYA,GAAM,WAAa,EACpC,KAAK,gBAAkBA,GAAM,iBAAmB,IAChD,KAAK,SAAWA,GAAM,SACtB,KAAK,SAAWA,GAAM,SAGtB,KAAK,UAAYA,GAAM,WAAa,KAAK,kBAAA,EACzC,KAAK,OAASA,GAAM,QAAU,KAAK,eAAA,EACnC,KAAK,aAAe,KAAK,IAAA,EACzB,KAAK,WAAaA,GAAM,YAAcL,EAGlC,KAAK,QAAQ,cAEb,KAAK,OAAO,aAAA,EAAe,MAAOM,GAAa,CAC3CC,QAAM,KAAK,2CAA4CD,CAAG,CAC9D,CAAC,EAGD,KAAK,gBAAkB,IACvB,KAAK,WAAa,YAAY,IAAM,KAAK,MAAA,EAAQ,MAAM,IAAM,CAAE,CAAC,EAAG,KAAK,eAAe,GAG3F,KAAK,kBAAoB,IAAIE,EAAAA,kBAAkB,IAAI,EACnD,KAAK,QAAU,IAAIrB,EAAoB,IAAI,EAE3C,KAAK,kBAAoBkB,GAAM,mBAAqB,CAChD,MAAO,SAAY,QAAQ,QAAA,EAC3B,QAAS,SAAY,QAAQ,QAAQ,CACjC,IAAK,CAAE,KAAM,GAAI,QAAS,EAAA,EAC1B,OAAQ,CAAE,GAAI,GAAI,SAAU,EAAA,CAAG,CAClC,CAAA,EAEL,KAAK,mBAAqBA,GAAM,oBAAsB,CAClD,MAAO,SAAY,QAAQ,QAAQ,EAAE,EACrC,QAAS,SAAY,QAAQ,QAAQ,CAAA,CAAE,CAAA,CAG/C,CAIO,YAAYI,EAA4BC,EAA+B,CAC1E,KAAK,aAAeD,EACfA,EAAa,OAAOC,CAAO,EAAE,MAAOJ,GAAQ,CAC7CC,QAAM,KAAK,wCAAyCD,CAAG,CAC3D,CAAC,CACL,CAEA,cAAcK,EAAsC,CAChD,KAAK,kBAAoBA,EACpBA,EAAkB,MAAM,IAAI,EAAE,MAAOL,GAAQ,CAC9CC,QAAM,KAAK,8CAA+CD,CAAG,CACjE,CAAC,CACL,CAEA,eAAeM,EAAwC,CACnD,KAAK,mBAAqBA,EACrBA,EAAmB,MAAM,IAAI,EAAE,MAAON,GAAQ,CAC/CC,QAAM,KAAK,6CAA8CD,CAAG,CAChE,CAAC,CACL,CAEO,gBAAgBO,EAAsC,CACzD,KAAK,kBAAoBA,EACpBA,EAAkB,MAAA,EAAQ,MAAOP,GAAQ,CAC1CC,QAAM,KAAK,4CAA6CD,CAAG,CAC/D,CAAC,CACL,CAEO,qBAAqBQ,EAAgC,CACxD,KAAK,eAAiBA,EACjBA,EAAe,MAAA,EAAQ,MAAOR,GAAQ,CACvCC,QAAM,KAAK,yCAA0CD,CAAG,CAC5D,CAAC,CACL,CAEO,iBAAiBS,EAA8B,CAClD,KAAK,cAAgBA,EAChBA,EAAc,kBAAA,EAAoB,MAAOT,GAAQ,CAClDC,QAAM,KAAK,oDAAqDD,CAAG,CACvE,CAAC,CACL,CAEO,oBAAoBU,EAAuC,CAC9D,KAAK,kBAAoBA,EACpBA,GAAmB,MAAA,EAAQ,MAAOV,GAAQ,CAC3CC,QAAM,KAAK,4CAA6CD,CAAG,CAC/D,CAAC,CACL,CAGQ,mBAA4B,CAChC,MAAMW,EAAO,WAAW,KAAK,IAAA,CAAK,IAAItB,EAAU,EAAE,CAAC,GACnD,OAAO,KAAK,SAAW,GAAGsB,CAAI,IAAI,KAAK,QAAQ,GAAKA,CACxD,CAEO,aAAaC,EAAY,CAC5B,KAAK,UAAYA,EACjB,KAAK,aAAe,KAAK,IAAA,CAC7B,CAEO,cAAuB,CAC1B,OAAO,KAAK,SAChB,CAGO,aAAkC,CACrC,OAAO,KAAK,QAChB,CAEO,iBAAkB,CACrB,KAAK,UAAY,KAAK,kBAAA,EACtB,KAAK,aAAe,KAAK,IAAA,CAC7B,CAKA,MAAa,cAAe,CACxB,KAAK,aAAe,KAAK,IAAA,EACzB,MAAM,KAAK,IAAI,kBAAmB,EAAE,CACxC,CAGA,MAAa,iBAAkB,CAC3B,MAAM,KAAK,IAAI,oBAAqB,CAChC,sBAAuB,KAAK,IAAA,EAAQ,KAAK,aACzC,sBAAuB,KAAK,kBAC5B,kBAAmB,KAAK,UAAA,CAC3B,EACD,MAAM,KAAK,MAAA,CACf,CAGA,MAAa,YAAa,CACtB,KAAK,UAAY,KAAK,kBAAA,EACtB,KAAK,aAAe,KAAK,IAAA,EACzB,KAAK,gBAAkB,EACvB,KAAK,kBAAoB,EACzB,KAAK,WAAa,EAClB,MAAM,KAAK,aAAA,CACf,CAGA,MAAa,eAAgB,CACzB,MAAM,KAAK,gBAAA,EACX,MAAM,KAAK,WAAA,CACf,CAEO,UAAUA,EAAY,CACzB,KAAK,OAASA,CAClB,CAEO,WAAuC,CAC1C,OAAO,KAAK,MAChB,CAEO,gBAAyB,CAC5B,MAAO,QAAQ,KAAK,IAAA,CAAK,IAAIvB,EAAU,EAAE,CAAC,EAC9C,CAOO,eAAewB,EAAqC,CACvD,MAAMC,EAAM,KAAK,IAAA,EAGXC,EAAe,CAAC,KAAK,aAAgBF,EAAQ,QAAUA,EAAQ,SAAW,KAAK,YAAY,OAEjG,KAAK,YAAc,CACf,GAAG,KAAK,YACR,GAAGA,EACH,UAAWC,EACX,GAAIC,GAAgB,CAAE,UAAWD,CAAA,CAAI,EAIrCD,EAAQ,OACR,KAAK,OAASA,EAAQ,OACf,KAAK,aAAe,CAAC,KAAK,YAAY,SAE7C,KAAK,YAAY,OAAS,KAAK,QAAU,QAG7CZ,EAAAA,MAAM,IAAI,kCAAmC,KAAK,WAAW,CACjE,CAOA,MAAa,SAASY,EAMnB,CACC,KAAK,eAAe,CAChB,SAAUA,EAAQ,KAClB,MAAOA,EAAQ,MACf,MAAOA,EAAQ,MACf,OAAQA,EAAQ,OAChB,iBAAkBA,EAAQ,gBAAA,CAC7B,EACD,MAAM,KAAK,IAAI,sBAAuB,EAAE,CAC5C,CAKO,eAAeG,EAQb,CACL,KAAK,eAAeA,CAAO,CAC/B,CAKO,kBAAkBC,EAAqC,CAC1D,GAAI,CAAC,KAAK,YAAa,CAEnB,KAAK,eAAeA,CAAO,EAC3B,MACJ,CAEA,KAAK,YAAc,CACf,GAAG,KAAK,YACR,GAAGA,EACH,UAAW,KAAK,IAAA,CAAI,EAGxBhB,EAAAA,MAAM,IAAI,kCAAmC,KAAK,WAAW,CACjE,CAKO,gBAA0C,CAC7C,OAAO,KAAK,WAChB,CAKO,kBAAyB,CAC5B,KAAK,YAAc,OACnBA,EAAAA,MAAM,IAAI,iCAAiC,CAC/C,CAKO,YAAYiB,EAAkBC,EAAoBC,EAAyB,CAC9E,KAAK,eAAe,CAChB,SAAAF,EACA,UAAAC,EACA,SAAAC,CAAA,CACH,CACL,CAKO,eAAeC,EAAgBC,EAAsB,CACxD,KAAK,eAAe,CAChB,MAAAD,EACA,MAAAC,CAAA,CACH,CACL,CAQA,MAAM,IAAIC,EAAcC,EAA4B,CAKhD,GAJA,KAAK,aAID,CAACD,EAAK,WAAW,UAAU,EAAG,CAC9B,MAAMT,EAAM,KAAK,IAAA,EACb,KAAK,eAAiB,QAAaA,EAAM,KAAK,aAAelB,GAC7D,MAAM,KAAK,cAAA,EAEf,KAAK,aAAekB,EACpB,KAAK,oBACDS,IAAS,aAAa,KAAK,YACnC,CAGA,MAAME,EAAY5B,EAAc,IAAI0B,CAAI,EAClCG,EAAYD,EAAYF,EAAO,eAE/BI,EAAa,MAAM,KAAK,eAAeH,CAAI,EAC5CC,IAAWE,EAAW,YAAY,EAAIJ,GAGvCG,IAAc,YACdC,EAAW,mBAAmB,EAAI,KAAK,YAAY,OAAA,EAEnD,KAAK,YAAY,IAAI,CAAE,KAAMD,EAAW,UAAW,IAAI,OAAO,YAAA,CAAY,CAAG,EAGjF,MAAME,EAAoB,CACtB,KAAM,QACN,UAAAF,EACA,UAAW,IAAI,KAAA,EAAO,YAAA,EACtB,WAAAC,CAAA,EAGJ,KAAK,MAAM,KAAKC,CAAC,EAEjB3B,EAAAA,MAAM,IAAI,0BAA2BsB,EAAM,cAAe,KAAK,MAAM,MAAM,EAC3EtB,QAAM,IAAI,oBAAqB0B,CAAU,EAErC,KAAK,MAAM,QAAU,KAAK,WACrB,KAAK,MAAA,CAIlB,CAOA,MAAc,eAAeH,EAA0D,CACnF,IAAIK,EAAkC,CAAA,EAClCC,EAAmC,CAAA,EAEvC,GAAI,CACAD,EAAc,MAAM,KAAK,mBAAmB,QAAA,GAAc,CAAA,CAC9D,OAAS7B,EAAK,CACVC,QAAM,KAAK,yCAA0CD,CAAG,CAC5D,CAEA,GAAI,CACA8B,EAAe,MAAM,KAAK,oBAAoB,QAAA,GAAc,CAAA,CAChE,OAAS9B,EAAK,CACVC,QAAM,KAAK,0CAA2CD,CAAG,CAC7D,CAEA,MAAM2B,EAAkC,CAEpC,GAAG,KAAK,kBAAkB,GAAIE,CAAU,EACxC,GAAG,KAAK,kBAAkB,UAAWC,CAAW,EAChD,GAAG,KAAK,kBAAkB,GAAIN,GAAQ,CAAA,CAAE,EACxC,UAAW,KAAK,QAAU,KAC1B,aAAc,KAAK,UACnB,qBAAsB,IAAI,KAAK,KAAK,YAAY,EAAE,YAAA,EAClD,mBAAoB,KAAK,gBACzB,eAAgB/B,EAChB,cAAe,KAAK,UAAA,EAGxB,GAAI,KAAK,YAAa,CAClB,MAAMsC,EAAkB,CACpB,YAAa,KAAK,YAAY,SAC9B,gBAAiB,KAAK,YAAY,SAClC,iBAAkB,KAAK,YAAY,UACnC,gBAAiB,KAAK,YAAY,SAClC,aAAc,KAAK,YAAY,MAC/B,aAAc,KAAK,YAAY,MAC/B,cAAe,KAAK,YAAY,OAChC,iBAAkB,KAAK,YAAY,UACnC,iBAAkB,KAAK,YAAY,UACnC,GAAG,KAAK,kBAAkB,cAAe,KAAK,YAAY,kBAAoB,CAAA,CAAE,CAAA,EAEpF,OAAO,QAAQA,CAAe,EAAE,QAAQ,CAAC,CAACC,EAAKC,CAAK,IAAM,CAClDA,IAAU,SAAWN,EAAWK,CAAG,EAAIC,EAC/C,CAAC,CACL,CAEA,OAAON,CACX,CAQA,MAAM,UAAUO,EAAoBD,EAAeT,EAA4B,CAC3E,KAAK,aACL,MAAMG,EAAa,MAAM,KAAK,eAAeH,CAAI,EAE3CW,EAAoB,CACtB,KAAM,SACN,WAAAD,EACA,MAAAD,EACA,UAAW,IAAI,KAAA,EAAO,YAAA,EACtB,WAAAN,CAAA,EAGJ,KAAK,MAAM,KAAKQ,CAAC,EACb,KAAK,MAAM,QAAU,KAAK,WACrB,KAAK,MAAA,CAElB,CAEQ,kBAAkBC,EAAgBC,EAA+C,CACrF,MAAMC,EAA8B,CAAA,EAEpC,UAAWN,KAAOK,EAAK,CACnB,GAAI,CAAC,OAAO,UAAU,eAAe,KAAKA,EAAKL,CAAG,EAAG,SAErD,MAAMC,EAAQI,EAAIL,CAAG,EACfO,EAAcH,EAAS,GAAGA,CAAM,IAAIJ,CAAG,GAAKA,EAE9C,OAAOC,GAAU,UAAYA,IAAU,MAAQ,CAAC,MAAM,QAAQA,CAAK,EACnE,OAAO,OAAOK,EAAQ,KAAK,kBAAkBC,EAAaN,CAAK,CAAC,EAEhEK,EAAOC,CAAW,EAAIN,CAE9B,CAEA,OAAOK,CACX,CAOA,aAAaf,EAAcU,EAAeT,EAA4B,CAClE,OAAO,KAAK,UAAUD,EAAMU,EAAOT,CAAI,CAC3C,CAOA,MAAM,OAAQ,CACV,GAAI,CAAC,KAAK,QAAU,KAAK,MAAM,SAAW,EAAG,OAG7C,MAAMgB,EAAS,KAAK,MAAM,OAAO,EAAG,KAAK,SAAS,EAElD,GAAI,CACA,MAAM,KAAK,OAAO,KAAKA,CAAM,EAC7B,KAAK,iBACT,OAASC,EAAW,CAChB,GAAI,KAAK,OAAO,UACZ,GAAI,CACA,MAAM,KAAK,OAAO,UAAUD,CAAM,CACtC,OAASE,EAAY,CAEjB,KAAK,MAAM,QAAQ,GAAGF,CAAM,EAC5BvC,QAAM,KAAK,4CAA6CyC,CAAU,CACtE,MAEA,KAAK,MAAM,QAAQ,GAAGF,CAAM,EAGhCvC,MAAAA,QAAM,MAAM,0BAA2BwC,CAAS,EAC1CA,CACV,CACJ,CAEA,UAAW,CACP,MAAO,CAAC,GAAG,KAAK,KAAK,CACzB,CAEA,MAAM,UAAW,CACT,KAAK,YAAY,cAAc,KAAK,UAAU,EAClD,MAAM,KAAK,MAAA,CACf,CAKA,eAAgB,CACZ,OAAO,KAAK,UAChB,CAEA,kBAAkBE,EAAcC,EAAY,CACxC,YAAK,cAAgBA,EACd,KAAK,mBAAmB,kBAAkBD,EAAMC,CAAE,CAC7D,CAGJ"}