@goliapkg/sentori-react-native 4.0.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 +3 -3
  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/init.js CHANGED
@@ -1,279 +1,106 @@
1
- import { setLogLevel } from '@goliapkg/sentori-core';
1
+ // sentori.init(config) — the single configuration entry point
2
+ // (design.md §4). Synchronous, never throws; a bad config degrades
3
+ // every verb to a no-op with one console.warn, never a crash
4
+ // (failure-isolation iron rule).
5
+ import { safeFn, setLogLevel } from '@goliapkg/sentori-core';
2
6
  import { setConfig } from './config';
7
+ import { registerEmitHook } from './emit-hooks';
3
8
  import { installGlobalHandler } from './handlers/global';
4
9
  import { installLifecycleHandler } from './handlers/lifecycle';
5
- import { installPromiseHandler } from './handlers/promise';
6
10
  import { installNetworkHandler } from './handlers/network';
7
- import { getBundleInfo } from './bundle-info';
8
- import { markLaunchCompleted, runLaunchCrashGuard, } from './launch-crash-guard';
9
- import { getInstallId } from './install-id';
10
- import { startMetricsTimer } from './metrics';
11
- import { emitColdStart, markColdStartT0, startRuntimeMetricsTimer, } from './runtime-metrics';
12
- import { startFpsInstrument } from './runtime-metrics-fps';
13
- import { startHeapInstrument } from './runtime-metrics-heap';
14
- import { startNetworkBytesInstrument } from './runtime-metrics-network';
15
- import { startTrackTimer } from './track';
16
- import { drainNativePending, markNativeJsBridgeReady, setNativeConfig } from './native';
17
- import { getColdStartMs } from './mobile-vitals';
18
- import { startHeartbeat } from './heartbeat';
19
- import { startSpan } from '@goliapkg/sentori-core';
20
- import { startControlChannel } from './control-channel';
11
+ import { installPromiseHandler } from './handlers/promise';
21
12
  import { startLongTaskMonitor } from './long-task-monitor';
22
- import { startNetworkTypeWatch } from './netinfo';
23
- import { startPreCrashSentinel } from './pre-crash-sentinel';
24
- import { startReplay } from './replay';
25
- import { startSampleProfiler } from './sample-profiler';
26
- import { startSession } from './session-tracker';
27
- import { drainOfflineQueue, enqueue, startTransport, uploadAttachment, } from './transport';
28
- const DEFAULT_INGEST_URL = 'https://ingest.sentori.golia.jp';
29
- export const init = (options) => {
30
- if (!options.token || !options.token.startsWith('st_pk_')) {
31
- throw new Error("Sentori: token is required and must start with 'st_pk_'");
32
- }
33
- if (!options.release) {
34
- throw new Error('Sentori: release is required');
13
+ import { checkColdStart } from './mobile-vitals';
14
+ import { markNativeJsBridgeReady, setNativeConfig } from './native';
15
+ import { shipNativePending } from './native-pending';
16
+ import { drainReplay, startReplay } from './replay';
17
+ import { drainOfflineQueue, startTransport, uploadAttachment } from './transport';
18
+ let _initialized = false;
19
+ export const init = safeFn('init', (config) => {
20
+ if (_initialized)
21
+ return;
22
+ if (!config || typeof config.token !== 'string' || config.token.length === 0) {
23
+ // eslint-disable-next-line no-console
24
+ console.warn('[sentori] init skipped: token missing — SDK is a no-op');
25
+ return;
35
26
  }
36
- // v2.3 — set log level FIRST so any startup-time logger calls
37
- // are gated correctly. Default 'warn' from logger.ts; an explicit
38
- // host setting overrides.
39
- setLogLevel(options.logLevel);
40
- const env = options.environment ??
41
- (typeof __DEV__ !== 'undefined' && __DEV__ ? 'dev' : 'prod');
42
- // v0.9.0 #3 — launch-crash guard. Fires *before* any other setup so
43
- // a known-bad bundle can roll back instead of running JS that's
44
- // about to die again. AsyncStorage-backed; if the host doesn't have
45
- // it the guard is a no-op.
46
- const lcg = options.capture?.launchCrashGuard;
47
- if (lcg?.enabled) {
48
- void runLaunchCrashGuard(lcg, options.release, getBundleInfo()?.id ?? null);
27
+ if (typeof config.ingestUrl !== 'string' || config.ingestUrl.length === 0) {
28
+ // eslint-disable-next-line no-console
29
+ console.warn('[sentori] init skipped: ingestUrl missing — SDK is a no-op');
30
+ return;
49
31
  }
32
+ _initialized = true;
50
33
  setConfig({
51
- token: options.token,
52
- release: options.release,
53
- environment: env,
54
- ingestUrl: options.ingestUrl ?? DEFAULT_INGEST_URL,
34
+ token: config.token,
35
+ ingestUrl: config.ingestUrl.replace(/\/+$/, ''),
36
+ release: config.release ?? '',
37
+ environment: config.environment ?? 'production',
55
38
  enabled: true,
56
- screenshotsEnabled: options.capture?.screenshot === true,
57
- // v2.3 — `sample` is the canonical name; `sampling` is the
58
- // back-compat alias. If both are supplied, `sample` wins.
59
- errorSampleRate: options.sample?.errors ?? options.sampling?.errors ?? null,
60
- traceSampleRate: options.sample?.traces ?? options.sampling?.traces ?? null,
61
- messageSampleRate: options.sample?.messages ?? options.sampling?.messages ?? null,
62
- sessionTrailEnabled: options.capture?.sessionTrail === true,
63
- // v2.0 W3 — when true, every `track()` also pushes a
64
- // `type: 'track'` breadcrumb so a subsequent captureException
65
- // carries the customer journey. Defaults false to preserve v1
66
- // breadcrumb shape on upgrade.
67
- trackAutoBreadcrumb: options.capture?.trackAutoBreadcrumb === true,
68
- // v2.3 — host-side beforeSend hook (sync). Stored on Config so
69
- // capture.ts can pull it without re-resolving the InitOptions.
70
- beforeSend: options.beforeSend,
39
+ detect: {
40
+ rageTap: config.detect?.rageTap ?? true,
41
+ longFreeze: config.detect?.longFreeze ?? true,
42
+ slowColdStart: config.detect?.slowColdStart ?? true,
43
+ slowApi: config.detect?.slowApi ?? false,
44
+ },
45
+ replaySeconds: config.replaySeconds ?? 30,
46
+ beforeSend: config.beforeSend,
71
47
  });
72
- // Tell the native crash handler about the config so the JSON it writes
73
- // on the next NSException / Java uncaught carries release + env.
48
+ setLogLevel(config.logLevel ?? 'warn');
49
+ // JS-side error capture + the signal-ring feeders.
50
+ installGlobalHandler();
51
+ installPromiseHandler();
52
+ installNetworkHandler();
53
+ installLifecycleHandler();
54
+ // Warn-scenario detectors (design.md §3 minimum set). rage_tap
55
+ // rides the RageTapCapture component; the rest start here.
56
+ if (config.detect?.longFreeze !== false)
57
+ startLongTaskMonitor();
58
+ // B-type replay: a rolling in-memory wireframe ring; an error/warn
59
+ // going out drains it into a replay attachment on that event.
60
+ const replaySeconds = config.replaySeconds ?? 30;
61
+ if (replaySeconds > 0) {
62
+ startReplay({ mode: 'wireframe' });
63
+ registerEmitHook((event) => {
64
+ if (event.kind !== 'error' && event.kind !== 'warn')
65
+ return;
66
+ if (!event.id)
67
+ return;
68
+ const lines = drainReplay();
69
+ if (!lines)
70
+ return;
71
+ const base64 = base64Encode(lines);
72
+ if (!base64)
73
+ return;
74
+ void uploadAttachment(event.id, 'replay', { base64, mediaType: 'application/x-sentori-replay' }, { source: 'js' });
75
+ });
76
+ }
77
+ // Native side: hand over release/environment for the crash-file
78
+ // writer, mark the bridge live, then drain crashes from previous
79
+ // launches. All fire-and-forget — init stays synchronous and fast
80
+ // (< 50 ms budget; the work below happens off the critical path).
74
81
  setNativeConfig({
75
- token: options.token,
76
- release: options.release,
77
- environment: env,
82
+ environment: config.environment ?? 'production',
83
+ release: config.release ?? '',
84
+ token: config.token,
78
85
  });
79
- // v0.9.4 #1 — finalize cold-start measurement. iOS uses the
80
- // delta from `applicationDidFinishLaunching` to this call;
81
- // Android uses Process.getStartElapsedRealtime() so the value is
82
- // computed at this point and cached.
83
86
  markNativeJsBridgeReady();
84
- // Emit a one-off cold-start span. Server aggregates these per
85
- // release for the Mobile Vitals dashboard. No-op when native
86
- // module isn't linked.
87
- const coldMs = getColdStartMs();
88
- if (coldMs !== null && coldMs > 0 && coldMs < 60_000) {
89
- const span = startSpan('sentori.cold_start', {
90
- name: 'cold-start',
91
- parent: null,
92
- startNowMs: Date.now() - coldMs,
93
- tags: { 'vital.kind': 'cold_start' },
94
- });
95
- span.finish({ status: 'ok' });
96
- }
97
87
  startTransport();
98
- // v1.1 +S7 升级 — control channel poll for live-debug flag.
99
- startControlChannel();
100
- // v0.8.0-c — start watching network class. No-op if NetInfo isn't
101
- // installed; events just won't carry `device.networkType` in that
102
- // case.
103
- startNetworkTypeWatch();
104
- // v0.8.3 — drain custom-metric ring every 30 s.
105
- startMetricsTimer();
106
- // v1.1 chunk B — drain `sentori.track()` ring every 30 s.
107
- startTrackTimer();
108
- // v2.1 W2 — runtime metrics auto-instrument. Defaults on; host
109
- // can opt out with `capture: { runtimeMetrics: false }`. The
110
- // ring + emit live in `@goliapkg/sentori-core`; we own the
111
- // 30 s flusher + the cold-start one-shot here. FPS / heap /
112
- // route-nav / network instruments ship in W2 part 3 (each
113
- // gated on its own per-tick perf budget CI test).
114
- if (options.capture?.runtimeMetrics !== false) {
115
- markColdStartT0();
116
- startRuntimeMetricsTimer();
117
- // Defer the emit one tick so React's first paint settles
118
- // before we stamp "cold-start ended". 0-delay setTimeout puts
119
- // the call after the current microtask queue drains.
120
- setTimeout(emitColdStart, 0);
121
- // FPS via rAF (per-tick budget < 0.5 ms — see
122
- // runtime-metrics-fps.ts header). Heap is a 30 s polling
123
- // tick; no-op when performance.memory isn't exposed (most
124
- // RN engines today; we ship the wiring anyway so the same
125
- // SDK works on web targets via @goliapkg/sentori-javascript).
126
- startFpsInstrument();
127
- startHeapInstrument();
128
- // Network bytes counters drain every 30 s. The counters
129
- // themselves are incremented inline by handlers/network.ts
130
- // on every fetch round-trip — see the recordNetworkBytes
131
- // call site there. No-op when `capture.network: false` is
132
- // set (no fetch patch → no counter increments).
133
- startNetworkBytesInstrument();
134
- // Route-nav dwell timing emits inline from `navigation.ts`'s
135
- // useTraceNavigation state listener — no extra start call
136
- // needed; the host already mounts that hook for tracing.
137
- }
138
- // v1.1 chunk S1 — warm the install-id cache. Fire-and-forget;
139
- // any event captured before the first resolve simply omits
140
- // `device.installId`. Subsequent captures pick it up via the
141
- // sync `peekInstallId()` read in collectDevice().
142
- void getInstallId();
143
- // v0.9.1 +S4 — pre-crash sentinel. Off by default; opt-in via
144
- // `capture.preCrashSentinel: true`.
145
- if (options.capture?.preCrashSentinel === true) {
146
- startPreCrashSentinel({
147
- enabled: true,
148
- channels: options.capture.sentinelChannels,
149
- });
150
- }
151
- // v0.9.6 #4 — long-task monitor. Off by default.
152
- const lt = options.capture?.longTaskMonitor;
153
- if (lt) {
154
- startLongTaskMonitor({
155
- enabled: true,
156
- thresholdMs: typeof lt === 'object' ? lt.thresholdMs : undefined,
157
- });
158
- }
159
- // v0.9.6 #2 — wireframe replay. Off by default.
160
- const rp = options.capture?.replay;
161
- if (rp === 'wireframe') {
162
- startReplay({ mode: 'wireframe' });
163
- }
164
- else if (rp && typeof rp === 'object' && rp.mode === 'wireframe') {
165
- startReplay({ hz: rp.hz, mode: 'wireframe' });
166
- }
167
- // v1.1 #4 升级 — JS sample profiler. Off by default.
168
- const sp = options.capture?.sampleProfiler;
169
- if (sp) {
170
- startSampleProfiler({
171
- enabled: true,
172
- flushMs: typeof sp === 'object' ? sp.flushMs : undefined,
173
- sampleMs: typeof sp === 'object' ? sp.sampleMs : undefined,
174
- });
88
+ checkColdStart(config.detect?.slowColdStart !== false);
89
+ void shipNativePending().catch(() => undefined);
90
+ void drainOfflineQueue();
91
+ });
92
+ /** RN's Hermes has no btoa in older releases; go through base64.ts. */
93
+ const base64Encode = (text) => {
94
+ try {
95
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
96
+ const { encodeBase64 } = require('./base64');
97
+ return encodeBase64(text);
175
98
  }
176
- const capture = options.capture ?? {};
177
- if (capture.globalErrors !== false)
178
- installGlobalHandler();
179
- if (capture.promiseRejections !== false)
180
- installPromiseHandler();
181
- if (capture.network !== false) {
182
- const netOpts = typeof capture.network === 'object' ? capture.network : undefined;
183
- installNetworkHandler({ graphql: netOpts?.graphql });
184
- }
185
- if (capture.sessions !== false) {
186
- // Open the cold-start session now (RN doesn't fire an AppState
187
- // `change` for the initial `active` state), then bind AppState so
188
- // background ends it and the next foreground opens a fresh one.
189
- startSession();
190
- installLifecycleHandler();
191
- }
192
- // Analytics v1 — live-presence heartbeat. Foreground 1/min by
193
- // default; pass `capture.heartbeat = false` to opt out, or
194
- // `{ intervalMs: 30_000 }` to override. The default budget is well
195
- // under the "几乎不能造成性能抖动" rule (CLAUDE.md).
196
- const heartbeatOpt = capture.heartbeat;
197
- if (heartbeatOpt !== false) {
198
- startHeartbeat(typeof heartbeatOpt === 'object' ? heartbeatOpt : {});
199
- }
200
- // Drain events persisted from previous session (best-effort):
201
- // - native crashes from <Documents>/sentori/pending/*.json
202
- // - JS transport offline queue from AsyncStorage
203
- drainNativePending()
204
- .then(async (items) => {
205
- for (const json of items) {
206
- try {
207
- const event = JSON.parse(json);
208
- // Phase 42 sub-E.05 / F.09: the native crash handler couldn't
209
- // upload attachments at crash time (the app was dying); it
210
- // base64-encoded them into `_pendingAttachments` instead.
211
- // On next launch we upload each before enqueueing the event,
212
- // so the dashboard sees the refs in `event.attachments[]`.
213
- if (event._pendingAttachments && event._pendingAttachments.length > 0) {
214
- for (const p of event._pendingAttachments) {
215
- const meta = await uploadAttachment(event.id, p.kind, { base64: p.base64, mediaType: p.mediaType }, { source: p.source });
216
- if (meta) {
217
- if (!event.attachments)
218
- event.attachments = [];
219
- event.attachments.push(meta);
220
- }
221
- }
222
- delete event._pendingAttachments;
223
- }
224
- enqueue(event);
225
- }
226
- catch {
227
- // skip malformed
228
- }
229
- }
230
- })
231
- .catch(() => { });
232
- drainOfflineQueue().catch(() => { });
233
- // v0.9.0 #3 — init reached the end without throwing. Schedule the
234
- // "launch completed" marker after one tick so any synchronous user
235
- // code right after `init()` gets to run first; we want the marker to
236
- // confirm the JS bridge stayed alive, not just that `init()` returned.
237
- if (lcg?.enabled) {
238
- setTimeout(() => {
239
- void markLaunchCompleted(getBundleInfo()?.id ?? null);
240
- }, 2_000);
241
- }
242
- // v2.3 — onReady callback. Fires after setConfig + native bind +
243
- // transport start are all settled. The drain-pending work is
244
- // still in flight (it's async) but the SDK is ready to accept
245
- // new captures. Host wires this to know the SDK is live without
246
- // scanning the console. Wrapped in try/catch — host callback
247
- // throwing must not propagate (NEVER rule).
248
- if (options.onReady) {
249
- const nativeMod = (() => {
250
- try {
251
- // eslint-disable-next-line @typescript-eslint/no-require-imports
252
- const { native } = require('./native');
253
- const n = native?.();
254
- return n ?? null;
255
- }
256
- catch {
257
- return null;
258
- }
259
- })();
260
- const info = {
261
- sdkVersion: SDK_VERSION,
262
- coldStartMs: coldMs ?? undefined,
263
- native: {
264
- bound: !!nativeMod,
265
- methods: nativeMod ? Object.keys(nativeMod).sort() : [],
266
- },
267
- };
268
- try {
269
- options.onReady(info);
270
- }
271
- catch {
272
- // Host's onReady threw. NEVER rule — swallow.
273
- }
99
+ catch {
100
+ return null;
274
101
  }
275
102
  };
276
- // Bumped on each SDK release; surfaced in onReady payload + the
277
- // future Sentry-compat layer's identification string.
278
- const SDK_VERSION = '2.3.0';
103
+ export const __resetForTests = () => {
104
+ _initialized = false;
105
+ };
279
106
  //# sourceMappingURL=init.js.map
package/lib/init.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,4 @@
1
- export type LongTaskMonitorOptions = {
2
- enabled: boolean;
3
- /** Threshold ms above which a tick lag becomes a longtask span.
4
- * Default 200ms. Lower → noisier. */
5
- thresholdMs?: number;
6
- };
7
- export declare function startLongTaskMonitor(opts: LongTaskMonitorOptions): void;
1
+ export declare function startLongTaskMonitor(): void;
8
2
  export declare function stopLongTaskMonitor(): void;
9
3
  /** Test-only. */
10
4
  export declare function __resetLongTaskMonitorForTests(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"long-task-monitor.d.ts","sourceRoot":"","sources":["../src/long-task-monitor.ts"],"names":[],"mappings":"AAqCA,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB;0CACsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAWvE;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AA8BD,iBAAiB;AACjB,wBAAgB,8BAA8B,IAAI,IAAI,CAKrD"}
1
+ {"version":3,"file":"long-task-monitor.d.ts","sourceRoot":"","sources":["../src/long-task-monitor.ts"],"names":[],"mappings":"AA8BA,wBAAgB,oBAAoB,IAAI,IAAI,CAO3C;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AA0BD,iBAAiB;AACjB,wBAAgB,8BAA8B,IAAI,IAAI,CAKrD"}
@@ -1,48 +1,35 @@
1
- // v0.9.6 #4 — JS thread long-task monitor.
1
+ // long_freeze — detected warn scenario (design.md §3, category B:
2
+ // 「app 卡住了 / 死了几秒」), JS-thread side.
2
3
  //
3
- // What it does: a setInterval(50ms) tick checks how much wall-clock
4
- // passed vs the requested interval. Excess = the JS thread was busy
5
- // doing something else for at least that much. When the excess
6
- // crosses 200ms (a "long task" per Chrome's PerformanceObserver
7
- // threshold) we emit a `sentori.longtask` span so the dashboard's
8
- // trace waterfall shows where the JS thread stalled.
4
+ // Mini-spec: a setInterval(50 ms) tick measures wall-clock drift.
5
+ // Drift ≤ 2 s ⇒ a `freeze` signal in the ring (context only —
6
+ // brief jank is not worth an event). Drift > 2 s ⇒ one `warn`
7
+ // event, scenario `long_freeze`, surface = current screen, with the
8
+ // blocked duration. Rate-limited to 6 events/minute so a freeze
9
+ // storm cannot flood ingest.
9
10
  //
10
- // What it does NOT do: capture the stack DURING the long task. JS
11
- // is single-threaded — by the time our tick runs, the busy code is
12
- // already gone. The span carries the duration + nearest navigation
13
- // context (via active span) so triage still has a route to blame.
14
- //
15
- // Why this and not a real Hermes sampler: Hermes ships a sampling
16
- // profiler but accessing it from JS requires RN-internal bridges
17
- // that vary per RN minor. We could swizzle / vendor headers but
18
- // that's an Insight-build-config burden. The long-task monitor
19
- // gets ~80% of the practical value (find slow renders, expensive
20
- // reducers, accidental sync work in render path) with zero native
21
- // code + zero RN-version sensitivity.
22
- //
23
- // Pairs naturally with +S4 (pre-crash sentinel, RAF frame budget,
24
- // fires at the slow-frame threshold) — long-task monitor fires
25
- // further down the slowness scale.
26
- import { startSpan } from '@goliapkg/sentori-core';
11
+ // What it cannot do: capture the stack DURING the block — JS is
12
+ // single-threaded; by the time our tick runs the busy code is gone.
13
+ // The native watchdogs (HangWatchdog / AnrWatchdog) cover the
14
+ // UI-thread side of the same scenario.
15
+ import { pushSignal } from '@goliapkg/sentori-core';
16
+ import { currentScreen } from './navigation';
17
+ import { warnDetected } from './verbs';
27
18
  const TICK_INTERVAL_MS = 50;
28
- const LONGTASK_THRESHOLD_MS = 200; // > 200ms blocking = a longtask
29
- const MAX_EMITS_PER_MIN = 60;
19
+ const SIGNAL_THRESHOLD_MS = 200; // ring entry: noticeable jank
20
+ const WARN_THRESHOLD_MS = 2_000; // warn event: a real freeze
21
+ const MAX_WARNS_PER_MIN = 6;
30
22
  let _timer = null;
31
23
  let _lastTick = 0;
32
- let _emitWindowStart = 0;
33
- let _emitsThisWindow = 0;
34
- export function startLongTaskMonitor(opts) {
24
+ let _warnWindowStart = 0;
25
+ let _warnsThisWindow = 0;
26
+ export function startLongTaskMonitor() {
35
27
  if (_timer !== null)
36
28
  return;
37
- if (!opts.enabled)
38
- return;
39
- const threshold = opts.thresholdMs ?? LONGTASK_THRESHOLD_MS;
40
29
  _lastTick = Date.now();
41
- _emitWindowStart = _lastTick;
42
- _emitsThisWindow = 0;
43
- _timer = setInterval(() => {
44
- tick(threshold);
45
- }, TICK_INTERVAL_MS);
30
+ _warnWindowStart = _lastTick;
31
+ _warnsThisWindow = 0;
32
+ _timer = setInterval(tick, TICK_INTERVAL_MS);
46
33
  _timer.unref?.();
47
34
  }
48
35
  export function stopLongTaskMonitor() {
@@ -51,38 +38,30 @@ export function stopLongTaskMonitor() {
51
38
  _timer = null;
52
39
  }
53
40
  }
54
- function tick(threshold) {
41
+ function tick() {
55
42
  const now = Date.now();
56
43
  const elapsed = now - _lastTick;
57
44
  _lastTick = now;
58
45
  const lag = elapsed - TICK_INTERVAL_MS;
59
- if (lag <= threshold)
46
+ if (lag <= SIGNAL_THRESHOLD_MS)
47
+ return;
48
+ pushSignal('freeze', { blockedMs: Math.round(lag) });
49
+ if (lag <= WARN_THRESHOLD_MS)
60
50
  return;
61
- // Rate-limit emits: at most MAX_EMITS_PER_MIN per minute so a
62
- // pathological scroll-block-storm doesn't generate 1000 spans.
63
- if (now - _emitWindowStart >= 60_000) {
64
- _emitWindowStart = now;
65
- _emitsThisWindow = 0;
51
+ if (now - _warnWindowStart >= 60_000) {
52
+ _warnWindowStart = now;
53
+ _warnsThisWindow = 0;
66
54
  }
67
- if (_emitsThisWindow >= MAX_EMITS_PER_MIN)
55
+ if (_warnsThisWindow >= MAX_WARNS_PER_MIN)
68
56
  return;
69
- _emitsThisWindow += 1;
70
- const span = startSpan('sentori.longtask', {
71
- name: 'js.longtask',
72
- startNowMs: now - lag,
73
- tags: {
74
- 'profile.kind': 'longtask',
75
- 'profile.duration_ms': String(Math.round(lag)),
76
- 'profile.tick_interval_ms': String(TICK_INTERVAL_MS),
77
- },
78
- });
79
- span.finish({ endNowMs: now, status: 'ok' });
57
+ _warnsThisWindow += 1;
58
+ warnDetected('long_freeze', { screen: currentScreen() }, { blockedMs: Math.round(lag), thread: 'js' });
80
59
  }
81
60
  /** Test-only. */
82
61
  export function __resetLongTaskMonitorForTests() {
83
62
  stopLongTaskMonitor();
84
63
  _lastTick = 0;
85
- _emitWindowStart = 0;
86
- _emitsThisWindow = 0;
64
+ _warnWindowStart = 0;
65
+ _warnsThisWindow = 0;
87
66
  }
88
67
  //# sourceMappingURL=long-task-monitor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"long-task-monitor.js","sourceRoot":"","sources":["../src/long-task-monitor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"long-task-monitor.js","sourceRoot":"","sources":["../src/long-task-monitor.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,qCAAqC;AACrC,EAAE;AACF,kEAAkE;AAClE,8DAA8D;AAC9D,8DAA8D;AAC9D,oEAAoE;AACpE,gEAAgE;AAChE,6BAA6B;AAC7B,EAAE;AACF,gEAAgE;AAChE,oEAAoE;AACpE,8DAA8D;AAC9D,uCAAuC;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC5B,MAAM,mBAAmB,GAAG,GAAG,CAAC,CAAC,8BAA8B;AAC/D,MAAM,iBAAiB,GAAG,KAAK,CAAC,CAAC,4BAA4B;AAC7D,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAE5B,IAAI,MAAM,GAA0C,IAAI,CAAC;AACzD,IAAI,SAAS,GAAG,CAAC,CAAC;AAClB,IAAI,gBAAgB,GAAG,CAAC,CAAC;AACzB,IAAI,gBAAgB,GAAG,CAAC,CAAC;AAEzB,MAAM,UAAU,oBAAoB;IAClC,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO;IAC5B,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,gBAAgB,GAAG,SAAS,CAAC;IAC7B,gBAAgB,GAAG,CAAC,CAAC;IACrB,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAC5C,MAA4C,CAAC,KAAK,EAAE,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,aAAa,CAAC,MAAM,CAAC,CAAC;QACtB,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,IAAI;IACX,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,GAAG,GAAG,SAAS,CAAC;IAChC,SAAS,GAAG,GAAG,CAAC;IAChB,MAAM,GAAG,GAAG,OAAO,GAAG,gBAAgB,CAAC;IACvC,IAAI,GAAG,IAAI,mBAAmB;QAAE,OAAO;IAEvC,UAAU,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrD,IAAI,GAAG,IAAI,iBAAiB;QAAE,OAAO;IAErC,IAAI,GAAG,GAAG,gBAAgB,IAAI,MAAM,EAAE,CAAC;QACrC,gBAAgB,GAAG,GAAG,CAAC;QACvB,gBAAgB,GAAG,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,gBAAgB,IAAI,iBAAiB;QAAE,OAAO;IAClD,gBAAgB,IAAI,CAAC,CAAC;IAEtB,YAAY,CACV,aAAa,EACb,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,EAC3B,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAC7C,CAAC;AACJ,CAAC;AAED,iBAAiB;AACjB,MAAM,UAAU,8BAA8B;IAC5C,mBAAmB,EAAE,CAAC;IACtB,SAAS,GAAG,CAAC,CAAC;IACd,gBAAgB,GAAG,CAAC,CAAC;IACrB,gBAAgB,GAAG,CAAC,CAAC;AACvB,CAAC"}
@@ -1,35 +1,7 @@
1
- /** Read the native-side cold start measurement once. Cached. Returns
2
- * null when the native module isn't linked (Expo Go / tests). */
1
+ /** Read the native-side cold start measurement once. Cached. */
3
2
  export declare function getColdStartMs(): null | number;
4
- /**
5
- * v0.9.4 #1 — Time-To-Full-Display marker. Host calls this at the
6
- * point the screen is functionally "ready" (data fetched, images
7
- * loaded, etc.) so the dashboard can show real perceived load time
8
- * vs auto-detected TTID.
9
- *
10
- * const h = sentori.markTimeToFullDisplay('Home');
11
- * // ...data fetched, images rendered...
12
- * h.end();
13
- *
14
- * If `.end()` is never called, the handle's span is finished as
15
- * `cancelled` at the next `markTimeToFullDisplay` call (one TTFD in
16
- * flight at a time is the typical case).
17
- */
18
- export type TimeToFullDisplayHandle = {
19
- end: (opts?: {
20
- status?: 'cancelled' | 'error' | 'ok';
21
- }) => void;
22
- cancel: () => void;
23
- };
24
- export declare function markTimeToFullDisplay(route: string): TimeToFullDisplayHandle;
25
- /** v0.9.4 #1 — read the per-screen slow/frozen frame counts since
26
- * the most recent navigation transition. Native module reads
27
- * CADisplayLink / Choreographer counters; returns null when not
28
- * linked. */
29
- export declare function getFrameCounters(): null | {
30
- slow: number;
31
- frozen: number;
32
- };
3
+ /** Called once from init(): signal always, warn when slow. */
4
+ export declare function checkColdStart(detectEnabled: boolean): void;
33
5
  /** Test-only. */
34
6
  export declare function __resetMobileVitalsForTests(): void;
35
7
  //# sourceMappingURL=mobile-vitals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mobile-vitals.d.ts","sourceRoot":"","sources":["../src/mobile-vitals.ts"],"names":[],"mappings":"AA6BA;kEACkE;AAClE,wBAAgB,cAAc,IAAI,IAAI,GAAG,MAAM,CAS9C;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAOF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,uBAAuB,CAqB5E;AAED;;;cAGc;AACd,wBAAgB,gBAAgB,IAAI,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAM1E;AAED,iBAAiB;AACjB,wBAAgB,2BAA2B,IAAI,IAAI,CAKlD"}
1
+ {"version":3,"file":"mobile-vitals.d.ts","sourceRoot":"","sources":["../src/mobile-vitals.ts"],"names":[],"mappings":"AAqBA,gEAAgE;AAChE,wBAAgB,cAAc,IAAI,IAAI,GAAG,MAAM,CAS9C;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,aAAa,EAAE,OAAO,GAAG,IAAI,CAO3D;AAED,iBAAiB;AACjB,wBAAgB,2BAA2B,IAAI,IAAI,CAGlD"}