@goliapkg/sentori-react-native 4.0.0 → 5.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 (308) hide show
  1. package/MIGRATION.md +131 -0
  2. package/README.md +40 -30
  3. package/android/build.gradle +21 -0
  4. package/android/src/main/java/com/sentori/SentoriCrashHandler.kt +29 -0
  5. package/android/src/main/java/com/sentori/SentoriModule.kt +8 -0
  6. package/android/src/main/java/com/sentori/SentoriScreenshotCapture.kt +36 -4
  7. package/android/src/test/java/com/sentori/SentoriCrashHandlerTest.kt +7 -2
  8. package/android/src/test/resources/robolectric.properties +10 -0
  9. package/ios/SentoriCrashHandler.swift +48 -4
  10. package/ios/SentoriModule.swift +12 -0
  11. package/ios/SentoriScreenshotCapture.swift +34 -3
  12. package/lib/config.d.ts +17 -47
  13. package/lib/config.d.ts.map +1 -1
  14. package/lib/config.js +3 -0
  15. package/lib/config.js.map +1 -1
  16. package/lib/device.d.ts +5 -0
  17. package/lib/device.d.ts.map +1 -0
  18. package/lib/device.js +29 -0
  19. package/lib/device.js.map +1 -0
  20. package/lib/emit-hooks.d.ts +7 -0
  21. package/lib/emit-hooks.d.ts.map +1 -0
  22. package/lib/emit-hooks.js +24 -0
  23. package/lib/emit-hooks.js.map +1 -0
  24. package/lib/error-boundary.d.ts.map +1 -1
  25. package/lib/error-boundary.js +1 -1
  26. package/lib/error-boundary.js.map +1 -1
  27. package/lib/feature-flags.d.ts.map +1 -1
  28. package/lib/handlers/dev-symbolicate.d.ts +1 -1
  29. package/lib/handlers/dev-symbolicate.d.ts.map +1 -1
  30. package/lib/handlers/dev-symbolicate.js +2 -0
  31. package/lib/handlers/dev-symbolicate.js.map +1 -1
  32. package/lib/handlers/global.js +1 -1
  33. package/lib/handlers/global.js.map +1 -1
  34. package/lib/handlers/lifecycle.js +3 -3
  35. package/lib/handlers/lifecycle.js.map +1 -1
  36. package/lib/handlers/network.d.ts +2 -2
  37. package/lib/handlers/network.d.ts.map +1 -1
  38. package/lib/handlers/network.js +69 -187
  39. package/lib/handlers/network.js.map +1 -1
  40. package/lib/handlers/promise.js +1 -1
  41. package/lib/handlers/promise.js.map +1 -1
  42. package/lib/handlers/screenshot.d.ts.map +1 -1
  43. package/lib/handlers/screenshot.js +3 -12
  44. package/lib/handlers/screenshot.js.map +1 -1
  45. package/lib/index.d.ts +32 -109
  46. package/lib/index.d.ts.map +1 -1
  47. package/lib/index.js +54 -103
  48. package/lib/index.js.map +1 -1
  49. package/lib/init.d.ts +3 -150
  50. package/lib/init.d.ts.map +1 -1
  51. package/lib/init.js +100 -261
  52. package/lib/init.js.map +1 -1
  53. package/lib/long-task-monitor.d.ts +1 -7
  54. package/lib/long-task-monitor.d.ts.map +1 -1
  55. package/lib/long-task-monitor.js +37 -58
  56. package/lib/long-task-monitor.js.map +1 -1
  57. package/lib/mask.d.ts +5 -13
  58. package/lib/mask.d.ts.map +1 -1
  59. package/lib/mask.js +29 -30
  60. package/lib/mask.js.map +1 -1
  61. package/lib/mobile-vitals.d.ts +3 -31
  62. package/lib/mobile-vitals.d.ts.map +1 -1
  63. package/lib/mobile-vitals.js +22 -61
  64. package/lib/mobile-vitals.js.map +1 -1
  65. package/lib/native-pending.d.ts +3 -0
  66. package/lib/native-pending.d.ts.map +1 -0
  67. package/lib/native-pending.js +64 -0
  68. package/lib/native-pending.js.map +1 -0
  69. package/lib/native.d.ts +4 -11
  70. package/lib/native.d.ts.map +1 -1
  71. package/lib/native.js +23 -0
  72. package/lib/native.js.map +1 -1
  73. package/lib/navigation.d.ts +3 -17
  74. package/lib/navigation.d.ts.map +1 -1
  75. package/lib/navigation.js +32 -133
  76. package/lib/navigation.js.map +1 -1
  77. package/lib/netinfo.d.ts +1 -1
  78. package/lib/netinfo.d.ts.map +1 -1
  79. package/lib/netinfo.js +2 -2
  80. package/lib/netinfo.js.map +1 -1
  81. package/lib/push.d.ts.map +1 -1
  82. package/lib/push.js +2 -4
  83. package/lib/push.js.map +1 -1
  84. package/lib/rage-tap.d.ts.map +1 -1
  85. package/lib/rage-tap.js +56 -23
  86. package/lib/rage-tap.js.map +1 -1
  87. package/lib/replay-screens.d.ts +15 -0
  88. package/lib/replay-screens.d.ts.map +1 -0
  89. package/lib/replay-screens.js +87 -0
  90. package/lib/replay-screens.js.map +1 -0
  91. package/lib/replay.d.ts.map +1 -1
  92. package/lib/replay.js +3 -24
  93. package/lib/replay.js.map +1 -1
  94. package/lib/responsiveness-detector.d.ts +18 -0
  95. package/lib/responsiveness-detector.d.ts.map +1 -0
  96. package/lib/responsiveness-detector.js +55 -0
  97. package/lib/responsiveness-detector.js.map +1 -0
  98. package/lib/scope.d.ts +7 -0
  99. package/lib/scope.d.ts.map +1 -0
  100. package/lib/scope.js +41 -0
  101. package/lib/scope.js.map +1 -0
  102. package/lib/transport.d.ts +19 -92
  103. package/lib/transport.d.ts.map +1 -1
  104. package/lib/transport.js +75 -288
  105. package/lib/transport.js.map +1 -1
  106. package/lib/verbs.d.ts +16 -0
  107. package/lib/verbs.d.ts.map +1 -0
  108. package/lib/verbs.js +153 -0
  109. package/lib/verbs.js.map +1 -0
  110. package/package.json +4 -3
  111. package/src/__tests__/iron-rule.test.ts +128 -0
  112. package/src/__tests__/replay-screens.test.ts +63 -0
  113. package/src/__tests__/responsiveness-detector.test.ts +74 -0
  114. package/src/__tests__/screenshot.test.ts +0 -2
  115. package/src/__tests__/transport.test.ts +66 -213
  116. package/src/__tests__/verbs.test.ts +91 -0
  117. package/src/config.ts +20 -47
  118. package/src/device.ts +36 -0
  119. package/src/emit-hooks.ts +30 -0
  120. package/src/error-boundary.tsx +1 -1
  121. package/src/handlers/dev-symbolicate.ts +2 -1
  122. package/src/handlers/global.ts +1 -1
  123. package/src/handlers/lifecycle.ts +3 -3
  124. package/src/handlers/network.ts +95 -211
  125. package/src/handlers/promise.ts +1 -1
  126. package/src/handlers/screenshot.ts +3 -11
  127. package/src/index.ts +84 -215
  128. package/src/init.ts +115 -449
  129. package/src/long-task-monitor.ts +42 -64
  130. package/src/mask.ts +29 -31
  131. package/src/mobile-vitals.ts +22 -82
  132. package/src/native-pending.ts +92 -0
  133. package/src/native.ts +33 -0
  134. package/src/navigation.ts +34 -142
  135. package/src/netinfo.ts +3 -3
  136. package/src/push.ts +2 -5
  137. package/src/rage-tap.tsx +72 -25
  138. package/src/replay-screens.ts +95 -0
  139. package/src/replay.ts +3 -20
  140. package/src/responsiveness-detector.ts +66 -0
  141. package/src/scope.ts +50 -0
  142. package/src/transport.ts +84 -371
  143. package/src/verbs.ts +198 -0
  144. package/lib/breadcrumbs.d.ts +0 -18
  145. package/lib/breadcrumbs.d.ts.map +0 -1
  146. package/lib/breadcrumbs.js +0 -42
  147. package/lib/breadcrumbs.js.map +0 -1
  148. package/lib/bundle-info.d.ts +0 -12
  149. package/lib/bundle-info.d.ts.map +0 -1
  150. package/lib/bundle-info.js +0 -73
  151. package/lib/bundle-info.js.map +0 -1
  152. package/lib/capture.d.ts +0 -140
  153. package/lib/capture.d.ts.map +0 -1
  154. package/lib/capture.js +0 -511
  155. package/lib/capture.js.map +0 -1
  156. package/lib/compat/sentry.d.ts +0 -126
  157. package/lib/compat/sentry.d.ts.map +0 -1
  158. package/lib/compat/sentry.js +0 -332
  159. package/lib/compat/sentry.js.map +0 -1
  160. package/lib/control-channel.d.ts +0 -6
  161. package/lib/control-channel.d.ts.map +0 -1
  162. package/lib/control-channel.js +0 -96
  163. package/lib/control-channel.js.map +0 -1
  164. package/lib/expo-compat.d.ts +0 -270
  165. package/lib/expo-compat.d.ts.map +0 -1
  166. package/lib/expo-compat.js +0 -500
  167. package/lib/expo-compat.js.map +0 -1
  168. package/lib/feedback-widget.d.ts +0 -35
  169. package/lib/feedback-widget.d.ts.map +0 -1
  170. package/lib/feedback-widget.js +0 -193
  171. package/lib/feedback-widget.js.map +0 -1
  172. package/lib/feedback.d.ts +0 -2
  173. package/lib/feedback.d.ts.map +0 -1
  174. package/lib/feedback.js +0 -17
  175. package/lib/feedback.js.map +0 -1
  176. package/lib/heartbeat.d.ts +0 -9
  177. package/lib/heartbeat.d.ts.map +0 -1
  178. package/lib/heartbeat.js +0 -138
  179. package/lib/heartbeat.js.map +0 -1
  180. package/lib/index.js.bak +0 -64
  181. package/lib/install-id.d.ts +0 -17
  182. package/lib/install-id.d.ts.map +0 -1
  183. package/lib/install-id.js +0 -125
  184. package/lib/install-id.js.map +0 -1
  185. package/lib/lifecycle.d.ts +0 -28
  186. package/lib/lifecycle.d.ts.map +0 -1
  187. package/lib/lifecycle.js +0 -73
  188. package/lib/lifecycle.js.map +0 -1
  189. package/lib/measure.d.ts +0 -4
  190. package/lib/measure.d.ts.map +0 -1
  191. package/lib/measure.js +0 -25
  192. package/lib/measure.js.map +0 -1
  193. package/lib/metrics.d.ts +0 -24
  194. package/lib/metrics.d.ts.map +0 -1
  195. package/lib/metrics.js +0 -81
  196. package/lib/metrics.js.map +0 -1
  197. package/lib/pre-crash-sentinel.d.ts +0 -12
  198. package/lib/pre-crash-sentinel.d.ts.map +0 -1
  199. package/lib/pre-crash-sentinel.js +0 -116
  200. package/lib/pre-crash-sentinel.js.map +0 -1
  201. package/lib/report-security.d.ts +0 -40
  202. package/lib/report-security.d.ts.map +0 -1
  203. package/lib/report-security.js +0 -159
  204. package/lib/report-security.js.map +0 -1
  205. package/lib/runtime-metrics-fps.d.ts +0 -19
  206. package/lib/runtime-metrics-fps.d.ts.map +0 -1
  207. package/lib/runtime-metrics-fps.js +0 -128
  208. package/lib/runtime-metrics-fps.js.map +0 -1
  209. package/lib/runtime-metrics-heap.d.ts +0 -13
  210. package/lib/runtime-metrics-heap.d.ts.map +0 -1
  211. package/lib/runtime-metrics-heap.js +0 -67
  212. package/lib/runtime-metrics-heap.js.map +0 -1
  213. package/lib/runtime-metrics-network.d.ts +0 -23
  214. package/lib/runtime-metrics-network.d.ts.map +0 -1
  215. package/lib/runtime-metrics-network.js +0 -99
  216. package/lib/runtime-metrics-network.js.map +0 -1
  217. package/lib/runtime-metrics.d.ts +0 -43
  218. package/lib/runtime-metrics.d.ts.map +0 -1
  219. package/lib/runtime-metrics.js +0 -115
  220. package/lib/runtime-metrics.js.map +0 -1
  221. package/lib/sample-profiler.d.ts +0 -21
  222. package/lib/sample-profiler.d.ts.map +0 -1
  223. package/lib/sample-profiler.js +0 -152
  224. package/lib/sample-profiler.js.map +0 -1
  225. package/lib/sentinel-context.d.ts +0 -4
  226. package/lib/sentinel-context.d.ts.map +0 -1
  227. package/lib/sentinel-context.js +0 -52
  228. package/lib/sentinel-context.js.map +0 -1
  229. package/lib/session-tracker.d.ts +0 -6
  230. package/lib/session-tracker.d.ts.map +0 -1
  231. package/lib/session-tracker.js +0 -50
  232. package/lib/session-tracker.js.map +0 -1
  233. package/lib/stack.d.ts +0 -3
  234. package/lib/stack.d.ts.map +0 -1
  235. package/lib/stack.js +0 -7
  236. package/lib/stack.js.map +0 -1
  237. package/lib/state-snapshots.d.ts +0 -33
  238. package/lib/state-snapshots.d.ts.map +0 -1
  239. package/lib/state-snapshots.js +0 -109
  240. package/lib/state-snapshots.js.map +0 -1
  241. package/lib/track.d.ts +0 -34
  242. package/lib/track.d.ts.map +0 -1
  243. package/lib/track.js +0 -107
  244. package/lib/track.js.map +0 -1
  245. package/lib/trail.d.ts +0 -12
  246. package/lib/trail.d.ts.map +0 -1
  247. package/lib/trail.js +0 -28
  248. package/lib/trail.js.map +0 -1
  249. package/lib/trust-score.d.ts +0 -20
  250. package/lib/trust-score.d.ts.map +0 -1
  251. package/lib/trust-score.js +0 -151
  252. package/lib/trust-score.js.map +0 -1
  253. package/lib/types.d.ts +0 -2
  254. package/lib/types.d.ts.map +0 -1
  255. package/lib/types.js +0 -4
  256. package/lib/types.js.map +0 -1
  257. package/lib/uuid.d.ts +0 -2
  258. package/lib/uuid.d.ts.map +0 -1
  259. package/lib/uuid.js +0 -3
  260. package/lib/uuid.js.map +0 -1
  261. package/src/__tests__/before-send.test.ts +0 -72
  262. package/src/__tests__/breadcrumbs.test.ts +0 -44
  263. package/src/__tests__/capture-replay.test.ts +0 -150
  264. package/src/__tests__/compat-sentry.test.ts +0 -121
  265. package/src/__tests__/control-channel.test.ts +0 -111
  266. package/src/__tests__/install-id.test.ts +0 -60
  267. package/src/__tests__/long-task-monitor.test.ts +0 -59
  268. package/src/__tests__/measure.test.ts +0 -45
  269. package/src/__tests__/navigation.test.ts +0 -175
  270. package/src/__tests__/push.test.ts +0 -238
  271. package/src/__tests__/report-security.test.ts +0 -106
  272. package/src/__tests__/runtime-metrics-instruments.test.ts +0 -109
  273. package/src/__tests__/runtime-metrics-network.test.ts +0 -78
  274. package/src/__tests__/sample-profiler.test.ts +0 -59
  275. package/src/__tests__/stack.test.ts +0 -45
  276. package/src/__tests__/state-snapshots.test.ts +0 -119
  277. package/src/__tests__/tracing.test.ts +0 -201
  278. package/src/__tests__/track.test.ts +0 -91
  279. package/src/__tests__/uuid.test.ts +0 -41
  280. package/src/breadcrumbs.ts +0 -57
  281. package/src/bundle-info.ts +0 -95
  282. package/src/capture.ts +0 -660
  283. package/src/compat/sentry.ts +0 -490
  284. package/src/control-channel.ts +0 -98
  285. package/src/expo-compat.ts +0 -698
  286. package/src/feedback-widget.tsx +0 -316
  287. package/src/feedback.ts +0 -21
  288. package/src/heartbeat.ts +0 -157
  289. package/src/install-id.ts +0 -146
  290. package/src/lifecycle.ts +0 -76
  291. package/src/measure.ts +0 -28
  292. package/src/metrics.ts +0 -94
  293. package/src/pre-crash-sentinel.ts +0 -140
  294. package/src/report-security.ts +0 -165
  295. package/src/runtime-metrics-fps.ts +0 -137
  296. package/src/runtime-metrics-heap.ts +0 -78
  297. package/src/runtime-metrics-network.ts +0 -103
  298. package/src/runtime-metrics.ts +0 -122
  299. package/src/sample-profiler.ts +0 -169
  300. package/src/sentinel-context.ts +0 -60
  301. package/src/session-tracker.ts +0 -53
  302. package/src/stack.ts +0 -10
  303. package/src/state-snapshots.ts +0 -133
  304. package/src/track.ts +0 -123
  305. package/src/trail.ts +0 -32
  306. package/src/trust-score.ts +0 -176
  307. package/src/types.ts +0 -21
  308. package/src/uuid.ts +0 -2
package/lib/lifecycle.js DELETED
@@ -1,73 +0,0 @@
1
- // v2.0 W3 — top-level lifecycle: flush / close.
2
- //
3
- // Sentry / OTel parity: a single `flush(timeoutMs?)` that drains
4
- // every in-flight buffer (events / metrics / track), gated by a
5
- // timeout so a slow network doesn't hang the host's shutdown path.
6
- //
7
- // Use before short-lived process exit (CLI / serverless function /
8
- // fixture cleanup) to ensure pending captures land before the
9
- // process dies.
10
- import { flush as flushTransport } from './transport';
11
- import { flushMetrics } from './metrics';
12
- import { flushTrack } from './track';
13
- import { reportInternal } from '@goliapkg/sentori-core';
14
- let _closed = false;
15
- /**
16
- * Force-flush every pending Sentori buffer (events, metrics,
17
- * track). Returns when the flush settles or the timeout fires —
18
- * whichever happens first.
19
- *
20
- * Never rejects: per the NEVER rule, individual flush failures
21
- * are silently absorbed (and self-reported via the internal
22
- * circuit-breaker), and the resolved promise's value is undefined.
23
- *
24
- * await sentori.flush(5_000) // wait up to 5 s, then move on
25
- * process.exit(0)
26
- */
27
- export async function flush(timeoutMs = 5_000) {
28
- if (_closed)
29
- return;
30
- try {
31
- const drainAll = Promise.all([
32
- flushTransport().catch((err) => {
33
- reportInternal('flush.transport', err);
34
- }),
35
- flushMetrics().catch((err) => {
36
- reportInternal('flush.metrics', err);
37
- }),
38
- flushTrack().catch((err) => {
39
- reportInternal('flush.track', err);
40
- }),
41
- ]).then(() => undefined);
42
- const timer = new Promise((resolve) => setTimeout(resolve, timeoutMs));
43
- await Promise.race([drainAll, timer]);
44
- }
45
- catch (err) {
46
- // Belt-and-braces: even though each branch already has its own
47
- // catch, the wrapping race shouldn't be able to surface a
48
- // failure to the host either. NEVER rule.
49
- reportInternal('flush', err);
50
- }
51
- }
52
- /**
53
- * Flush + shut down. After `close()`, further capture* calls remain
54
- * silent no-ops via `_closed` gate. Idempotent — re-calling is safe.
55
- *
56
- * await sentori.close()
57
- * // SDK is asleep; no more events go out.
58
- */
59
- export async function close(timeoutMs) {
60
- await flush(timeoutMs);
61
- _closed = true;
62
- }
63
- /** Test hook — reset the shutdown latch so unit tests don't have to
64
- * re-init the whole SDK between cases. */
65
- export function __resetLifecycleForTests() {
66
- _closed = false;
67
- }
68
- /** Internal — capture* implementations check this to short-circuit
69
- * after `close()`. */
70
- export function isClosed() {
71
- return _closed;
72
- }
73
- //# sourceMappingURL=lifecycle.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,EAAE;AACF,iEAAiE;AACjE,gEAAgE;AAChE,mEAAmE;AACnE,EAAE;AACF,mEAAmE;AACnE,8DAA8D;AAC9D,gBAAgB;AAEhB,OAAO,EAAE,KAAK,IAAI,cAAc,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,IAAI,OAAO,GAAG,KAAK,CAAC;AAEpB;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,YAAoB,KAAK;IACnD,IAAI,OAAO;QAAE,OAAO;IACpB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;YAC3B,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC7B,cAAc,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;YACzC,CAAC,CAAC;YACF,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC3B,cAAc,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;YACvC,CAAC,CAAC;YACF,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACzB,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;YACrC,CAAC,CAAC;SACH,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;QAC7E,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,+DAA+D;QAC/D,0DAA0D;QAC1D,0CAA0C;QAC1C,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,SAAkB;IAC5C,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;IACvB,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC;AAED;2CAC2C;AAC3C,MAAM,UAAU,wBAAwB;IACtC,OAAO,GAAG,KAAK,CAAC;AAClB,CAAC;AAED;uBACuB;AACvB,MAAM,UAAU,QAAQ;IACtB,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/lib/measure.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export declare function measureFn<T>(name: string, fn: () => Promise<T> | T, opts?: {
2
- tags?: Record<string, string>;
3
- }): Promise<T>;
4
- //# sourceMappingURL=measure.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../src/measure.ts"],"names":[],"mappings":"AASA,wBAAsB,SAAS,CAAC,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EACxB,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACvC,OAAO,CAAC,CAAC,CAAC,CAcZ"}
package/lib/measure.js DELETED
@@ -1,25 +0,0 @@
1
- // v0.9.0 #14 — `sentori.measureFn(name, fn)`. Profile-lite. Wrap an
2
- // async (or sync) function call in a span so it shows on the issue
3
- // detail trace waterfall without writing the boilerplate every time.
4
- // The full Hermes-sampler profiler (#4) is the deep version of this
5
- // idea; `measureFn` is the cheap version that doesn't need a native
6
- // module.
7
- import { startSpan } from '@goliapkg/sentori-core';
8
- export async function measureFn(name, fn, opts) {
9
- const span = startSpan('sentori.measureFn', {
10
- name,
11
- tags: opts?.tags ?? {},
12
- });
13
- try {
14
- const result = await fn();
15
- span.finish({ status: 'ok' });
16
- return result;
17
- }
18
- catch (e) {
19
- if (e instanceof Error)
20
- span.setTag('error.message', e.message);
21
- span.finish({ status: 'error' });
22
- throw e;
23
- }
24
- }
25
- //# sourceMappingURL=measure.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"measure.js","sourceRoot":"","sources":["../src/measure.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,mEAAmE;AACnE,qEAAqE;AACrE,oEAAoE;AACpE,oEAAoE;AACpE,UAAU;AAEV,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAY,EACZ,EAAwB,EACxB,IAAwC;IAExC,MAAM,IAAI,GAAG,SAAS,CAAC,mBAAmB,EAAE;QAC1C,IAAI;QACJ,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE;KACvB,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9B,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,KAAK;YAAE,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QAChE,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QACjC,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC"}
package/lib/metrics.d.ts DELETED
@@ -1,24 +0,0 @@
1
- import type { SpanContextLike } from '@goliapkg/sentori-core';
2
- /**
3
- * Record a numeric metric point. Cheap to call from a render hook —
4
- * pushes into a 500-slot ring drained every 30 s (or on overflow).
5
- *
6
- * v2.0 — accepts an optional `parent: SpanContextLike` so a metric
7
- * can be correlated to a span. The dashboard span-detail view joins
8
- * metric points by `tags.span_id` / `tags.trace_id`.
9
- *
10
- * const span = sentori.startSpan({ name: 'db.query users' })
11
- * sentori.recordMetric('db.query.duration_ms', 42, undefined, { parent: span })
12
- * span.end({ status: 'ok' })
13
- */
14
- export declare function recordMetric(name: string, value: number, tags?: Record<string, string>, opts?: {
15
- parent?: SpanContextLike;
16
- }): void;
17
- export declare function flushMetrics(): Promise<void>;
18
- /**
19
- * Start the 30 s flush timer. Called once from `init()`. Idempotent.
20
- * `clearMetricsTimer` is exposed for tests / teardown.
21
- */
22
- export declare function startMetricsTimer(): void;
23
- export declare function __resetMetricsForTests(): void;
24
- //# sourceMappingURL=metrics.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAkB9D;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,eAAe,CAAA;CAAE,GAClC,IAAI,CAcN;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAOlD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAQxC;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAM7C"}
package/lib/metrics.js DELETED
@@ -1,81 +0,0 @@
1
- // v0.8.3 — custom metrics buffer.
2
- //
3
- // `recordMetric(name, value, tags?)` pushes a point into a fixed-size
4
- // ring. A timer flushes the ring every 30 s (or when the buffer is
5
- // full); captureException also forces a flush so the metrics line up
6
- // with the error event in the dashboard. Best-effort: a flush failure
7
- // drops the batch on the floor — metrics aren't critical telemetry.
8
- //
9
- // Why not one fetch per point: noisy loops (`recordMetric('frame', 1)`
10
- // in a render hook) would burn the JS thread + saturate the device's
11
- // outgoing connection pool. Batching makes the SDK safe to use as a
12
- // cheap counter primitive.
13
- import { getConfig, isInitialized } from './config';
14
- import { sendMetricsBatch } from './transport';
15
- const MAX_BUFFER = 500;
16
- const FLUSH_INTERVAL_MS = 30_000;
17
- let _buf = [];
18
- let _timer = null;
19
- /**
20
- * Record a numeric metric point. Cheap to call from a render hook —
21
- * pushes into a 500-slot ring drained every 30 s (or on overflow).
22
- *
23
- * v2.0 — accepts an optional `parent: SpanContextLike` so a metric
24
- * can be correlated to a span. The dashboard span-detail view joins
25
- * metric points by `tags.span_id` / `tags.trace_id`.
26
- *
27
- * const span = sentori.startSpan({ name: 'db.query users' })
28
- * sentori.recordMetric('db.query.duration_ms', 42, undefined, { parent: span })
29
- * span.end({ status: 'ok' })
30
- */
31
- export function recordMetric(name, value, tags, opts) {
32
- if (!isInitialized())
33
- return;
34
- if (typeof name !== 'string' || name.length === 0 || name.length > 200)
35
- return;
36
- if (typeof value !== 'number' || !Number.isFinite(value))
37
- return;
38
- if (tags && Object.keys(tags).length > 20)
39
- return;
40
- // Merge span-context tags so the dashboard can join metric points
41
- // to the span that produced them without a separate schema column.
42
- const finalTags = opts?.parent
43
- ? { ...(tags ?? {}), span_id: opts.parent.spanId, trace_id: opts.parent.traceId }
44
- : tags;
45
- _buf.push({ name, tags: finalTags, ts: new Date().toISOString(), value });
46
- if (_buf.length >= MAX_BUFFER) {
47
- void flushMetrics();
48
- }
49
- }
50
- export async function flushMetrics() {
51
- if (_buf.length === 0)
52
- return;
53
- const config = getConfig();
54
- if (!config)
55
- return;
56
- const batch = _buf;
57
- _buf = [];
58
- await sendMetricsBatch(config.ingestUrl, config.token, batch);
59
- }
60
- /**
61
- * Start the 30 s flush timer. Called once from `init()`. Idempotent.
62
- * `clearMetricsTimer` is exposed for tests / teardown.
63
- */
64
- export function startMetricsTimer() {
65
- if (_timer !== null)
66
- return;
67
- _timer = setInterval(() => {
68
- void flushMetrics();
69
- }, FLUSH_INTERVAL_MS);
70
- // Don't keep the process alive solely for this timer (Node would).
71
- // In RN setInterval is a NoopRef so this is harmless there.
72
- _timer.unref?.();
73
- }
74
- export function __resetMetricsForTests() {
75
- if (_timer !== null) {
76
- clearInterval(_timer);
77
- _timer = null;
78
- }
79
- _buf = [];
80
- }
81
- //# sourceMappingURL=metrics.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,EAAE;AACF,sEAAsE;AACtE,mEAAmE;AACnE,qEAAqE;AACrE,sEAAsE;AACtE,oEAAoE;AACpE,EAAE;AACF,uEAAuE;AACvE,qEAAqE;AACrE,oEAAoE;AACpE,2BAA2B;AAI3B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAS/C,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC,IAAI,IAAI,GAAY,EAAE,CAAC;AACvB,IAAI,MAAM,GAA0C,IAAI,CAAC;AAEzD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,KAAa,EACb,IAA6B,EAC7B,IAAmC;IAEnC,IAAI,CAAC,aAAa,EAAE;QAAE,OAAO;IAC7B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO;IAC/E,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO;IACjE,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO;IAClD,kEAAkE;IAClE,mEAAmE;IACnE,MAAM,SAAS,GAAuC,IAAI,EAAE,MAAM;QAChE,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;QACjF,CAAC,CAAC,IAAI,CAAC;IACT,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,IAAI,IAAI,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;QAC9B,KAAK,YAAY,EAAE,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC9B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,MAAM,KAAK,GAAG,IAAI,CAAC;IACnB,IAAI,GAAG,EAAE,CAAC;IACV,MAAM,gBAAgB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO;IAC5B,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QACxB,KAAK,YAAY,EAAE,CAAC;IACtB,CAAC,EAAE,iBAAiB,CAAC,CAAC;IACtB,mEAAmE;IACnE,4DAA4D;IAC3D,MAA4C,CAAC,KAAK,EAAE,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,aAAa,CAAC,MAAM,CAAC,CAAC;QACtB,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,GAAG,EAAE,CAAC;AACZ,CAAC"}
@@ -1,12 +0,0 @@
1
- export type PreCrashChannel = 'frame-budget-overrun' | 'memory-pressure' | 'oom-warning' | 'storage-low';
2
- export type PreCrashSentinelOptions = {
3
- enabled: boolean;
4
- channels?: PreCrashChannel[];
5
- /** Lower → more sensitive. Default 32 ms (< 30 fps). */
6
- frameBudgetMs?: number;
7
- /** Fraction of frames in the window that must miss budget. Default 0.5. */
8
- tripRatio?: number;
9
- };
10
- export declare function startPreCrashSentinel(opts: PreCrashSentinelOptions): void;
11
- export declare function stopPreCrashSentinel(): void;
12
- //# sourceMappingURL=pre-crash-sentinel.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pre-crash-sentinel.d.ts","sourceRoot":"","sources":["../src/pre-crash-sentinel.ts"],"names":[],"mappings":"AAmCA,MAAM,MAAM,eAAe,GACvB,sBAAsB,GACtB,iBAAiB,GACjB,aAAa,GACb,aAAa,CAAC;AAElB,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;IAC7B,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,CAUzE;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAK3C"}
@@ -1,116 +0,0 @@
1
- // v0.9.1 +S4 — pre-crash sentinel.
2
- //
3
- // Predictive (vs reactive) telemetry. Subscribes to JS-thread frame
4
- // timing via requestAnimationFrame and, when a rolling 60-frame
5
- // window has ≥ 50% of frames slower than 32 ms (i.e. < 30 fps for
6
- // half the window), emits an `event.kind = nearCrash` to the server.
7
- // Backend stores it in the same events stream so the dashboard shows
8
- // "X user sessions had near-crash signals 4 minutes before the
9
- // actual NSException".
10
- //
11
- // Memory pressure / OOM / storage low signals will need native
12
- // system observers and ship in v1.0. v0.9.1 covers the most common
13
- // runaway-render-loop case purely from JS.
14
- import { startSpan } from '@goliapkg/sentori-core';
15
- import { getBundleInfo } from './bundle-info';
16
- import { collectDeviceForSentinel, getAppForSentinel } from './sentinel-context';
17
- import { getConfig, isInitialized } from './config';
18
- import { enqueue } from './transport';
19
- import { uuidV7 } from './uuid';
20
- const FRAME_BUDGET_MS = 32; // < 30 fps
21
- const WINDOW_FRAMES = 60; // ~1 s at 60 fps
22
- const TRIP_RATIO = 0.5;
23
- const COOLDOWN_MS = 60_000; // don't spam: one nearCrash event per minute
24
- let _running = false;
25
- let _lastFrameAt = 0;
26
- let _slowFrames = 0;
27
- let _totalFrames = 0;
28
- let _lastEmitAt = 0;
29
- let _channels = new Set();
30
- export function startPreCrashSentinel(opts) {
31
- if (!opts.enabled || _running)
32
- return;
33
- _running = true;
34
- _channels = new Set(opts.channels ?? ['frame-budget-overrun']);
35
- if (_channels.has('frame-budget-overrun')) {
36
- startFrameBudgetWatch(opts.frameBudgetMs ?? FRAME_BUDGET_MS, opts.tripRatio ?? TRIP_RATIO);
37
- }
38
- // Native channels (memory-pressure, oom-warning, storage-low) hook
39
- // through a TODO native module in v1.0.
40
- }
41
- export function stopPreCrashSentinel() {
42
- _running = false;
43
- _slowFrames = 0;
44
- _totalFrames = 0;
45
- _channels.clear();
46
- }
47
- function startFrameBudgetWatch(budgetMs, tripRatio) {
48
- if (typeof requestAnimationFrame !== 'function')
49
- return;
50
- _lastFrameAt = Date.now();
51
- function tick() {
52
- if (!_running)
53
- return;
54
- const now = Date.now();
55
- const delta = now - _lastFrameAt;
56
- _lastFrameAt = now;
57
- if (delta >= budgetMs)
58
- _slowFrames++;
59
- _totalFrames++;
60
- if (_totalFrames >= WINDOW_FRAMES) {
61
- const ratio = _slowFrames / _totalFrames;
62
- if (ratio >= tripRatio && now - _lastEmitAt > COOLDOWN_MS) {
63
- _lastEmitAt = now;
64
- emitNearCrash({
65
- slowFrames: _slowFrames,
66
- totalFrames: _totalFrames,
67
- ratio,
68
- windowMs: WINDOW_FRAMES * (budgetMs / 2), // approximate
69
- channel: 'frame-budget-overrun',
70
- });
71
- }
72
- _slowFrames = 0;
73
- _totalFrames = 0;
74
- }
75
- requestAnimationFrame(tick);
76
- }
77
- requestAnimationFrame(tick);
78
- }
79
- function emitNearCrash(data) {
80
- if (!isInitialized())
81
- return;
82
- const config = getConfig();
83
- if (!config)
84
- return;
85
- const span = startSpan('sentori.nearCrash', {
86
- name: data.channel,
87
- tags: {
88
- 'nearCrash.channel': data.channel,
89
- 'nearCrash.ratio': data.ratio.toFixed(3),
90
- 'nearCrash.slow_frames': String(data.slowFrames),
91
- 'nearCrash.total_frames': String(data.totalFrames),
92
- },
93
- });
94
- span.finish({ status: 'ok' });
95
- const event = {
96
- id: uuidV7(),
97
- timestamp: new Date().toISOString(),
98
- kind: 'nearCrash',
99
- platform: 'javascript',
100
- release: config.release,
101
- environment: config.environment,
102
- device: collectDeviceForSentinel(),
103
- app: getAppForSentinel(config.release),
104
- ...(getBundleInfo() ? { bundle: getBundleInfo() } : {}),
105
- error: {
106
- type: 'NearCrash',
107
- message: `frame budget overrun: ${(data.ratio * 100).toFixed(0)}% of last ${data.totalFrames} frames slow`,
108
- stack: [],
109
- },
110
- tags: {
111
- 'nearCrash.channel': data.channel,
112
- },
113
- };
114
- enqueue(event);
115
- }
116
- //# sourceMappingURL=pre-crash-sentinel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pre-crash-sentinel.js","sourceRoot":"","sources":["../src/pre-crash-sentinel.ts"],"names":[],"mappings":"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"}
@@ -1,40 +0,0 @@
1
- export type SecurityReportData = Record<string, unknown>;
2
- /**
3
- * Report an arbitrary security signal. Fire-and-forget; resolves
4
- * with the server-assigned event id on success or `null` on any
5
- * failure (network down, server unhappy, SDK not initialised).
6
- *
7
- * Use the dedicated helpers (`reportPinMismatch`, future
8
- * `reportRootDetected`, …) when their shape applies — the dashboard
9
- * renders kind-specific panels off the well-known kinds.
10
- */
11
- export declare function reportSecurity(kind: string, data?: SecurityReportData): Promise<null | string>;
12
- /**
13
- * v1.1 chunk S4 — link the current device's user / install to a
14
- * federated identity (e.g. a Google sub or Apple `sub`). Idempotent;
15
- * call on every sign-in. Posts to `/v1/security/link`. The dashboard
16
- * uses this to stitch the same user across projects in the Posture
17
- * cross-project view.
18
- *
19
- * Privacy: only the opaque OAuth `subject` value travels. Never pass
20
- * the email, display name, avatar, or any other identity attribute.
21
- */
22
- export declare function linkFederatedIdentity(args: {
23
- provider: string;
24
- subject: string;
25
- userId?: string;
26
- }): Promise<boolean>;
27
- /**
28
- * TLS certificate pin mismatch — caller observed a server cert that
29
- * didn't match the configured pin set. Posts `kind = 'pin.mismatch'`
30
- * with the expected + observed pin (or hash) so the dashboard's
31
- * Pin anomaly panel can cluster reports by server.
32
- */
33
- export declare function reportPinMismatch(args: {
34
- expected: string;
35
- observed: string;
36
- /** Hostname the SDK was connecting to. Used by the dashboard to
37
- * cluster reports per server. */
38
- serverName: string;
39
- }): Promise<null | string>;
40
- //# sourceMappingURL=report-security.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"report-security.d.ts","sourceRoot":"","sources":["../src/report-security.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzD;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAkCxB;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,OAAO,CAAC,CA2BnB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB;sCACkC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAuCzB"}
@@ -1,159 +0,0 @@
1
- // v1.1 chunk S2 — security event reporting.
2
- //
3
- // `sentori.reportSecurity(kind, data)` POSTs a single security event
4
- // to `/v1/security:report`. Helpers wrap common kinds with the right
5
- // payload shape so dashboards can rely on it without coordinating
6
- // schemas with every host app.
7
- //
8
- // Why a separate API from `captureException` / `track`: security
9
- // reports have different retention + access patterns (the trust
10
- // scoring engine in S3 reads them on a hot path) and conflating
11
- // them with errors would pollute issue grouping. Single endpoint,
12
- // no batching: pin mismatches and root-detection signals are
13
- // low-volume by nature (one per app-lifetime in most cases).
14
- import { getConfig, isInitialized } from './config';
15
- import { peekInstallId } from './install-id';
16
- import { getCurrentUserId } from './capture';
17
- const SDK_VERSION = '0.0.0';
18
- /**
19
- * Report an arbitrary security signal. Fire-and-forget; resolves
20
- * with the server-assigned event id on success or `null` on any
21
- * failure (network down, server unhappy, SDK not initialised).
22
- *
23
- * Use the dedicated helpers (`reportPinMismatch`, future
24
- * `reportRootDetected`, …) when their shape applies — the dashboard
25
- * renders kind-specific panels off the well-known kinds.
26
- */
27
- export async function reportSecurity(kind, data = {}) {
28
- if (!isInitialized())
29
- return null;
30
- if (typeof kind !== 'string' || kind.length === 0 || kind.length > 100) {
31
- return null;
32
- }
33
- if (Object.keys(data).length > 40)
34
- return null;
35
- const config = getConfig();
36
- if (!config)
37
- return null;
38
- const body = {
39
- kind,
40
- data,
41
- ts: new Date().toISOString(),
42
- userId: getCurrentUserId(),
43
- installId: peekInstallId() ?? undefined,
44
- release: config.release,
45
- environment: config.environment,
46
- };
47
- try {
48
- const resp = await fetch(`${config.ingestUrl}/v1/security:report`, {
49
- body: JSON.stringify(body),
50
- headers: {
51
- Authorization: `Bearer ${config.token}`,
52
- 'Content-Type': 'application/json',
53
- 'Sentori-Sdk': `react-native/${SDK_VERSION}`,
54
- },
55
- method: 'POST',
56
- });
57
- if (!resp.ok)
58
- return null;
59
- const parsed = (await resp.json().catch(() => null));
60
- return parsed?.id ?? null;
61
- }
62
- catch {
63
- return null;
64
- }
65
- }
66
- /**
67
- * v1.1 chunk S4 — link the current device's user / install to a
68
- * federated identity (e.g. a Google sub or Apple `sub`). Idempotent;
69
- * call on every sign-in. Posts to `/v1/security/link`. The dashboard
70
- * uses this to stitch the same user across projects in the Posture
71
- * cross-project view.
72
- *
73
- * Privacy: only the opaque OAuth `subject` value travels. Never pass
74
- * the email, display name, avatar, or any other identity attribute.
75
- */
76
- export async function linkFederatedIdentity(args) {
77
- if (!args || typeof args.provider !== 'string' || args.provider.length === 0)
78
- return false;
79
- if (typeof args.subject !== 'string' || args.subject.length === 0)
80
- return false;
81
- if (!isInitialized())
82
- return false;
83
- const config = getConfig();
84
- if (!config)
85
- return false;
86
- const installId = peekInstallId() ?? undefined;
87
- const body = {
88
- provider: args.provider,
89
- subject: args.subject,
90
- userId: args.userId ?? getCurrentUserId(),
91
- installId,
92
- };
93
- try {
94
- const resp = await fetch(`${config.ingestUrl}/v1/security/link`, {
95
- body: JSON.stringify(body),
96
- headers: {
97
- Authorization: `Bearer ${config.token}`,
98
- 'Content-Type': 'application/json',
99
- 'Sentori-Sdk': `react-native/${SDK_VERSION}`,
100
- },
101
- method: 'POST',
102
- });
103
- return resp.ok;
104
- }
105
- catch {
106
- return false;
107
- }
108
- }
109
- /**
110
- * TLS certificate pin mismatch — caller observed a server cert that
111
- * didn't match the configured pin set. Posts `kind = 'pin.mismatch'`
112
- * with the expected + observed pin (or hash) so the dashboard's
113
- * Pin anomaly panel can cluster reports by server.
114
- */
115
- export async function reportPinMismatch(args) {
116
- if (!args || typeof args.serverName !== 'string' || args.serverName.length === 0) {
117
- return null;
118
- }
119
- // The serverName rides on the top-level envelope (column-typed on
120
- // the server) so dashboard queries don't need to crack the data
121
- // JSONB. We still echo it inside `data` for self-contained payloads.
122
- if (!isInitialized())
123
- return null;
124
- const config = getConfig();
125
- if (!config)
126
- return null;
127
- const body = {
128
- kind: 'pin.mismatch',
129
- serverName: args.serverName,
130
- ts: new Date().toISOString(),
131
- userId: getCurrentUserId(),
132
- installId: peekInstallId() ?? undefined,
133
- release: config.release,
134
- environment: config.environment,
135
- data: {
136
- expected: args.expected,
137
- observed: args.observed,
138
- },
139
- };
140
- try {
141
- const resp = await fetch(`${config.ingestUrl}/v1/security:report`, {
142
- body: JSON.stringify(body),
143
- headers: {
144
- Authorization: `Bearer ${config.token}`,
145
- 'Content-Type': 'application/json',
146
- 'Sentori-Sdk': `react-native/${SDK_VERSION}`,
147
- },
148
- method: 'POST',
149
- });
150
- if (!resp.ok)
151
- return null;
152
- const parsed = (await resp.json().catch(() => null));
153
- return parsed?.id ?? null;
154
- }
155
- catch {
156
- return null;
157
- }
158
- }
159
- //# sourceMappingURL=report-security.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"report-security.js","sourceRoot":"","sources":["../src/report-security.ts"],"names":[],"mappings":"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"}
@@ -1,19 +0,0 @@
1
- /** Idempotent start. Safe to call multiple times; only the first
2
- * call kicks off the rAF loop. */
3
- export declare function startFpsInstrument(): void;
4
- /** Stop the loop. Used by tests + by hosts that want to opt out
5
- * mid-session. */
6
- export declare function stopFpsInstrument(): void;
7
- /** Test-only state inspection. */
8
- export declare function __peekFpsInstrumentState(): {
9
- count: number;
10
- running: boolean;
11
- };
12
- /** Test-only force-emit (skips the every-300-frames gate). */
13
- export declare function __forceEmitFpsForTests(): void;
14
- /** Test-only sample injection so we can assert without spinning
15
- * rAF in the test runner. */
16
- export declare function __pushSampleForTests(dt: number): void;
17
- /** Test-only reset between runs. */
18
- export declare function __resetFpsInstrumentForTests(): void;
19
- //# sourceMappingURL=runtime-metrics-fps.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtime-metrics-fps.d.ts","sourceRoot":"","sources":["../src/runtime-metrics-fps.ts"],"names":[],"mappings":"AAwFA;mCACmC;AACnC,wBAAgB,kBAAkB,IAAI,IAAI,CAQzC;AAED;mBACmB;AACnB,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,kCAAkC;AAClC,wBAAgB,wBAAwB,IAAI;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB,CAEA;AAED,8DAA8D;AAC9D,wBAAgB,sBAAsB,IAAI,IAAI,CAI7C;AAED;8BAC8B;AAC9B,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAIrD;AAED,oCAAoC;AACpC,wBAAgB,4BAA4B,IAAI,IAAI,CAMnD"}