@goliapkg/sentori-react-native 3.1.0 → 5.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 (284) hide show
  1. package/android/build.gradle +21 -0
  2. package/android/src/main/java/com/sentori/SentoriCrashHandler.kt +29 -0
  3. package/android/src/test/java/com/sentori/SentoriCrashHandlerTest.kt +7 -2
  4. package/android/src/test/resources/robolectric.properties +10 -0
  5. package/lib/config.d.ts +16 -47
  6. package/lib/config.d.ts.map +1 -1
  7. package/lib/config.js +3 -0
  8. package/lib/config.js.map +1 -1
  9. package/lib/device.d.ts +5 -0
  10. package/lib/device.d.ts.map +1 -0
  11. package/lib/device.js +29 -0
  12. package/lib/device.js.map +1 -0
  13. package/lib/emit-hooks.d.ts +7 -0
  14. package/lib/emit-hooks.d.ts.map +1 -0
  15. package/lib/emit-hooks.js +24 -0
  16. package/lib/emit-hooks.js.map +1 -0
  17. package/lib/error-boundary.d.ts.map +1 -1
  18. package/lib/error-boundary.js +1 -1
  19. package/lib/error-boundary.js.map +1 -1
  20. package/lib/feature-flags.d.ts.map +1 -1
  21. package/lib/handlers/dev-symbolicate.d.ts +1 -1
  22. package/lib/handlers/dev-symbolicate.d.ts.map +1 -1
  23. package/lib/handlers/dev-symbolicate.js +2 -0
  24. package/lib/handlers/dev-symbolicate.js.map +1 -1
  25. package/lib/handlers/global.js +1 -1
  26. package/lib/handlers/global.js.map +1 -1
  27. package/lib/handlers/lifecycle.js +3 -3
  28. package/lib/handlers/lifecycle.js.map +1 -1
  29. package/lib/handlers/network.d.ts +2 -2
  30. package/lib/handlers/network.d.ts.map +1 -1
  31. package/lib/handlers/network.js +69 -187
  32. package/lib/handlers/network.js.map +1 -1
  33. package/lib/handlers/promise.js +1 -1
  34. package/lib/handlers/promise.js.map +1 -1
  35. package/lib/handlers/screenshot.d.ts.map +1 -1
  36. package/lib/handlers/screenshot.js +3 -12
  37. package/lib/handlers/screenshot.js.map +1 -1
  38. package/lib/index.d.ts +31 -109
  39. package/lib/index.d.ts.map +1 -1
  40. package/lib/index.js +51 -103
  41. package/lib/index.js.map +1 -1
  42. package/lib/init.d.ts +3 -150
  43. package/lib/init.d.ts.map +1 -1
  44. package/lib/init.js +88 -261
  45. package/lib/init.js.map +1 -1
  46. package/lib/long-task-monitor.d.ts +1 -7
  47. package/lib/long-task-monitor.d.ts.map +1 -1
  48. package/lib/long-task-monitor.js +37 -58
  49. package/lib/long-task-monitor.js.map +1 -1
  50. package/lib/mobile-vitals.d.ts +3 -31
  51. package/lib/mobile-vitals.d.ts.map +1 -1
  52. package/lib/mobile-vitals.js +22 -61
  53. package/lib/mobile-vitals.js.map +1 -1
  54. package/lib/native-pending.d.ts +3 -0
  55. package/lib/native-pending.d.ts.map +1 -0
  56. package/lib/native-pending.js +64 -0
  57. package/lib/native-pending.js.map +1 -0
  58. package/lib/navigation.d.ts +3 -17
  59. package/lib/navigation.d.ts.map +1 -1
  60. package/lib/navigation.js +32 -133
  61. package/lib/navigation.js.map +1 -1
  62. package/lib/netinfo.d.ts +1 -1
  63. package/lib/netinfo.d.ts.map +1 -1
  64. package/lib/netinfo.js +2 -2
  65. package/lib/netinfo.js.map +1 -1
  66. package/lib/push.d.ts.map +1 -1
  67. package/lib/push.js +2 -4
  68. package/lib/push.js.map +1 -1
  69. package/lib/rage-tap.d.ts.map +1 -1
  70. package/lib/rage-tap.js +28 -23
  71. package/lib/rage-tap.js.map +1 -1
  72. package/lib/replay.d.ts.map +1 -1
  73. package/lib/replay.js +3 -24
  74. package/lib/replay.js.map +1 -1
  75. package/lib/scope.d.ts +7 -0
  76. package/lib/scope.d.ts.map +1 -0
  77. package/lib/scope.js +41 -0
  78. package/lib/scope.js.map +1 -0
  79. package/lib/transport.d.ts +19 -92
  80. package/lib/transport.d.ts.map +1 -1
  81. package/lib/transport.js +75 -288
  82. package/lib/transport.js.map +1 -1
  83. package/lib/verbs.d.ts +16 -0
  84. package/lib/verbs.d.ts.map +1 -0
  85. package/lib/verbs.js +153 -0
  86. package/lib/verbs.js.map +1 -0
  87. package/package.json +5 -5
  88. package/src/__tests__/iron-rule.test.ts +128 -0
  89. package/src/__tests__/screenshot.test.ts +0 -2
  90. package/src/__tests__/transport.test.ts +66 -213
  91. package/src/__tests__/verbs.test.ts +91 -0
  92. package/src/config.ts +19 -47
  93. package/src/device.ts +36 -0
  94. package/src/emit-hooks.ts +30 -0
  95. package/src/error-boundary.tsx +1 -1
  96. package/src/handlers/dev-symbolicate.ts +2 -1
  97. package/src/handlers/global.ts +1 -1
  98. package/src/handlers/lifecycle.ts +3 -3
  99. package/src/handlers/network.ts +95 -211
  100. package/src/handlers/promise.ts +1 -1
  101. package/src/handlers/screenshot.ts +3 -11
  102. package/src/index.ts +81 -215
  103. package/src/init.ts +94 -446
  104. package/src/long-task-monitor.ts +42 -64
  105. package/src/mobile-vitals.ts +22 -82
  106. package/src/native-pending.ts +92 -0
  107. package/src/navigation.ts +34 -142
  108. package/src/netinfo.ts +3 -3
  109. package/src/push.ts +2 -5
  110. package/src/rage-tap.tsx +29 -26
  111. package/src/replay.ts +3 -20
  112. package/src/scope.ts +50 -0
  113. package/src/transport.ts +84 -371
  114. package/src/verbs.ts +198 -0
  115. package/lib/breadcrumbs.d.ts +0 -18
  116. package/lib/breadcrumbs.d.ts.map +0 -1
  117. package/lib/breadcrumbs.js +0 -42
  118. package/lib/breadcrumbs.js.map +0 -1
  119. package/lib/bundle-info.d.ts +0 -12
  120. package/lib/bundle-info.d.ts.map +0 -1
  121. package/lib/bundle-info.js +0 -73
  122. package/lib/bundle-info.js.map +0 -1
  123. package/lib/capture.d.ts +0 -140
  124. package/lib/capture.d.ts.map +0 -1
  125. package/lib/capture.js +0 -511
  126. package/lib/capture.js.map +0 -1
  127. package/lib/compat/sentry.d.ts +0 -126
  128. package/lib/compat/sentry.d.ts.map +0 -1
  129. package/lib/compat/sentry.js +0 -332
  130. package/lib/compat/sentry.js.map +0 -1
  131. package/lib/control-channel.d.ts +0 -6
  132. package/lib/control-channel.d.ts.map +0 -1
  133. package/lib/control-channel.js +0 -96
  134. package/lib/control-channel.js.map +0 -1
  135. package/lib/expo-compat.d.ts +0 -270
  136. package/lib/expo-compat.d.ts.map +0 -1
  137. package/lib/expo-compat.js +0 -500
  138. package/lib/expo-compat.js.map +0 -1
  139. package/lib/feedback-widget.d.ts +0 -35
  140. package/lib/feedback-widget.d.ts.map +0 -1
  141. package/lib/feedback-widget.js +0 -193
  142. package/lib/feedback-widget.js.map +0 -1
  143. package/lib/feedback.d.ts +0 -2
  144. package/lib/feedback.d.ts.map +0 -1
  145. package/lib/feedback.js +0 -17
  146. package/lib/feedback.js.map +0 -1
  147. package/lib/heartbeat.d.ts +0 -9
  148. package/lib/heartbeat.d.ts.map +0 -1
  149. package/lib/heartbeat.js +0 -138
  150. package/lib/heartbeat.js.map +0 -1
  151. package/lib/index.js.bak +0 -64
  152. package/lib/install-id.d.ts +0 -17
  153. package/lib/install-id.d.ts.map +0 -1
  154. package/lib/install-id.js +0 -125
  155. package/lib/install-id.js.map +0 -1
  156. package/lib/lifecycle.d.ts +0 -28
  157. package/lib/lifecycle.d.ts.map +0 -1
  158. package/lib/lifecycle.js +0 -73
  159. package/lib/lifecycle.js.map +0 -1
  160. package/lib/mask.d.ts +0 -16
  161. package/lib/mask.d.ts.map +0 -1
  162. package/lib/mask.js +0 -36
  163. package/lib/mask.js.map +0 -1
  164. package/lib/measure.d.ts +0 -4
  165. package/lib/measure.d.ts.map +0 -1
  166. package/lib/measure.js +0 -25
  167. package/lib/measure.js.map +0 -1
  168. package/lib/metrics.d.ts +0 -24
  169. package/lib/metrics.d.ts.map +0 -1
  170. package/lib/metrics.js +0 -81
  171. package/lib/metrics.js.map +0 -1
  172. package/lib/pre-crash-sentinel.d.ts +0 -12
  173. package/lib/pre-crash-sentinel.d.ts.map +0 -1
  174. package/lib/pre-crash-sentinel.js +0 -116
  175. package/lib/pre-crash-sentinel.js.map +0 -1
  176. package/lib/report-security.d.ts +0 -40
  177. package/lib/report-security.d.ts.map +0 -1
  178. package/lib/report-security.js +0 -159
  179. package/lib/report-security.js.map +0 -1
  180. package/lib/runtime-metrics-fps.d.ts +0 -19
  181. package/lib/runtime-metrics-fps.d.ts.map +0 -1
  182. package/lib/runtime-metrics-fps.js +0 -128
  183. package/lib/runtime-metrics-fps.js.map +0 -1
  184. package/lib/runtime-metrics-heap.d.ts +0 -13
  185. package/lib/runtime-metrics-heap.d.ts.map +0 -1
  186. package/lib/runtime-metrics-heap.js +0 -67
  187. package/lib/runtime-metrics-heap.js.map +0 -1
  188. package/lib/runtime-metrics-network.d.ts +0 -23
  189. package/lib/runtime-metrics-network.d.ts.map +0 -1
  190. package/lib/runtime-metrics-network.js +0 -99
  191. package/lib/runtime-metrics-network.js.map +0 -1
  192. package/lib/runtime-metrics.d.ts +0 -43
  193. package/lib/runtime-metrics.d.ts.map +0 -1
  194. package/lib/runtime-metrics.js +0 -115
  195. package/lib/runtime-metrics.js.map +0 -1
  196. package/lib/sample-profiler.d.ts +0 -21
  197. package/lib/sample-profiler.d.ts.map +0 -1
  198. package/lib/sample-profiler.js +0 -152
  199. package/lib/sample-profiler.js.map +0 -1
  200. package/lib/sentinel-context.d.ts +0 -4
  201. package/lib/sentinel-context.d.ts.map +0 -1
  202. package/lib/sentinel-context.js +0 -52
  203. package/lib/sentinel-context.js.map +0 -1
  204. package/lib/session-tracker.d.ts +0 -6
  205. package/lib/session-tracker.d.ts.map +0 -1
  206. package/lib/session-tracker.js +0 -50
  207. package/lib/session-tracker.js.map +0 -1
  208. package/lib/stack.d.ts +0 -3
  209. package/lib/stack.d.ts.map +0 -1
  210. package/lib/stack.js +0 -7
  211. package/lib/stack.js.map +0 -1
  212. package/lib/state-snapshots.d.ts +0 -33
  213. package/lib/state-snapshots.d.ts.map +0 -1
  214. package/lib/state-snapshots.js +0 -109
  215. package/lib/state-snapshots.js.map +0 -1
  216. package/lib/track.d.ts +0 -34
  217. package/lib/track.d.ts.map +0 -1
  218. package/lib/track.js +0 -107
  219. package/lib/track.js.map +0 -1
  220. package/lib/trail.d.ts +0 -12
  221. package/lib/trail.d.ts.map +0 -1
  222. package/lib/trail.js +0 -28
  223. package/lib/trail.js.map +0 -1
  224. package/lib/trust-score.d.ts +0 -20
  225. package/lib/trust-score.d.ts.map +0 -1
  226. package/lib/trust-score.js +0 -151
  227. package/lib/trust-score.js.map +0 -1
  228. package/lib/types.d.ts +0 -2
  229. package/lib/types.d.ts.map +0 -1
  230. package/lib/types.js +0 -4
  231. package/lib/types.js.map +0 -1
  232. package/lib/uuid.d.ts +0 -2
  233. package/lib/uuid.d.ts.map +0 -1
  234. package/lib/uuid.js +0 -3
  235. package/lib/uuid.js.map +0 -1
  236. package/src/__tests__/before-send.test.ts +0 -72
  237. package/src/__tests__/breadcrumbs.test.ts +0 -44
  238. package/src/__tests__/capture-replay.test.ts +0 -150
  239. package/src/__tests__/compat-sentry.test.ts +0 -121
  240. package/src/__tests__/control-channel.test.ts +0 -111
  241. package/src/__tests__/install-id.test.ts +0 -60
  242. package/src/__tests__/long-task-monitor.test.ts +0 -59
  243. package/src/__tests__/measure.test.ts +0 -45
  244. package/src/__tests__/navigation.test.ts +0 -175
  245. package/src/__tests__/push.test.ts +0 -238
  246. package/src/__tests__/report-security.test.ts +0 -106
  247. package/src/__tests__/runtime-metrics-instruments.test.ts +0 -109
  248. package/src/__tests__/runtime-metrics-network.test.ts +0 -78
  249. package/src/__tests__/sample-profiler.test.ts +0 -59
  250. package/src/__tests__/stack.test.ts +0 -45
  251. package/src/__tests__/state-snapshots.test.ts +0 -119
  252. package/src/__tests__/tracing.test.ts +0 -201
  253. package/src/__tests__/track.test.ts +0 -91
  254. package/src/__tests__/uuid.test.ts +0 -41
  255. package/src/breadcrumbs.ts +0 -57
  256. package/src/bundle-info.ts +0 -95
  257. package/src/capture.ts +0 -660
  258. package/src/compat/sentry.ts +0 -490
  259. package/src/control-channel.ts +0 -98
  260. package/src/expo-compat.ts +0 -698
  261. package/src/feedback-widget.tsx +0 -316
  262. package/src/feedback.ts +0 -21
  263. package/src/heartbeat.ts +0 -157
  264. package/src/install-id.ts +0 -146
  265. package/src/lifecycle.ts +0 -76
  266. package/src/mask.ts +0 -41
  267. package/src/measure.ts +0 -28
  268. package/src/metrics.ts +0 -94
  269. package/src/pre-crash-sentinel.ts +0 -140
  270. package/src/report-security.ts +0 -165
  271. package/src/runtime-metrics-fps.ts +0 -137
  272. package/src/runtime-metrics-heap.ts +0 -78
  273. package/src/runtime-metrics-network.ts +0 -103
  274. package/src/runtime-metrics.ts +0 -122
  275. package/src/sample-profiler.ts +0 -169
  276. package/src/sentinel-context.ts +0 -60
  277. package/src/session-tracker.ts +0 -53
  278. package/src/stack.ts +0 -10
  279. package/src/state-snapshots.ts +0 -133
  280. package/src/track.ts +0 -123
  281. package/src/trail.ts +0 -32
  282. package/src/trust-score.ts +0 -176
  283. package/src/types.ts +0 -21
  284. package/src/uuid.ts +0 -2
package/lib/trail.js DELETED
@@ -1,28 +0,0 @@
1
- // Phase 46 — singleton TrailBuffer for the RN SDK.
2
- //
3
- // Kept in its own module so callers (including navigation.ts, which
4
- // is intentionally lightweight) can record steps without pulling in
5
- // capture.ts → handlers/screenshot.ts → react-native. The buffer is
6
- // drained inside capture.ts when an event captures and
7
- // `sessionTrailEnabled` is on.
8
- import { TrailBuffer } from '@goliapkg/sentori-core';
9
- const _trail = new TrailBuffer(30);
10
- /**
11
- * Phase 46 — record a step into the session-trail buffer. The buffer
12
- * is a fixed-size FIFO (default 30 steps); pushing past capacity
13
- * drops the oldest entry. Steps are only uploaded if
14
- * `init({ capture: { sessionTrail: true } })` is on AND a
15
- * `captureException` follows.
16
- */
17
- export const captureStep = (label, opts) => {
18
- _trail.push({
19
- ts: Date.now(),
20
- label,
21
- ...(opts ?? {}),
22
- });
23
- };
24
- export const getTrailBuffer = () => _trail;
25
- export const __resetTrailForTests = () => {
26
- _trail.clear();
27
- };
28
- //# sourceMappingURL=trail.js.map
package/lib/trail.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"trail.js","sourceRoot":"","sources":["../src/trail.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,oEAAoE;AACpE,oEAAoE;AACpE,oEAAoE;AACpE,uDAAuD;AACvD,+BAA+B;AAE/B,OAAO,EAAE,WAAW,EAAkB,MAAM,wBAAwB,CAAC;AAErE,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,IAAyB,EAAQ,EAAE;IAC5E,MAAM,CAAC,IAAI,CAAC;QACV,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;QACd,KAAK;QACL,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;KAChB,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAgB,EAAE,CAAC,MAAM,CAAC;AAExD,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAS,EAAE;IAC7C,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC,CAAC"}
@@ -1,20 +0,0 @@
1
- export type TrustSignal = {
2
- count: number;
3
- kind: string;
4
- weight: number;
5
- };
6
- export type TrustScore = {
7
- computedAt: string;
8
- installId: string;
9
- score: number;
10
- signals: TrustSignal[];
11
- };
12
- /**
13
- * Resolve the device's trust score. Always resolves — never throws,
14
- * never rejects. The two-layer cache means the first call after cold
15
- * start usually serves a < 1 ms result while a background refresh
16
- * keeps the value current.
17
- */
18
- export declare function queryTrustScore(): Promise<TrustScore>;
19
- export declare function __resetTrustScoreForTests(): void;
20
- //# sourceMappingURL=trust-score.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"trust-score.d.ts","sourceRoot":"","sources":["../src/trust-score.ts"],"names":[],"mappings":"AA6BA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAqFF;;;;;GAKG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,UAAU,CAAC,CAuC3D;AAED,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD"}
@@ -1,151 +0,0 @@
1
- // v1.1 chunk S3 — `sentori.queryTrustScore()` for the host app.
2
- //
3
- // Returns the device's current trust score (0–100, higher = healthier)
4
- // plus the per-kind signal mix that produced it. The host app uses
5
- // this to decide whether to step up authentication, decline a
6
- // purchase, or simply log a soft warning.
7
- //
8
- // Caching:
9
- // L1 — process-memory, ~30 s. Same process should not re-fetch on
10
- // every screen render; the score moves on a "minutes" cadence.
11
- // L2 — install-id-derived AsyncStorage entry, ~5 minutes. Lets the
12
- // host paint a cached score on cold start without waiting for
13
- // the network. Stale entries are still served; the SDK
14
- // re-fetches in the background.
15
- //
16
- // Fail-soft posture: if the network's down or the SDK isn't
17
- // initialised, returns the cached value (if any), else the safe
18
- // default (score = 100). The host should never see a thrown error
19
- // from this call — the score system is supposed to be invisible.
20
- import { isAnyNativeModuleLinked } from './native-loader';
21
- import { getConfig, isInitialized } from './config';
22
- import { getInstallId } from './install-id';
23
- const SDK_VERSION = '0.0.0';
24
- const STORAGE_KEY = '@sentori/trust-score';
25
- const L1_TTL_MS = 30_000;
26
- const L2_TTL_MS = 5 * 60_000;
27
- let _l1 = null;
28
- let _inflight = null;
29
- function loadAsyncStorage() {
30
- if (!isAnyNativeModuleLinked(['RNCAsyncStorage', 'AsyncStorageModule']))
31
- return null;
32
- try {
33
- // eslint-disable-next-line @typescript-eslint/no-require-imports
34
- const mod = require('@react-native-async-storage/async-storage');
35
- return mod.default ?? mod;
36
- }
37
- catch {
38
- return null;
39
- }
40
- }
41
- function safeDefault(installId) {
42
- return {
43
- computedAt: new Date().toISOString(),
44
- installId,
45
- score: 100,
46
- signals: [],
47
- };
48
- }
49
- async function readL2() {
50
- const storage = loadAsyncStorage();
51
- if (!storage)
52
- return null;
53
- try {
54
- const raw = await storage.getItem(STORAGE_KEY);
55
- if (!raw)
56
- return null;
57
- const parsed = JSON.parse(raw);
58
- if (typeof parsed?.fetchedAt !== 'number' ||
59
- typeof parsed?.score?.score !== 'number') {
60
- return null;
61
- }
62
- return parsed;
63
- }
64
- catch {
65
- return null;
66
- }
67
- }
68
- async function writeL2(entry) {
69
- const storage = loadAsyncStorage();
70
- if (!storage)
71
- return;
72
- try {
73
- await storage.setItem(STORAGE_KEY, JSON.stringify(entry));
74
- }
75
- catch {
76
- // best-effort
77
- }
78
- }
79
- async function fetchFresh(installId) {
80
- const config = getConfig();
81
- if (!config)
82
- return safeDefault(installId);
83
- try {
84
- const resp = await fetch(`${config.ingestUrl}/v1/security/score?installId=${encodeURIComponent(installId)}`, {
85
- headers: {
86
- Authorization: `Bearer ${config.token}`,
87
- 'Sentori-Sdk': `react-native/${SDK_VERSION}`,
88
- },
89
- method: 'GET',
90
- });
91
- if (!resp.ok)
92
- return safeDefault(installId);
93
- const parsed = (await resp.json());
94
- return parsed;
95
- }
96
- catch {
97
- return safeDefault(installId);
98
- }
99
- }
100
- /**
101
- * Resolve the device's trust score. Always resolves — never throws,
102
- * never rejects. The two-layer cache means the first call after cold
103
- * start usually serves a < 1 ms result while a background refresh
104
- * keeps the value current.
105
- */
106
- export async function queryTrustScore() {
107
- if (!isInitialized()) {
108
- const id = await getInstallId();
109
- return safeDefault(id);
110
- }
111
- // L1 hit
112
- const now = Date.now();
113
- if (_l1 && now - _l1.fetchedAt < L1_TTL_MS) {
114
- return _l1.score;
115
- }
116
- // Coalesce concurrent calls onto the same inflight fetch.
117
- if (_inflight)
118
- return _inflight;
119
- _inflight = (async () => {
120
- try {
121
- const installId = await getInstallId();
122
- // L2 hit — serve immediately, kick off background refresh
123
- const l2 = await readL2();
124
- if (l2 && now - l2.fetchedAt < L2_TTL_MS && l2.score.installId === installId) {
125
- _l1 = l2;
126
- // background refresh (don't block caller)
127
- void (async () => {
128
- const fresh = await fetchFresh(installId);
129
- const entry = { fetchedAt: Date.now(), score: fresh };
130
- _l1 = entry;
131
- await writeL2(entry);
132
- })();
133
- return l2.score;
134
- }
135
- const fresh = await fetchFresh(installId);
136
- const entry = { fetchedAt: Date.now(), score: fresh };
137
- _l1 = entry;
138
- await writeL2(entry);
139
- return fresh;
140
- }
141
- finally {
142
- _inflight = null;
143
- }
144
- })();
145
- return _inflight;
146
- }
147
- export function __resetTrustScoreForTests() {
148
- _l1 = null;
149
- _inflight = null;
150
- }
151
- //# sourceMappingURL=trust-score.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"trust-score.js","sourceRoot":"","sources":["../src/trust-score.ts"],"names":[],"mappings":"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"}
package/lib/types.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export type { App, AttachmentKind, AttachmentMeta, AttachmentSource, Breadcrumb, BreadcrumbType, CaptureExtras, Device, DeviceOS, Event, EventKind, Frame, Platform, SentoriError, Tags, User, } from '@goliapkg/sentori-core';
2
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,GAAG,EACH,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,aAAa,EACb,MAAM,EACN,QAAQ,EACR,KAAK,EACL,SAAS,EACT,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,IAAI,EACJ,IAAI,GACL,MAAM,wBAAwB,CAAA"}
package/lib/types.js DELETED
@@ -1,4 +0,0 @@
1
- // Phase 21: wire-format types moved to @goliapkg/sentori-core. Re-
2
- // exported here so existing relative imports keep working.
3
- export {};
4
- //# sourceMappingURL=types.js.map
package/lib/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,2DAA2D"}
package/lib/uuid.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export { uuidV7 } from '@goliapkg/sentori-core';
2
- //# sourceMappingURL=uuid.d.ts.map
package/lib/uuid.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../src/uuid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA"}
package/lib/uuid.js DELETED
@@ -1,3 +0,0 @@
1
- // Phase 21: moved to @goliapkg/sentori-core.
2
- export { uuidV7 } from '@goliapkg/sentori-core';
3
- //# sourceMappingURL=uuid.js.map
package/lib/uuid.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"uuid.js","sourceRoot":"","sources":["../src/uuid.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA"}
@@ -1,72 +0,0 @@
1
- /**
2
- * v2.3 — beforeSend hook unit coverage for the RN SDK.
3
- *
4
- * We exercise the dispatcher directly via the
5
- * `__applyBeforeSendForTests` test hook rather than running the full
6
- * captureException pipeline. The behaviour-level coverage of
7
- * captureException's enqueue path lives in the JS SDK's `sdk.test.ts`
8
- * (which mocks fetch); the dispatcher itself is the only RN-specific
9
- * piece (RN uses the same NEVER-rule policy as JS, but the
10
- * one-shot warn flag is per-SDK so we verify it in both).
11
- */
12
- import { describe, expect, test } from 'bun:test';
13
-
14
- import { __applyBeforeSendForTests as applyBeforeSend } from '../capture';
15
- import type { Event } from '../types';
16
-
17
- function freshEvent(message: string): Event {
18
- return {
19
- id: '019eaa00-0000-7000-8000-000000000001',
20
- timestamp: '2026-06-03T07:00:00.000Z',
21
- kind: 'message',
22
- platform: 'javascript',
23
- release: 'app@1.0.0+1',
24
- environment: 'test',
25
- device: { os: 'ios' },
26
- app: { version: '1.0.0', build: '1' },
27
- user: null,
28
- tags: {},
29
- breadcrumbs: [],
30
- message,
31
- } as Event;
32
- }
33
-
34
- describe('applyBeforeSend (RN, v2.3)', () => {
35
- test('no hook → returns event unchanged', () => {
36
- const ev = freshEvent('passthrough');
37
- expect(applyBeforeSend(ev, undefined)).toBe(ev);
38
- });
39
-
40
- test('hook mutates: returned event is what the caller sees', () => {
41
- const ev = freshEvent('please scrub');
42
- const out = applyBeforeSend(ev, (e) => ({
43
- ...e,
44
- tags: { ...e.tags, scrubbed: '1' },
45
- }));
46
- expect(out).not.toBeNull();
47
- expect(out!.tags?.scrubbed).toBe('1');
48
- });
49
-
50
- test('hook returns null → dispatcher returns null (caller drops)', () => {
51
- const ev = freshEvent('drop me');
52
- expect(applyBeforeSend(ev, () => null)).toBeNull();
53
- });
54
-
55
- test('hook throws → dispatcher returns the original event (NEVER rule)', () => {
56
- const ev = freshEvent('survives bad hook');
57
- const out = applyBeforeSend(ev, () => {
58
- throw new Error('hook boom');
59
- });
60
- expect(out).toBe(ev);
61
- });
62
-
63
- test('hook returns non-event garbage → dispatcher returns the original event', () => {
64
- const ev = freshEvent('survives bad return');
65
- const out = applyBeforeSend(
66
- ev,
67
- // @ts-expect-error — host returns garbage; v2.3 contract is "fall back unmodified"
68
- () => 42,
69
- );
70
- expect(out).toBe(ev);
71
- });
72
- });
@@ -1,44 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'bun:test';
2
-
3
- import {
4
- addBreadcrumb,
5
- getBreadcrumbs,
6
- __resetForTests,
7
- } from '../breadcrumbs';
8
-
9
- describe('breadcrumbs', () => {
10
- beforeEach(() => {
11
- __resetForTests();
12
- });
13
-
14
- it('adds and retrieves a breadcrumb', () => {
15
- addBreadcrumb({ type: 'log', data: { level: 'info', message: 'hi' } });
16
- const crumbs = getBreadcrumbs();
17
- expect(crumbs).toHaveLength(1);
18
- expect(crumbs[0]?.type).toBe('log');
19
- expect(crumbs[0]?.data.message).toBe('hi');
20
- });
21
-
22
- it('auto-generates ISO 8601 timestamp when not provided', () => {
23
- addBreadcrumb({ type: 'nav', data: { from: 'a', to: 'b' } });
24
- const crumbs = getBreadcrumbs();
25
- expect(crumbs[0]?.timestamp).toMatch(/^\d{4}-\d{2}-\d{2}T/);
26
- });
27
-
28
- it('caps at 100 entries (oldest discarded)', () => {
29
- for (let i = 0; i < 150; i++) {
30
- addBreadcrumb({ type: 'custom', data: { i } });
31
- }
32
- const crumbs = getBreadcrumbs();
33
- expect(crumbs).toHaveLength(100);
34
- expect(crumbs[0]?.data.i).toBe(50);
35
- expect(crumbs[99]?.data.i).toBe(149);
36
- });
37
-
38
- it('returns a fresh copy on each getBreadcrumbs call', () => {
39
- addBreadcrumb({ type: 'log', data: {} });
40
- const a = getBreadcrumbs();
41
- const b = getBreadcrumbs();
42
- expect(a).not.toBe(b);
43
- });
44
- });
@@ -1,150 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, mock, test } from 'bun:test';
2
-
3
- import { __captureAndAttachReplayForTests } from '../capture';
4
- import { setConfig, __resetForTests as resetConfig } from '../config';
5
- import type { Event } from '../types';
6
-
7
- // Insight 2026-05-18 rc.3 verify: walker is healthy, ticks land
8
- // deep wireframe JSON with TextView text, but the `replay` kind
9
- // never reaches `event.attachments`. Root cause was the inline
10
- // `btoa(ndjson)` upload path — spec-compliant Hermes / Bun btoa
11
- // throws `InvalidCharacterError` on any code point > 0xFF, and the
12
- // surrounding catch swallowed the throw silently. rc.4 routes
13
- // through `base64Utf8`, fixing both Latin-1 and UTF-8 inputs.
14
- //
15
- // These tests run the actual captureAndAttachReplay function the
16
- // captureException pipeline runs. fetch is mocked at the
17
- // transport.ts boundary so the upload landing isn't tested here
18
- // (covered separately in screenshot.test.ts); what we care about
19
- // is "does event.attachments grow when the input contains
20
- // non-Latin-1 text?".
21
-
22
- const origFetch = globalThis.fetch;
23
-
24
- beforeEach(() => {
25
- setConfig({
26
- enabled: true,
27
- environment: 'test',
28
- errorSampleRate: null,
29
- ingestUrl: 'http://localhost:18080',
30
- release: 'app@1.0.0+1',
31
- screenshotsEnabled: true,
32
- sessionTrailEnabled: true,
33
- token: 'st_pk_test',
34
- traceSampleRate: null,
35
- });
36
- });
37
-
38
- afterEach(() => {
39
- globalThis.fetch = origFetch;
40
- resetConfig();
41
- });
42
-
43
- function makeEvent(): Event {
44
- return {
45
- id: '019eaa00-0000-7000-8000-000000000001',
46
- timestamp: '2026-05-18T05:15:24.000Z',
47
- kind: 'error',
48
- platform: 'javascript',
49
- release: 'app@1.0.0+1',
50
- environment: 'test',
51
- device: { os: 'android', osVersion: '36' },
52
- app: {
53
- version: '1.0.0',
54
- build: '1',
55
- framework: { name: 'react-native', version: '0.80.0' },
56
- },
57
- user: null,
58
- tags: undefined,
59
- breadcrumbs: [],
60
- error: { type: 'Error', message: 'boom', stack: [], cause: null },
61
- fingerprint: undefined,
62
- };
63
- }
64
-
65
- function mockUploadSuccess(): { calls: { url: string; body: unknown }[] } {
66
- const calls: { url: string; body: unknown }[] = [];
67
- globalThis.fetch = mock(async (url: Request | string | URL, init?: RequestInit) => {
68
- let body: unknown = undefined;
69
- try {
70
- body = init?.body ? JSON.parse(String(init.body)) : undefined;
71
- } catch {
72
- body = init?.body;
73
- }
74
- calls.push({ url: String(url), body });
75
- return new Response(
76
- JSON.stringify({
77
- kind: 'replay',
78
- mediaType: 'application/x-ndjson',
79
- refId: '019e3000-7000-7000-8000-00000000aaaa',
80
- sizeBytes: 200,
81
- }),
82
- { headers: { 'content-type': 'application/json' }, status: 201 },
83
- );
84
- }) as typeof fetch;
85
- return { calls };
86
- }
87
-
88
- describe('captureAndAttachReplay — Insight rc.3 regression', () => {
89
- test('Latin-1 ndjson attaches replay kind (control)', async () => {
90
- const { calls } = mockUploadSuccess();
91
- const event = makeEvent();
92
- const ndjson =
93
- '{"ts":1700000000,"width":390,"height":844,"nodes":[' +
94
- '{"kind":"text","x":10,"y":20,"w":100,"h":20,"text":"Settings"}]}';
95
- await __captureAndAttachReplayForTests(event, ndjson);
96
- expect(calls.length).toBe(1);
97
- expect(event.attachments?.length).toBe(1);
98
- expect(event.attachments?.[0]?.kind).toBe('replay');
99
- });
100
-
101
- test('UTF-8 ndjson attaches replay kind (the rc.3 Android crash repro)', async () => {
102
- // This is the bug: pre-rc.4 `btoa(ndjson)` threw on the
103
- // Japanese characters below, the catch swallowed it, the
104
- // attachment silently never landed. Post-rc.4 the helper
105
- // handles UTF-8 and the attachment lands normally.
106
- const { calls } = mockUploadSuccess();
107
- const event = makeEvent();
108
- const ndjson =
109
- '{"ts":1700000000,"width":390,"height":844,"nodes":[' +
110
- '{"kind":"text","x":10,"y":20,"w":100,"h":20,"text":"設定"},' +
111
- '{"kind":"text","x":10,"y":50,"w":100,"h":20,"text":"ログアウト"}]}';
112
- await __captureAndAttachReplayForTests(event, ndjson);
113
- expect(calls.length).toBe(1);
114
- expect(event.attachments?.length).toBe(1);
115
- expect(event.attachments?.[0]?.kind).toBe('replay');
116
- });
117
-
118
- test('mixed em-dash / smart-quote / emoji attaches replay kind', async () => {
119
- const { calls } = mockUploadSuccess();
120
- const event = makeEvent();
121
- const ndjson =
122
- '{"ts":1,"width":390,"height":844,"nodes":[' +
123
- '{"kind":"text","x":0,"y":0,"w":50,"h":20,"text":"hello — world"},' +
124
- '{"kind":"text","x":0,"y":30,"w":50,"h":20,"text":"\\"quoted\\""},' +
125
- '{"kind":"text","x":0,"y":60,"w":50,"h":20,"text":"🎉"}]}';
126
- await __captureAndAttachReplayForTests(event, ndjson);
127
- expect(calls.length).toBe(1);
128
- expect(event.attachments?.length).toBe(1);
129
- expect(event.attachments?.[0]?.kind).toBe('replay');
130
- });
131
-
132
- test('upload returns null → no attachment, no throw', async () => {
133
- globalThis.fetch = (async () =>
134
- new Response('{"error":"tooLarge"}', { status: 413 })) as typeof fetch;
135
- const event = makeEvent();
136
- const ndjson = '{"ts":1,"nodes":[]}';
137
- await __captureAndAttachReplayForTests(event, ndjson);
138
- expect(event.attachments).toBeUndefined();
139
- });
140
-
141
- test('fetch throws (offline) → no attachment, no throw out of the function', async () => {
142
- globalThis.fetch = (async () => {
143
- throw new TypeError('Network request failed');
144
- }) as typeof fetch;
145
- const event = makeEvent();
146
- const ndjson = '{"ts":1,"nodes":[]}';
147
- await __captureAndAttachReplayForTests(event, ndjson);
148
- expect(event.attachments).toBeUndefined();
149
- });
150
- });
@@ -1,121 +0,0 @@
1
- /**
2
- * v2.3 W6.3 — Sentry-compat translation layer coverage.
3
- *
4
- * We exercise the pure-function pieces directly via the test hooks
5
- * exported from the compat module (parseDsn, mapCategoryToType,
6
- * mapLevel). The stateful pieces — init / captureException /
7
- * setUser dispatching to the native init + scope — are covered by
8
- * the upstream Sentori-native tests (sdk.test, before-send.test);
9
- * the compat layer only re-shapes the call arguments before
10
- * delegating, so testing the re-shape is enough.
11
- */
12
- import { describe, expect, test } from 'bun:test';
13
-
14
- import {
15
- __mapCategoryToTypeForTests,
16
- __mapLevelForTests,
17
- __parseDsnForTests,
18
- Severity,
19
- } from '../compat/sentry';
20
-
21
- describe('parseDsn', () => {
22
- test('extracts token + ingestUrl from a Sentori DSN', () => {
23
- const r = __parseDsnForTests(
24
- 'https://st_pk_testabcdef@ingest.sentori.golia.jp/1',
25
- );
26
- expect(r.token).toBe('st_pk_testabcdef');
27
- expect(r.ingestUrl).toBe('https://ingest.sentori.golia.jp');
28
- });
29
-
30
- test('honours custom port + host', () => {
31
- const r = __parseDsnForTests('https://st_pk_x@self-hosted.example.com:8443/42');
32
- expect(r.token).toBe('st_pk_x');
33
- expect(r.ingestUrl).toBe('https://self-hosted.example.com:8443');
34
- });
35
-
36
- test('rejects non-Sentori token prefix with a clear pointer', () => {
37
- expect(() =>
38
- __parseDsnForTests('https://abcd1234@sentry.io/12345'),
39
- ).toThrow(/st_pk_/);
40
- });
41
-
42
- test('rejects DSN without user-info (no token)', () => {
43
- expect(() => __parseDsnForTests('https://sentry.io/12345')).toThrow();
44
- });
45
-
46
- test('rejects malformed URL', () => {
47
- expect(() => __parseDsnForTests('not-a-url')).toThrow(/not a valid URL/);
48
- });
49
- });
50
-
51
- describe('mapCategoryToType', () => {
52
- test('user-interaction categories → user', () => {
53
- for (const c of ['auth', 'click', 'gesture', 'input', 'touch', 'ui']) {
54
- expect(__mapCategoryToTypeForTests(c)).toBe('user');
55
- }
56
- });
57
-
58
- test('network categories → net', () => {
59
- for (const c of ['fetch', 'http', 'xhr']) {
60
- expect(__mapCategoryToTypeForTests(c)).toBe('net');
61
- }
62
- });
63
-
64
- test('navigation categories → nav', () => {
65
- for (const c of ['nav', 'navigation', 'route']) {
66
- expect(__mapCategoryToTypeForTests(c)).toBe('nav');
67
- }
68
- });
69
-
70
- test('log-shaped categories → log', () => {
71
- for (const c of ['console', 'log', 'sentry']) {
72
- expect(__mapCategoryToTypeForTests(c)).toBe('log');
73
- }
74
- });
75
-
76
- test('unknown category → custom', () => {
77
- expect(__mapCategoryToTypeForTests('whatever')).toBe('custom');
78
- });
79
-
80
- test('undefined → undefined (pass-through to native default)', () => {
81
- expect(__mapCategoryToTypeForTests(undefined)).toBeUndefined();
82
- });
83
- });
84
-
85
- describe('mapLevel', () => {
86
- test("Sentry's 'critical' maps to Sentori's 'fatal'", () => {
87
- expect(__mapLevelForTests('critical')).toBe('fatal');
88
- });
89
-
90
- test("Sentry's 'log' maps to Sentori's 'info' (no separate Log level)", () => {
91
- expect(__mapLevelForTests('log')).toBe('info');
92
- });
93
-
94
- test('5-level syslog names pass through unchanged', () => {
95
- expect(__mapLevelForTests('fatal')).toBe('fatal');
96
- expect(__mapLevelForTests('error')).toBe('error');
97
- expect(__mapLevelForTests('warning')).toBe('warning');
98
- expect(__mapLevelForTests('info')).toBe('info');
99
- expect(__mapLevelForTests('debug')).toBe('debug');
100
- });
101
-
102
- test('undefined → undefined', () => {
103
- expect(__mapLevelForTests(undefined)).toBeUndefined();
104
- });
105
- });
106
-
107
- describe('Severity export', () => {
108
- test('Critical collapses onto fatal', () => {
109
- expect(Severity.Critical).toBe('fatal');
110
- });
111
- test('Log collapses onto info', () => {
112
- expect(Severity.Log).toBe('info');
113
- });
114
- test('standard levels are themselves', () => {
115
- expect(Severity.Fatal).toBe('fatal');
116
- expect(Severity.Error).toBe('error');
117
- expect(Severity.Warning).toBe('warning');
118
- expect(Severity.Info).toBe('info');
119
- expect(Severity.Debug).toBe('debug');
120
- });
121
- });