@cxpinsight/react-native 0.20.0 → 0.21.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.21.0
4
+
5
+ Requires `@cxpinsight/survey-spec@^0.11.0` (unchanged).
6
+
7
+ ### Added
8
+ - **App start and frame vitals on Android.** `APP_START_COLD` (process start → the first
9
+ screen's first frame, once per process), `APP_START_WARM` (activity re-created while the
10
+ process lived on), `APP_START_HOT` (back to the foreground) and, per screen visit,
11
+ `SLOW_FRAMES` / `FROZEN_FRAMES` (share of drawn frames over their deadline / over 700 ms,
12
+ Android vitals definitions), as `web_vitals` events like the rest. Android is also told
13
+ when the first screen is fully drawn (`reportFullyDrawn`), so the system's own
14
+ startup numbers (Play Console, Macrobenchmark) see it. Measured on an API 35 emulator
15
+ against Android's own numbers: cold start within 64 ms of "Fully drawn", hot start within
16
+ a frame of `am start -W`, slow frames 8.0 % vs `gfxinfo` 8.6 %.
17
+ Needs a native build (not Expo Go); visits under 30 frames report no frame share.
18
+ - iOS ships the same native module, switched off until it has been measured on iOS; iOS
19
+ keeps screen load, INP and JS stall from 0.20.0.
20
+
3
21
  ## 0.20.0
4
22
 
5
23
  Requires `@cxpinsight/survey-spec@^0.11.0`. Publish that first.
@@ -0,0 +1,170 @@
1
+ package com.cxpinsight.reactnative;
2
+
3
+ import android.app.Activity;
4
+ import android.app.Application;
5
+ import android.os.Build;
6
+ import android.os.Bundle;
7
+ import android.os.Handler;
8
+ import android.os.HandlerThread;
9
+ import android.os.Process;
10
+ import android.os.SystemClock;
11
+ import android.view.FrameMetrics;
12
+ import android.view.Window;
13
+
14
+ import androidx.annotation.NonNull;
15
+ import androidx.annotation.Nullable;
16
+
17
+ import com.facebook.react.bridge.Arguments;
18
+ import com.facebook.react.bridge.Promise;
19
+ import com.facebook.react.bridge.ReactApplicationContext;
20
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
21
+ import com.facebook.react.bridge.ReactMethod;
22
+ import com.facebook.react.bridge.WritableMap;
23
+
24
+ import java.lang.ref.WeakReference;
25
+
26
+ /**
27
+ * Mobile vitals that only native code can see — the Android half of ios/CXPVitals.m and the native
28
+ * half of src/core/vitals.ts.
29
+ *
30
+ * getLaunchInfo when this process started, when an activity was last created (a WARM start: the
31
+ * process lived on, the activity did not) and when the app last came to the
32
+ * foreground (a HOT start) — wall-clock ms, the clock JS's Date.now() reads.
33
+ * startFrameMonitor / getFrameStats
34
+ * frames DRAWN since the monitor started (FrameMetrics, the source Google's JankStats
35
+ * uses): total, slow (over the frame's deadline — the vsync interval) and frozen (over
36
+ * 700 ms), the Android vitals definitions. Cumulative; JS takes the difference per
37
+ * screen visit.
38
+ */
39
+ public class CXPVitalsModule extends ReactContextBaseJavaModule {
40
+ static final String NAME = "CXPVitals";
41
+
42
+ private static final long FROZEN_NS = 700_000_000L;
43
+
44
+ private static volatile double activityCreatedMs = 0;
45
+ private static volatile double foregroundMs = 0;
46
+ private static volatile boolean callbacksRegistered = false;
47
+ // A cold start happens once per process; a JS reload in the same process is not one.
48
+ private static volatile boolean launchReported = false;
49
+
50
+ private long total = 0, slow = 0, frozen = 0;
51
+ private boolean monitoring = false;
52
+ private WeakReference<Window> watched = new WeakReference<>(null);
53
+ private Window.OnFrameMetricsAvailableListener listener;
54
+ private HandlerThread metricsThread;
55
+ private Handler metricsHandler;
56
+
57
+ CXPVitalsModule(ReactApplicationContext context) {
58
+ super(context);
59
+ registerLifecycle(context);
60
+ }
61
+
62
+ @NonNull
63
+ @Override
64
+ public String getName() { return NAME; }
65
+
66
+ private static double wallFromElapsed(long elapsedMs) {
67
+ return System.currentTimeMillis() - (SystemClock.elapsedRealtime() - elapsedMs);
68
+ }
69
+
70
+ private void registerLifecycle(ReactApplicationContext context) {
71
+ if (callbacksRegistered) return;
72
+ if (!(context.getApplicationContext() instanceof Application)) return;
73
+ callbacksRegistered = true;
74
+ ((Application) context.getApplicationContext()).registerActivityLifecycleCallbacks(
75
+ new Application.ActivityLifecycleCallbacks() {
76
+ @Override public void onActivityCreated(@NonNull Activity a, @Nullable Bundle b) {
77
+ activityCreatedMs = System.currentTimeMillis();
78
+ }
79
+ @Override public void onActivityStarted(@NonNull Activity a) {
80
+ foregroundMs = System.currentTimeMillis();
81
+ if (monitoring) attach(a);
82
+ }
83
+ @Override public void onActivityResumed(@NonNull Activity a) { if (monitoring) attach(a); }
84
+ @Override public void onActivityPaused(@NonNull Activity a) {}
85
+ @Override public void onActivityStopped(@NonNull Activity a) {}
86
+ @Override public void onActivitySaveInstanceState(@NonNull Activity a, @NonNull Bundle b) {}
87
+ @Override public void onActivityDestroyed(@NonNull Activity a) {}
88
+ });
89
+ }
90
+
91
+ @ReactMethod
92
+ public void getLaunchInfo(Promise promise) {
93
+ WritableMap m = Arguments.createMap();
94
+ boolean first = !launchReported;
95
+ launchReported = true;
96
+ m.putBoolean("firstInProcess", first);
97
+ double processStart = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
98
+ ? wallFromElapsed(Process.getStartElapsedRealtime()) : 0;
99
+ m.putDouble("processStartMs", processStart);
100
+ m.putBoolean("prewarmed", false);
101
+ m.putDouble("finishedLaunchingMs", 0);
102
+ m.putDouble("foregroundMs", foregroundMs);
103
+ m.putDouble("activityCreatedMs", activityCreatedMs);
104
+ m.putDouble("nowMs", System.currentTimeMillis());
105
+ m.putString("frameSource", "frame_metrics");
106
+ promise.resolve(m);
107
+ }
108
+
109
+ @ReactMethod
110
+ public void startFrameMonitor() {
111
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return;
112
+ monitoring = true;
113
+ Activity a = getCurrentActivity();
114
+ if (a != null) a.runOnUiThread(() -> attach(a));
115
+ }
116
+
117
+ private synchronized void attach(Activity activity) {
118
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N || activity == null) return;
119
+ Window window = activity.getWindow();
120
+ if (window == null || window == watched.get()) return;
121
+ Window previous = watched.get();
122
+ if (previous != null && listener != null) {
123
+ try { previous.removeOnFrameMetricsAvailableListener(listener); } catch (Exception ignored) {}
124
+ }
125
+ if (metricsThread == null) {
126
+ metricsThread = new HandlerThread("cxp-frame-metrics");
127
+ metricsThread.start();
128
+ metricsHandler = new Handler(metricsThread.getLooper());
129
+ }
130
+ if (listener == null) {
131
+ listener = (w, metrics, dropped) -> {
132
+ long duration = metrics.getMetric(FrameMetrics.TOTAL_DURATION);
133
+ long deadline = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
134
+ ? metrics.getMetric(FrameMetrics.DEADLINE) : 16_666_667L;
135
+ synchronized (CXPVitalsModule.this) {
136
+ total += 1 + dropped;
137
+ if (duration > deadline) slow += 1;
138
+ if (duration > FROZEN_NS) frozen += 1;
139
+ }
140
+ };
141
+ }
142
+ try {
143
+ window.addOnFrameMetricsAvailableListener(listener, metricsHandler);
144
+ watched = new WeakReference<>(window);
145
+ } catch (Exception ignored) {}
146
+ }
147
+
148
+ /**
149
+ * The first screen's content is on the display: tell Android, so the system logs "Fully drawn"
150
+ * (Time to Full Display, measured by Android from the launch) — what Play Console's startup
151
+ * metrics and Macrobenchmark read. Once per process; Android ignores repeats.
152
+ */
153
+ @ReactMethod
154
+ public void reportFullyDrawn() {
155
+ Activity a = getCurrentActivity();
156
+ if (a == null) return;
157
+ a.runOnUiThread(() -> { try { a.reportFullyDrawn(); } catch (Exception ignored) {} });
158
+ }
159
+
160
+ @ReactMethod
161
+ public void getFrameStats(Promise promise) {
162
+ WritableMap m = Arguments.createMap();
163
+ synchronized (this) {
164
+ m.putDouble("total", total);
165
+ m.putDouble("slow", slow);
166
+ m.putDouble("frozen", frozen);
167
+ }
168
+ promise.resolve(m);
169
+ }
170
+ }
@@ -7,6 +7,7 @@ import com.facebook.react.bridge.NativeModule;
7
7
  import com.facebook.react.bridge.ReactApplicationContext;
8
8
  import com.facebook.react.uimanager.ViewManager;
9
9
 
10
+ import java.util.Arrays;
10
11
  import java.util.Collections;
11
12
  import java.util.List;
12
13
 
@@ -14,7 +15,7 @@ public class CXPinsightPackage implements ReactPackage {
14
15
  @NonNull
15
16
  @Override
16
17
  public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
17
- return Collections.<NativeModule>singletonList(new CXPScreenshotModule(reactContext));
18
+ return Arrays.<NativeModule>asList(new CXPScreenshotModule(reactContext), new CXPVitalsModule(reactContext));
18
19
  }
19
20
 
20
21
  @NonNull
@@ -0,0 +1,143 @@
1
+ // Mobile vitals that only native code can see — the native half of src/core/vitals.ts.
2
+ //
3
+ // getLaunchInfo when this process started (and whether iOS prewarmed it), when the app finished
4
+ // launching, and when it last came to the foreground — wall-clock ms, the clock
5
+ // JS's Date.now() reads, so JS can measure up to the first frame it sees.
6
+ // startFrameMonitor / getFrameStats
7
+ // frames the main thread delivered since the monitor started: total, slow (later
8
+ // than 1.5 refresh intervals — a missed deadline) and frozen (over 700 ms), the
9
+ // Android vitals definitions. Counts are cumulative; JS takes the difference per
10
+ // screen visit. Paused while the app is in the background.
11
+ //
12
+ // Prewarm: since iOS 15 the system may start an app's process before anyone opens it, so the process
13
+ // start can be minutes before the launch. Apple's advice is to measure such launches from when the
14
+ // app finishes launching instead; `prewarmed` says which one JS should use.
15
+
16
+ #import <React/RCTBridgeModule.h>
17
+ #import <UIKit/UIKit.h>
18
+ #import <QuartzCore/QuartzCore.h>
19
+ #include <sys/sysctl.h>
20
+ #include <unistd.h>
21
+
22
+ static double CXPNowMs(void) { return [[NSDate date] timeIntervalSince1970] * 1000.0; }
23
+
24
+ static double cxpProcessStartMs = 0;
25
+ static double cxpFinishedLaunchingMs = 0;
26
+ static double cxpForegroundMs = 0;
27
+ static BOOL cxpPrewarmed = NO;
28
+ // A cold start happens once per process; a JS reload in the same process is not one.
29
+ static BOOL cxpLaunchReported = NO;
30
+
31
+ static double CXPProcessStartMs(void)
32
+ {
33
+ struct kinfo_proc info;
34
+ size_t size = sizeof(info);
35
+ int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() };
36
+ if (sysctl(mib, 4, &info, &size, NULL, 0) != 0) return 0;
37
+ struct timeval t = info.kp_proc.p_starttime;
38
+ return t.tv_sec * 1000.0 + t.tv_usec / 1000.0;
39
+ }
40
+
41
+ // Runs before main() — so the launch notifications below are never missed. A C constructor rather
42
+ // than +load: RCT_EXPORT_MODULE defines +load on this class to register the module.
43
+ __attribute__((constructor)) static void CXPVitalsLaunchHooks(void)
44
+ {
45
+ cxpProcessStartMs = CXPProcessStartMs();
46
+ const char *prewarm = getenv("ActivePrewarm");
47
+ cxpPrewarmed = prewarm != NULL && strcmp(prewarm, "1") == 0;
48
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
49
+ [nc addObserverForName:UIApplicationDidFinishLaunchingNotification object:nil queue:nil
50
+ usingBlock:^(__unused NSNotification *n) { cxpFinishedLaunchingMs = CXPNowMs(); }];
51
+ [nc addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil
52
+ usingBlock:^(__unused NSNotification *n) { cxpForegroundMs = CXPNowMs(); }];
53
+ }
54
+
55
+ @interface CXPFrameMonitor : NSObject
56
+ @property (nonatomic, strong) CADisplayLink *link;
57
+ @property (nonatomic) CFTimeInterval last;
58
+ @property (nonatomic) long long total;
59
+ @property (nonatomic) long long slow;
60
+ @property (nonatomic) long long frozen;
61
+ @end
62
+
63
+ @implementation CXPFrameMonitor
64
+
65
+ - (void)start
66
+ {
67
+ if (self.link) return;
68
+ self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)];
69
+ [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
70
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
71
+ [nc addObserver:self selector:@selector(pause) name:UIApplicationDidEnterBackgroundNotification object:nil];
72
+ [nc addObserver:self selector:@selector(resume) name:UIApplicationDidBecomeActiveNotification object:nil];
73
+ }
74
+
75
+ - (void)pause { self.link.paused = YES; self.last = 0; }
76
+ - (void)resume { self.last = 0; self.link.paused = NO; }
77
+
78
+ - (void)tick:(CADisplayLink *)link
79
+ {
80
+ CFTimeInterval now = link.timestamp;
81
+ if (self.last > 0) {
82
+ CFTimeInterval expected = link.targetTimestamp - link.timestamp;
83
+ if (expected <= 0 || expected > 0.1) expected = 1.0 / 60.0;
84
+ CFTimeInterval dt = now - self.last;
85
+ self.total += 1;
86
+ if (dt > expected * 1.5) self.slow += 1;
87
+ if (dt > 0.7) self.frozen += 1;
88
+ }
89
+ self.last = now;
90
+ }
91
+
92
+ @end
93
+
94
+ @interface CXPVitals : NSObject <RCTBridgeModule>
95
+ @end
96
+
97
+ @implementation CXPVitals
98
+
99
+ RCT_EXPORT_MODULE(CXPVitals)
100
+
101
+ static CXPFrameMonitor *cxpMonitor = nil;
102
+
103
+
104
+ + (BOOL)requiresMainQueueSetup { return NO; }
105
+ - (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); }
106
+
107
+ RCT_EXPORT_METHOD(getLaunchInfo:(RCTPromiseResolveBlock)resolve
108
+ reject:(__unused RCTPromiseRejectBlock)reject)
109
+ {
110
+ BOOL first = !cxpLaunchReported;
111
+ cxpLaunchReported = YES;
112
+ resolve(@{
113
+ @"firstInProcess": @(first),
114
+ @"processStartMs": @(cxpProcessStartMs),
115
+ @"prewarmed": @(cxpPrewarmed),
116
+ @"finishedLaunchingMs": @(cxpFinishedLaunchingMs),
117
+ @"foregroundMs": @(cxpForegroundMs),
118
+ @"activityCreatedMs": @0,
119
+ @"nowMs": @(CXPNowMs()),
120
+ @"frameSource": @"display_link",
121
+ });
122
+ }
123
+
124
+ RCT_EXPORT_METHOD(startFrameMonitor)
125
+ {
126
+ if (!cxpMonitor) cxpMonitor = [CXPFrameMonitor new];
127
+ [cxpMonitor start];
128
+ }
129
+
130
+ // Android's "Fully drawn" has no iOS equivalent; kept so JS calls one API on both.
131
+ RCT_EXPORT_METHOD(reportFullyDrawn) {}
132
+
133
+ RCT_EXPORT_METHOD(getFrameStats:(RCTPromiseResolveBlock)resolve
134
+ reject:(__unused RCTPromiseRejectBlock)reject)
135
+ {
136
+ resolve(@{
137
+ @"total": @(cxpMonitor ? cxpMonitor.total : 0),
138
+ @"slow": @(cxpMonitor ? cxpMonitor.slow : 0),
139
+ @"frozen": @(cxpMonitor ? cxpMonitor.frozen : 0),
140
+ });
141
+ }
142
+
143
+ @end
@@ -1,14 +1,19 @@
1
- export type VitalName = 'SCREEN_LOAD' | 'INP' | 'JS_STALL';
1
+ export type VitalName = 'SCREEN_LOAD' | 'INP' | 'JS_STALL' | 'APP_START_COLD' | 'APP_START_WARM' | 'APP_START_HOT' | 'SLOW_FRAMES' | 'FROZEN_FRAMES';
2
2
  export interface VitalReport {
3
3
  name: VitalName;
4
4
  value: number;
5
5
  rating: 'good' | 'needs_improvement' | 'poor';
6
6
  screen: string;
7
7
  visitId: string;
8
- navigationType: 'screen' | 'resume';
8
+ navigationType: 'screen' | 'resume' | 'cold' | 'warm' | 'hot';
9
9
  attribution: Record<string, unknown>;
10
10
  }
11
11
  type Emit = (report: VitalReport) => void;
12
+ interface FrameStats {
13
+ total: number;
14
+ slow: number;
15
+ frozen: number;
16
+ }
12
17
  export declare function rate(name: VitalName, value: number): VitalReport['rating'];
13
18
  interface Visit {
14
19
  id: string;
@@ -19,6 +24,7 @@ interface Visit {
19
24
  maxStall: number;
20
25
  stallAt: number;
21
26
  startedAt: number;
27
+ frames0: FrameStats | null;
22
28
  }
23
29
  export declare function startVitals(cb: Emit): void;
24
30
  export declare function stopVitals(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"vitals.d.ts","sourceRoot":"","sources":["../../src/core/vitals.ts"],"names":[],"mappings":"AAoCA,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,KAAK,GAAG,UAAU,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,mBAAmB,GAAG,MAAM,CAAC;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;AAS1C,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAG1E;AA2BD,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AA+DD,wBAAgB,WAAW,CAAC,EAAE,EAAE,IAAI,GAAG,IAAI,CAS1C;AAED,wBAAgB,UAAU,IAAI,IAAI,CAUjC;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAiB7C;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAmBtF;AAED,iBAAiB;AACjB,wBAAgB,MAAM,IAAI;IAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAE9E"}
1
+ {"version":3,"file":"vitals.d.ts","sourceRoot":"","sources":["../../src/core/vitals.ts"],"names":[],"mappings":"AAoCA,MAAM,MAAM,SAAS,GACjB,aAAa,GAAG,KAAK,GAAG,UAAU,GAElC,gBAAgB,GAAG,gBAAgB,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe,CAAC;AAE5F,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,mBAAmB,GAAG,MAAM,CAAC;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IAC9D,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;AAqB1C,UAAU,UAAU;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAwBpE,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAG1E;AA2BD,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;CAC5B;AAsHD,wBAAgB,WAAW,CAAC,EAAE,EAAE,IAAI,GAAG,IAAI,CA0B1C;AAED,wBAAgB,UAAU,IAAI,IAAI,CAWjC;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAsB7C;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAmBtF;AAED,iBAAiB;AACjB,wBAAgB,MAAM,IAAI;IAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAE9E"}
@@ -46,7 +46,32 @@ const THRESHOLDS = {
46
46
  SCREEN_LOAD: [2500, 4000], // web.dev LCP
47
47
  INP: [200, 500], // web.dev INP
48
48
  JS_STALL: [249, 500], // Apple: ≥ 250 ms is a (micro) hang, > 500 ms a hang
49
+ // Android vitals — pass/fail, so good and poor meet: excessive at ≥ 5 s / 2 s / 1.5 s.
50
+ APP_START_COLD: [4999, 4999],
51
+ APP_START_WARM: [1999, 1999],
52
+ APP_START_HOT: [1499, 1499],
53
+ // Share of frames × 100 (10000 = all of them). Android vitals: > 50 % slow, > 0.1 % frozen.
54
+ SLOW_FRAMES: [5000, 5000],
55
+ FROZEN_FRAMES: [10, 10],
49
56
  };
57
+ // Platforms whose native vitals (app start, frames) have been measured against the platform's own
58
+ // numbers. iOS is off until ios/CXPVitals.m is checked against a real launch and a screen recording
59
+ // (it needs an Xcode 26 build); its JS vitals — screen load, INP, JS stall — are unaffected.
60
+ const NATIVE_VITALS_ON = ['android'];
61
+ function nativeVitals() {
62
+ try {
63
+ const m = react_native_1.TurboModuleRegistry?.get?.('CXPVitals')
64
+ ?? react_native_1.NativeModules?.CXPVitals;
65
+ return m || null;
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ // Frames in a visit below this are too few for a share to mean anything.
72
+ const MIN_FRAMES = 30;
73
+ // A launch longer than this is not a launch (a debugger pause, a JS reload in an old process).
74
+ const MAX_START_MS = 120000;
50
75
  function rate(name, value) {
51
76
  const [good, poor] = THRESHOLDS[name];
52
77
  return value <= good ? 'good' : value <= poor ? 'needs_improvement' : 'poor';
@@ -80,6 +105,14 @@ let stallTimer = null;
80
105
  let lastTick = 0;
81
106
  let appStateSub = null;
82
107
  let seq = 0;
108
+ let native = null;
109
+ let frameSource = '';
110
+ // Cold start: the launch's start (from native) and the first screen's first frame (from JS); reported
111
+ // once both are known, in whichever order they arrive.
112
+ let coldStartWall = 0;
113
+ let firstFrameWall = 0;
114
+ let coldReported = false;
115
+ let backgroundAtWall = 0;
83
116
  const newId = () => 'sv_' + Date.now().toString(36) + '_' + (seq++).toString(36) + Math.random().toString(36).slice(2, 6);
84
117
  // Reports made before startVitals (the opening screen's load) wait here for the SDK.
85
118
  let held = [];
@@ -108,14 +141,27 @@ function endVisit() {
108
141
  longest_stall_at_ms: Math.round(v.stallAt - v.startedAt),
109
142
  visit_duration_ms: Math.round(now() - v.startedAt),
110
143
  });
144
+ const f0 = v.frames0;
145
+ if (native && f0) {
146
+ native.getFrameStats().then((f) => {
147
+ const total = f.total - f0.total;
148
+ if (total < MIN_FRAMES)
149
+ return;
150
+ const attr = { frames: total, slow: f.slow - f0.slow, frozen: f.frozen - f0.frozen, frame_source: frameSource };
151
+ report('SLOW_FRAMES', ((f.slow - f0.slow) / total) * 10000, v, attr);
152
+ report('FROZEN_FRAMES', ((f.frozen - f0.frozen) / total) * 10000, v, attr);
153
+ }, () => { });
154
+ }
111
155
  }
112
156
  function beginVisit(screen, navigationType) {
113
157
  visit = {
114
158
  id: newId(), screen, navigationType, worstInp: 0, worstInpAttr: null,
115
- maxStall: 0, stallAt: 0, startedAt: now(),
159
+ maxStall: 0, stallAt: 0, startedAt: now(), frames0: null,
116
160
  };
117
161
  lastTick = now();
118
- return visit;
162
+ const v = visit;
163
+ native?.getFrameStats().then((f) => { v.frames0 = f; }, () => { });
164
+ return v;
119
165
  }
120
166
  function tick() {
121
167
  const t = now();
@@ -132,11 +178,50 @@ function onAppState(state) {
132
178
  lastTick = now();
133
179
  if (!visit && currentScreen)
134
180
  beginVisit(currentScreen, 'resume');
181
+ if (backgroundAtWall && native)
182
+ reportReturn(backgroundAtWall);
183
+ backgroundAtWall = 0;
135
184
  }
136
185
  else if (state === 'background' || state === 'inactive') {
186
+ if (state === 'background')
187
+ backgroundAtWall = Date.now();
137
188
  endVisit();
138
189
  }
139
190
  }
191
+ /**
192
+ * The app came back from the background: a WARM start when Android re-created its activity while
193
+ * the process lived on, a HOT start otherwise — from the native moment it started coming back to
194
+ * the first frame JS sees.
195
+ */
196
+ function reportReturn(sinceWall) {
197
+ const v = visit;
198
+ afterNextFrame(() => {
199
+ const endWall = Date.now();
200
+ native?.getLaunchInfo().then((info) => {
201
+ if (!v)
202
+ return;
203
+ const warm = info.activityCreatedMs > sinceWall;
204
+ const start = warm ? info.activityCreatedMs : info.foregroundMs;
205
+ if (!(start >= sinceWall) || endWall - start <= 0 || endWall - start > MAX_START_MS)
206
+ return;
207
+ v.navigationType = warm ? 'warm' : 'hot';
208
+ report(warm ? 'APP_START_WARM' : 'APP_START_HOT', endWall - start, v, {
209
+ start_source: warm ? 'activity_created' : 'foreground', frame_source: info.frameSource,
210
+ });
211
+ }, () => { });
212
+ });
213
+ }
214
+ function maybeReportCold() {
215
+ if (coldReported || !coldStartWall || !firstFrameWall)
216
+ return;
217
+ coldReported = true;
218
+ const value = firstFrameWall - coldStartWall;
219
+ const v = visit;
220
+ if (!v || value <= 0 || value > MAX_START_MS)
221
+ return;
222
+ report('APP_START_COLD', value, { ...v, navigationType: 'cold' }, { start_source: coldStartSource });
223
+ }
224
+ let coldStartSource = '';
140
225
  let currentScreen = null;
141
226
  function startVitals(cb) {
142
227
  emit = cb;
@@ -150,6 +235,29 @@ function startVitals(cb) {
150
235
  return;
151
236
  lastTick = now();
152
237
  stallTimer = setInterval(tick, STALL_TICK_MS);
238
+ native = NATIVE_VITALS_ON.includes(react_native_1.Platform.OS) ? nativeVitals() : null;
239
+ if (native) {
240
+ try {
241
+ native.startFrameMonitor();
242
+ }
243
+ catch { /* frames unavailable */ }
244
+ if (visit && !visit.frames0) {
245
+ const v = visit;
246
+ native.getFrameStats().then((f) => { v.frames0 = f; }, () => { });
247
+ }
248
+ native.getLaunchInfo().then((info) => {
249
+ frameSource = info.frameSource;
250
+ if (!info.firstInProcess) {
251
+ coldReported = true;
252
+ return;
253
+ }
254
+ // A prewarmed iOS process started before anyone opened the app; the launch is from when it
255
+ // finished launching (Apple's advice).
256
+ coldStartWall = info.prewarmed && info.finishedLaunchingMs ? info.finishedLaunchingMs : info.processStartMs;
257
+ coldStartSource = info.prewarmed ? 'finished_launching' : 'process_start';
258
+ maybeReportCold();
259
+ }, () => { });
260
+ }
153
261
  try {
154
262
  appStateSub = react_native_1.AppState.addEventListener('change', onAppState);
155
263
  }
@@ -166,6 +274,7 @@ function stopVitals() {
166
274
  currentScreen = null;
167
275
  lastInput = null;
168
276
  held = [];
277
+ native = null;
169
278
  }
170
279
  /**
171
280
  * A screen became current: the previous visit ends, this one starts, and its load is timed.
@@ -185,6 +294,14 @@ function onScreen(screen) {
185
294
  const byInput = lastInput && t - lastInput.at < NAV_INPUT_WINDOW_MS ? lastInput : null;
186
295
  const start = byInput ? byInput.at : t;
187
296
  afterNextFrame(() => {
297
+ if (!firstFrameWall) {
298
+ firstFrameWall = Date.now();
299
+ try {
300
+ native?.reportFullyDrawn?.();
301
+ }
302
+ catch { /* not on this platform */ }
303
+ maybeReportCold();
304
+ }
188
305
  report('SCREEN_LOAD', now() - start, v, {
189
306
  trigger: byInput ? byInput.kind : 'route_change',
190
307
  target_selector: byInput?.target ?? '',
@@ -1 +1 @@
1
- {"version":3,"file":"vitals.js","sourceRoot":"","sources":["../../src/core/vitals.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vitals.js","sourceRoot":"","sources":["../../src/core/vitals.ts"],"names":[],"mappings":";;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,+CAAsG;AAmBtG,qFAAqF;AACrF,MAAM,UAAU,GAAwC;IACtD,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAI,cAAc;IAC3C,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAc,cAAc;IAC3C,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAS,qDAAqD;IAClF,uFAAuF;IACvF,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;IAC5B,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;IAC3B,4FAA4F;IAC5F,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;IACzB,aAAa,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;CACxB,CAAC;AAcF,kGAAkG;AAClG,oGAAoG;AACpG,6FAA6F;AAC7F,MAAM,gBAAgB,GAAa,CAAC,SAAS,CAAC,CAAC;AAE/C,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,MAAM,CAAC,GAAI,kCAAmE,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC;eAC5F,4BAAyC,EAAE,SAAS,CAAC;QAC3D,OAAQ,CAAkB,IAAI,IAAI,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AAC1B,CAAC;AACD,yEAAyE;AACzE,MAAM,UAAU,GAAG,EAAE,CAAC;AACtB,+FAA+F;AAC/F,MAAM,YAAY,GAAG,MAAO,CAAC;AAE7B,cAAqB,IAAe,EAAE,KAAa;IACjD,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/E,CAAC;AAED,MAAM,GAAG,GAAG,GAAW,EAAE,CACvB,CAAC,OAAO,WAAW,KAAK,WAAW,IAAI,OAAO,WAAW,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;AAEjH,MAAM,cAAc,GAAG,CAAC,EAAc,EAAQ,EAAE;IAC9C,IAAI,CAAC;QACH,qBAAqB,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACrB,CAAC;AACH,CAAC,CAAC;AAEF,uEAAuE;AACvE,SAAS,UAAU,CAAC,eAAwB;IAC1C,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;IAChB,MAAM,EAAE,GAAG,OAAO,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC;IACvE,iGAAiG;IACjG,mFAAmF;IACnF,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI;QAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAC5F,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,aAAa,GAAG,EAAE,CAAC;AACzB,gEAAgE;AAChE,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAcjC,IAAI,IAAI,GAAgB,IAAI,CAAC;AAC7B,IAAI,KAAK,GAAiB,IAAI,CAAC;AAC/B,IAAI,SAAS,GAAiF,IAAI,CAAC;AACnG,IAAI,UAAU,GAA0C,IAAI,CAAC;AAC7D,IAAI,QAAQ,GAAG,CAAC,CAAC;AACjB,IAAI,WAAW,GAAkC,IAAI,CAAC;AACtD,IAAI,GAAG,GAAG,CAAC,CAAC;AACZ,IAAI,MAAM,GAAwB,IAAI,CAAC;AACvC,IAAI,WAAW,GAAG,EAAE,CAAC;AACrB,sGAAsG;AACtG,uDAAuD;AACvD,IAAI,aAAa,GAAG,CAAC,CAAC;AACtB,IAAI,cAAc,GAAG,CAAC,CAAC;AACvB,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,IAAI,gBAAgB,GAAG,CAAC,CAAC;AAEzB,MAAM,KAAK,GAAG,GAAW,EAAE,CACzB,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAExG,qFAAqF;AACrF,IAAI,IAAI,GAAkB,EAAE,CAAC;AAE7B,SAAS,MAAM,CAAC,IAAe,EAAE,KAAa,EAAE,CAAQ,EAAE,WAAoC;IAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/C,MAAM,CAAC,GAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,WAAW,EAAE,CAAC;IAC7J,IAAI,CAAC,IAAI,EAAE,CAAC;QAAC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IAC1D,IAAI,CAAC;QAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,wCAAwC,CAAC,CAAC;AACrE,CAAC;AAED,sEAAsE;AACtE,SAAS,QAAQ;IACf,MAAM,CAAC,GAAG,KAAK,CAAC;IAChB,KAAK,GAAG,IAAI,CAAC;IACb,IAAI,CAAC,CAAC;QAAE,OAAO;IACf,IAAI,CAAC,CAAC,YAAY;QAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;IACjE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE;QAChC,mBAAmB,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC;QACxD,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC;KACnD,CAAC,CAAC;IACH,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC;IACrB,IAAI,MAAM,IAAI,EAAE,EAAE,CAAC;QACjB,MAAM,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YAChC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;YACjC,IAAI,KAAK,GAAG,UAAU;gBAAE,OAAO;YAC/B,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;YAChH,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YACrE,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC7E,CAAC,EAAE,GAAG,EAAE,GAA4B,CAAC,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,MAAc,EAAE,cAA6C;IAC/E,KAAK,GAAG;QACN,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI;QACpE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI;KACzD,CAAC;IACF,QAAQ,GAAG,GAAG,EAAE,CAAC;IACjB,MAAM,CAAC,GAAG,KAAK,CAAC;IAChB,MAAM,EAAE,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAkB,CAAC,CAAC,CAAC;IAClF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,IAAI;IACX,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;IAChB,MAAM,GAAG,GAAG,CAAC,GAAG,QAAQ,GAAG,aAAa,CAAC,CAAG,mDAAmD;IAC/F,QAAQ,GAAG,CAAC,CAAC;IACb,IAAI,KAAK,IAAI,GAAG,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC;QAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;IAAC,CAAC;AACjF,CAAC;AAED,SAAS,UAAU,CAAC,KAAqB;IACvC,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,gGAAgG;QAChG,QAAQ,GAAG,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,KAAK,IAAI,aAAa;YAAE,UAAU,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QACjE,IAAI,gBAAgB,IAAI,MAAM;YAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC;QAC/D,gBAAgB,GAAG,CAAC,CAAC;IACvB,CAAC;SAAM,IAAI,KAAK,KAAK,YAAY,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QAC1D,IAAI,KAAK,KAAK,YAAY;YAAE,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1D,QAAQ,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,SAAiB;IACrC,MAAM,CAAC,GAAG,KAAK,CAAC;IAChB,cAAc,CAAC,GAAG,EAAE;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,EAAE,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACpC,IAAI,CAAC,CAAC;gBAAE,OAAO;YACf,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;YAChE,IAAI,CAAC,CAAC,KAAK,IAAI,SAAS,CAAC,IAAI,OAAO,GAAG,KAAK,IAAI,CAAC,IAAI,OAAO,GAAG,KAAK,GAAG,YAAY;gBAAE,OAAO;YAC5F,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe,EAAE,OAAO,GAAG,KAAK,EAAE,CAAC,EAAE;gBACpE,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,YAAY,EAAE,YAAY,EAAE,IAAI,CAAC,WAAW;aACvF,CAAC,CAAC;QACL,CAAC,EAAE,GAAG,EAAE,GAAwB,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,YAAY,IAAI,CAAC,aAAa,IAAI,CAAC,cAAc;QAAE,OAAO;IAC9D,YAAY,GAAG,IAAI,CAAC;IACpB,MAAM,KAAK,GAAG,cAAc,GAAG,aAAa,CAAC;IAC7C,MAAM,CAAC,GAAG,KAAK,CAAC;IAChB,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,YAAY;QAAE,OAAO;IACrD,MAAM,CAAC,gBAAgB,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC,CAAC;AACvG,CAAC;AACD,IAAI,eAAe,GAAG,EAAE,CAAC;AAEzB,IAAI,aAAa,GAAkB,IAAI,CAAC;AAExC,qBAA4B,EAAQ;IAClC,IAAI,GAAG,EAAE,CAAC;IACV,MAAM,OAAO,GAAG,IAAI,CAAC;IACrB,IAAI,GAAG,EAAE,CAAC;IACV,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC;QAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,IAAI,UAAU;QAAE,OAAO;IACvB,QAAQ,GAAG,GAAG,EAAE,CAAC;IACjB,UAAU,GAAG,WAAW,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAC9C,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,uBAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC;YAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,wBAAwB,CAAC,CAAC;QACtE,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,KAAK,CAAC;YAChB,MAAM,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAkB,CAAC,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACnC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;gBAAC,YAAY,GAAG,IAAI,CAAC;gBAAC,OAAO;YAAC,CAAC;YAC1D,2FAA2F;YAC3F,uCAAuC;YACvC,aAAa,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;YAC5G,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,eAAe,CAAC;YAC1E,eAAe,EAAE,CAAC;QACpB,CAAC,EAAE,GAAG,EAAE,GAAwB,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,CAAC;QAAC,WAAW,GAAG,uBAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;AACpG,CAAC;AAED;IACE,QAAQ,EAAE,CAAC;IACX,IAAI,UAAU;QAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAC1C,UAAU,GAAG,IAAI,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,GAAG,IAAI,CAAC;IACnB,IAAI,GAAG,IAAI,CAAC;IACZ,aAAa,GAAG,IAAI,CAAC;IACrB,SAAS,GAAG,IAAI,CAAC;IACjB,IAAI,GAAG,EAAE,CAAC;IACV,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,kBAAyB,MAAc;IACrC,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,aAAa;QAAE,OAAO;IAChD,aAAa,GAAG,MAAM,CAAC;IACvB,QAAQ,EAAE,CAAC;IACX,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvC,gGAAgG;IAChG,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;IAChB,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IACvF,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,cAAc,CAAC,GAAG,EAAE;QAClB,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC;gBAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,0BAA0B,CAAC,CAAC;YAC1E,eAAe,EAAE,CAAC;QACpB,CAAC;QACD,MAAM,CAAC,aAAa,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,EAAE;YACtC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc;YAChD,eAAe,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;YACtC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;YAC3C,2BAA2B,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SACtE,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,iBAAwB,IAAY,EAAE,eAAyB,EAAE,MAAe;IAC9E,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,MAAM,KAAK,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAC1C,SAAS,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,KAAK,CAAC;IAChB,cAAc,CAAC,GAAG,EAAE;QAClB,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK;YAAE,OAAO,CAAG,kEAAkE;QACnG,MAAM,QAAQ,GAAG,GAAG,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;QAClC,IAAI,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC;YAC7C,CAAC,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACtB,CAAC,CAAC,YAAY,GAAG;gBACf,UAAU,EAAE,IAAI;gBAChB,eAAe,EAAE,MAAM,IAAI,EAAE;gBAC7B,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC1D,WAAW,EAAE,KAAK,CAAC,KAAK;aACzB,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,iBAAiB;AACjB;IACE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;AAClC,CAAC"}
package/lib/version.d.ts CHANGED
@@ -5,5 +5,5 @@
5
5
  * missing screenshot or tap had to be diagnosed by asking the customer for their
6
6
  * package.json. test/sdkVersion.test.js fails when this and package.json differ.
7
7
  */
8
- export declare const SDK_VERSION = "0.20.0";
8
+ export declare const SDK_VERSION = "0.21.0";
9
9
  //# sourceMappingURL=version.d.ts.map
package/lib/version.js CHANGED
@@ -8,5 +8,5 @@ exports.SDK_VERSION = void 0;
8
8
  * missing screenshot or tap had to be diagnosed by asking the customer for their
9
9
  * package.json. test/sdkVersion.test.js fails when this and package.json differ.
10
10
  */
11
- exports.SDK_VERSION = '0.20.0';
11
+ exports.SDK_VERSION = '0.21.0';
12
12
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cxpinsight/react-native",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "CXPinsight React Native SDK — engagement tracking, native survey modals & visual setup mode",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",