@goliapkg/sentori-react-native 0.8.5 → 0.9.1
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.
- package/android/src/main/java/com/sentori/SentoriCrashHandler.kt +11 -1
- package/android/src/main/java/com/sentori/SentoriMobileVitals.kt +100 -0
- package/android/src/main/java/com/sentori/SentoriModule.kt +23 -0
- package/android/src/main/java/com/sentori/SentoriNativeExceptionBridge.kt +75 -0
- package/android/src/main/java/com/sentori/SentoriNativeSignals.kt +32 -0
- package/ios/SentoriMobileVitals.swift +104 -0
- package/ios/SentoriModule.swift +23 -0
- package/ios/SentoriNativeExceptionBridge.swift +90 -0
- package/lib/capture.d.ts.map +1 -1
- package/lib/capture.js +21 -0
- package/lib/capture.js.map +1 -1
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -0
- package/lib/index.js.map +1 -1
- package/lib/init.d.ts.map +1 -1
- package/lib/init.js +21 -1
- package/lib/init.js.map +1 -1
- package/lib/mobile-vitals.d.ts +35 -0
- package/lib/mobile-vitals.d.ts.map +1 -0
- package/lib/mobile-vitals.js +89 -0
- package/lib/mobile-vitals.js.map +1 -0
- package/lib/native.d.ts +20 -0
- package/lib/native.d.ts.map +1 -1
- package/lib/native.js +48 -0
- package/lib/native.js.map +1 -1
- package/lib/navigation.d.ts.map +1 -1
- package/lib/navigation.js +14 -2
- package/lib/navigation.js.map +1 -1
- package/package.json +1 -1
- package/src/capture.ts +22 -0
- package/src/index.ts +12 -0
- package/src/init.ts +21 -1
- package/src/mobile-vitals.ts +114 -0
- package/src/native.ts +88 -0
- package/src/navigation.ts +16 -2
package/src/native.ts
CHANGED
|
@@ -11,6 +11,41 @@ type SentoriNativeModule = {
|
|
|
11
11
|
release: string
|
|
12
12
|
token: string
|
|
13
13
|
}) => void
|
|
14
|
+
/**
|
|
15
|
+
* v0.9.4 #1 — cold start measurement. iOS:
|
|
16
|
+
* `mach_absolute_time` from `applicationDidFinishLaunching` to first
|
|
17
|
+
* JS bridge ready. Android: `Process.getStartElapsedRealtime()`.
|
|
18
|
+
* Returns null when native side hasn't captured yet.
|
|
19
|
+
*/
|
|
20
|
+
getColdStartMs?: () => null | number
|
|
21
|
+
/**
|
|
22
|
+
* v0.9.4 #1 — call once at JS init() to finalize the cold-start
|
|
23
|
+
* measurement. iOS subtracts from the app-delegate anchor;
|
|
24
|
+
* Android uses Process.getStartElapsedRealtime() so the call is
|
|
25
|
+
* idempotent if missed.
|
|
26
|
+
*/
|
|
27
|
+
markJsBridgeReady?: () => void
|
|
28
|
+
/**
|
|
29
|
+
* v0.9.4 #1 — slow/frozen frame counters since the most recent
|
|
30
|
+
* navigation transition. Native side hooks `CADisplayLink` (iOS)
|
|
31
|
+
* / `Choreographer.FrameCallback` (Android). Frame > 16.67ms =
|
|
32
|
+
* slow; > 700ms = frozen.
|
|
33
|
+
*/
|
|
34
|
+
getFrameCounters?: () => null | { frozen: number; slow: number }
|
|
35
|
+
/** Reset counters on navigation transition (called by useTraceNavigation). */
|
|
36
|
+
resetFrameCounters?: () => void
|
|
37
|
+
/**
|
|
38
|
+
* v0.9.5 #8 — read the most-recent native exception recorded by
|
|
39
|
+
* `SentoriNativeExceptionBridge` within the last 1 s. Used by the
|
|
40
|
+
* JS-side capture path to attach native stack info to a JSError
|
|
41
|
+
* that RN wrapped from a swallowed NSException / Java Exception.
|
|
42
|
+
*/
|
|
43
|
+
getRecentNativeException?: () => null | {
|
|
44
|
+
ageMs: number
|
|
45
|
+
name: string
|
|
46
|
+
reason: string
|
|
47
|
+
stack: string[]
|
|
48
|
+
}
|
|
14
49
|
/**
|
|
15
50
|
* v0.7.3 — JS-triggered screenshot with consumer-supplied mask IDs.
|
|
16
51
|
* `maskedIds` are RN `nativeID` strings; native walks the view
|
|
@@ -127,6 +162,59 @@ export function stopAnrWatchdog(): void {
|
|
|
127
162
|
}
|
|
128
163
|
}
|
|
129
164
|
|
|
165
|
+
/** v0.9.4 #1 — finalize cold-start measurement. Idempotent. */
|
|
166
|
+
export function markNativeJsBridgeReady(): void {
|
|
167
|
+
try {
|
|
168
|
+
native()?.markJsBridgeReady?.()
|
|
169
|
+
} catch {
|
|
170
|
+
// ignore
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** v0.9.4 #1 — read cold start ms once. null when native unavailable. */
|
|
175
|
+
export function getNativeColdStartMs(): null | number {
|
|
176
|
+
try {
|
|
177
|
+
const v = native()?.getColdStartMs?.()
|
|
178
|
+
return typeof v === 'number' && Number.isFinite(v) ? v : null
|
|
179
|
+
} catch {
|
|
180
|
+
return null
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** v0.9.4 #1 — read slow/frozen frame counters since last reset. */
|
|
185
|
+
export function getNativeFrameCounters(): null | { frozen: number; slow: number } {
|
|
186
|
+
try {
|
|
187
|
+
return native()?.getFrameCounters?.() ?? null
|
|
188
|
+
} catch {
|
|
189
|
+
return null
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** v0.9.4 #1 — reset frame counters on navigation transition. */
|
|
194
|
+
export function resetNativeFrameCounters(): void {
|
|
195
|
+
try {
|
|
196
|
+
native()?.resetFrameCounters?.()
|
|
197
|
+
} catch {
|
|
198
|
+
// ignore
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** v0.9.5 #8 — fetch the most-recent native exception from
|
|
203
|
+
* SentoriNativeExceptionBridge (within last ~1 s). null if none or
|
|
204
|
+
* bridge not linked. */
|
|
205
|
+
export function getRecentNativeException(): null | {
|
|
206
|
+
ageMs: number
|
|
207
|
+
name: string
|
|
208
|
+
reason: string
|
|
209
|
+
stack: string[]
|
|
210
|
+
} {
|
|
211
|
+
try {
|
|
212
|
+
return native()?.getRecentNativeException?.() ?? null
|
|
213
|
+
} catch {
|
|
214
|
+
return null
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
130
218
|
/**
|
|
131
219
|
* v0.7.3 — drives the native screenshot path. JS side passes the
|
|
132
220
|
* current list of mask `nativeID`s (read from the consumer's
|
package/src/navigation.ts
CHANGED
|
@@ -24,6 +24,10 @@ import { useEffect, useRef } from 'react';
|
|
|
24
24
|
|
|
25
25
|
import { setActiveSpan, startSpan, type SpanHandle } from '@goliapkg/sentori-core';
|
|
26
26
|
|
|
27
|
+
import {
|
|
28
|
+
getNativeFrameCounters,
|
|
29
|
+
resetNativeFrameCounters,
|
|
30
|
+
} from './native';
|
|
27
31
|
import { captureStep } from './trail';
|
|
28
32
|
|
|
29
33
|
/** Minimal contract: anything with `addListener('state', cb)` and
|
|
@@ -101,11 +105,21 @@ export function useTraceNavigation(navigationRef: NavigationRefLike): void {
|
|
|
101
105
|
const enteredAt = lastRouteEnteredAtRef.current;
|
|
102
106
|
if (!span) return null;
|
|
103
107
|
const dwellMs = enteredAt !== null ? Math.max(0, Date.now() - enteredAt) : null;
|
|
108
|
+
// v0.9.4 #1 — drain native frame counters at screen-leave.
|
|
109
|
+
// Empty/null when native module not linked; tags omitted.
|
|
110
|
+
const fc = getNativeFrameCounters();
|
|
111
|
+
const finishTags: Record<string, string> = {};
|
|
112
|
+
if (dwellMs !== null) finishTags['nav.dwell_ms'] = String(dwellMs);
|
|
113
|
+
if (fc) {
|
|
114
|
+
finishTags['vital.slow_frames'] = String(fc.slow);
|
|
115
|
+
finishTags['vital.frozen_frames'] = String(fc.frozen);
|
|
116
|
+
}
|
|
104
117
|
span.finish({
|
|
105
118
|
status: 'ok',
|
|
106
|
-
|
|
107
|
-
tags: dwellMs !== null ? { 'nav.dwell_ms': String(dwellMs) } : undefined,
|
|
119
|
+
tags: Object.keys(finishTags).length > 0 ? finishTags : undefined,
|
|
108
120
|
});
|
|
121
|
+
// Reset counters for the next screen.
|
|
122
|
+
resetNativeFrameCounters();
|
|
109
123
|
return dwellMs;
|
|
110
124
|
};
|
|
111
125
|
|