@switchlabs/verify-ai-react-native 2.4.9 → 2.4.11

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.
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useRef, useState, useCallback, useEffect } from 'react';
3
3
  import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, AppState, Platform, useWindowDimensions, } from 'react-native';
4
4
  import { CameraView, useCameraPermissions, } from 'expo-camera';
5
+ import { VerifyAIRequestError } from '../client';
5
6
  import { useTelemetry } from '../telemetry/TelemetryContext';
6
7
  /** Quality used when expo-image-manipulator is not available (lower = smaller). */
7
8
  const FALLBACK_QUALITY = 0.65;
@@ -87,6 +88,7 @@ export function VerifyAIScanner({ onCapture, onResult, onError, overlay, style,
87
88
  const [cameraReady, setCameraReady] = useState(false);
88
89
  const [cameraKey, setCameraKey] = useState(0);
89
90
  const cameraReadyRef = useRef(false);
91
+ const cameraEverReadyRef = useRef(false);
90
92
  const cameraInitFailedRef = useRef(false);
91
93
  const permissionDeniedTrackedRef = useRef(false);
92
94
  // Track dimensions for orientation detection and responsive layout
@@ -212,6 +214,7 @@ export function VerifyAIScanner({ onCapture, onResult, onError, overlay, style,
212
214
  const onCameraReady = useCallback(() => {
213
215
  setCameraReady(true);
214
216
  cameraReadyRef.current = true;
217
+ cameraEverReadyRef.current = true;
215
218
  cameraInitFailedRef.current = false;
216
219
  }, []);
217
220
  const onMountError = useCallback((event) => {
@@ -237,14 +240,20 @@ export function VerifyAIScanner({ onCapture, onResult, onError, overlay, style,
237
240
  return;
238
241
  const timer = setTimeout(() => {
239
242
  if (!cameraReadyRef.current && !cameraInitFailedRef.current) {
240
- telemetry?.track('camera_preview_timeout', {
241
- component: 'scanner',
242
- error: 'Camera did not initialize within 3 seconds remounting',
243
- });
244
- // Reset state and bump key to force a fresh CameraView mount
245
- setCameraReady(false);
246
- cameraReadyRef.current = false;
247
- setCameraKey((k) => k + 1);
243
+ // Only track + remount on first-ever mount. A rotation/app-resume
244
+ // triggered remount can legitimately take >3s without indicating a
245
+ // real failure, and firing the alert each time is noisy without
246
+ // surfacing new information. If the camera truly stays broken the
247
+ // user will see capture failures, which is a more meaningful signal.
248
+ if (!cameraEverReadyRef.current) {
249
+ telemetry?.track('camera_preview_timeout', {
250
+ component: 'scanner',
251
+ error: 'Camera did not initialize within 3 seconds — remounting',
252
+ });
253
+ setCameraReady(false);
254
+ cameraReadyRef.current = false;
255
+ setCameraKey((k) => k + 1);
256
+ }
248
257
  }
249
258
  }, 3000);
250
259
  return () => clearTimeout(timer);
@@ -408,12 +417,15 @@ export function VerifyAIScanner({ onCapture, onResult, onError, overlay, style,
408
417
  setLastError(error);
409
418
  setStatus('error');
410
419
  onError?.(error);
411
- // Track the error
412
- const isCaptureFail = error.message?.includes('capture') || error.message?.includes('photo');
413
- const isImageFail = error.message?.includes('manipulate') || error.message?.includes('image');
414
- telemetry?.track(isCaptureFail ? 'capture_failure'
415
- : isImageFail ? 'image_manipulation_failure'
416
- : 'unknown_error', { component: 'scanner', error });
420
+ // VerifyAIRequestError is already tracked by the client (auth_error,
421
+ // network_error, rate_limited, etc.). Skip here to avoid double-firing.
422
+ if (!(err instanceof VerifyAIRequestError)) {
423
+ const isCaptureFail = error.message?.includes('capture') || error.message?.includes('photo');
424
+ const isImageFail = error.message?.includes('manipulate') || error.message?.includes('image');
425
+ telemetry?.track(isCaptureFail ? 'capture_failure'
426
+ : isImageFail ? 'image_manipulation_failure'
427
+ : 'unknown_error', { component: 'scanner', error });
428
+ }
417
429
  // Reset after a brief pause
418
430
  setTimeout(() => setStatus('idle'), 2000);
419
431
  }
package/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "2.4.9";
1
+ export declare const SDK_VERSION = "2.4.11";
package/lib/version.js CHANGED
@@ -1 +1 @@
1
- export const SDK_VERSION = '2.4.9';
1
+ export const SDK_VERSION = '2.4.11';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@switchlabs/verify-ai-react-native",
3
- "version": "2.4.9",
3
+ "version": "2.4.11",
4
4
  "description": "React Native SDK for Verify AI - photo verification with AI vision processing",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -19,6 +19,7 @@ import type {
19
19
  ScannerStatus,
20
20
  ScannerOverlayConfig,
21
21
  } from '../types';
22
+ import { VerifyAIRequestError } from '../client';
22
23
  import { useTelemetry } from '../telemetry/TelemetryContext';
23
24
  import type { TelemetryReporter } from '../telemetry/TelemetryReporter';
24
25
 
@@ -152,6 +153,7 @@ export function VerifyAIScanner({
152
153
  const [cameraReady, setCameraReady] = useState(false);
153
154
  const [cameraKey, setCameraKey] = useState(0);
154
155
  const cameraReadyRef = useRef(false);
156
+ const cameraEverReadyRef = useRef(false);
155
157
  const cameraInitFailedRef = useRef(false);
156
158
  const permissionDeniedTrackedRef = useRef(false);
157
159
 
@@ -296,6 +298,7 @@ export function VerifyAIScanner({
296
298
  const onCameraReady = useCallback(() => {
297
299
  setCameraReady(true);
298
300
  cameraReadyRef.current = true;
301
+ cameraEverReadyRef.current = true;
299
302
  cameraInitFailedRef.current = false;
300
303
  }, []);
301
304
 
@@ -323,14 +326,20 @@ export function VerifyAIScanner({
323
326
 
324
327
  const timer = setTimeout(() => {
325
328
  if (!cameraReadyRef.current && !cameraInitFailedRef.current) {
326
- telemetry?.track('camera_preview_timeout', {
327
- component: 'scanner',
328
- error: 'Camera did not initialize within 3 seconds remounting',
329
- });
330
- // Reset state and bump key to force a fresh CameraView mount
331
- setCameraReady(false);
332
- cameraReadyRef.current = false;
333
- setCameraKey((k) => k + 1);
329
+ // Only track + remount on first-ever mount. A rotation/app-resume
330
+ // triggered remount can legitimately take >3s without indicating a
331
+ // real failure, and firing the alert each time is noisy without
332
+ // surfacing new information. If the camera truly stays broken the
333
+ // user will see capture failures, which is a more meaningful signal.
334
+ if (!cameraEverReadyRef.current) {
335
+ telemetry?.track('camera_preview_timeout', {
336
+ component: 'scanner',
337
+ error: 'Camera did not initialize within 3 seconds — remounting',
338
+ });
339
+ setCameraReady(false);
340
+ cameraReadyRef.current = false;
341
+ setCameraKey((k) => k + 1);
342
+ }
334
343
  }
335
344
  }, 3000);
336
345
 
@@ -516,15 +525,18 @@ export function VerifyAIScanner({
516
525
  setStatus('error');
517
526
  onError?.(error);
518
527
 
519
- // Track the error
520
- const isCaptureFail = error.message?.includes('capture') || error.message?.includes('photo');
521
- const isImageFail = error.message?.includes('manipulate') || error.message?.includes('image');
522
- telemetry?.track(
523
- isCaptureFail ? 'capture_failure'
524
- : isImageFail ? 'image_manipulation_failure'
525
- : 'unknown_error',
526
- { component: 'scanner', error },
527
- );
528
+ // VerifyAIRequestError is already tracked by the client (auth_error,
529
+ // network_error, rate_limited, etc.). Skip here to avoid double-firing.
530
+ if (!(err instanceof VerifyAIRequestError)) {
531
+ const isCaptureFail = error.message?.includes('capture') || error.message?.includes('photo');
532
+ const isImageFail = error.message?.includes('manipulate') || error.message?.includes('image');
533
+ telemetry?.track(
534
+ isCaptureFail ? 'capture_failure'
535
+ : isImageFail ? 'image_manipulation_failure'
536
+ : 'unknown_error',
537
+ { component: 'scanner', error },
538
+ );
539
+ }
528
540
 
529
541
  // Reset after a brief pause
530
542
  setTimeout(() => setStatus('idle'), 2000);
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const SDK_VERSION = '2.4.9';
1
+ export const SDK_VERSION = '2.4.11';