@sanctum-key/react-native-sdk 1.0.39 → 1.0.40

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanctum-key/react-native-sdk",
3
- "version": "1.0.39",
3
+ "version": "1.0.40",
4
4
  "description": "Sanctum Key React Native SDK",
5
5
  "main": "build/src/index.js",
6
6
  "types": "build/src/index.d.ts",
@@ -1 +1 @@
1
- {"version":3,"file":"EnhancedCameraView.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,EAAU,QAAQ,EAAmC,MAAM,4BAA4B,CAAC;AAG/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,uBAAuB,EAAE,SAAS,CAAC;IACnF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC9E;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAqS5D,CAAC"}
1
+ {"version":3,"file":"EnhancedCameraView.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,EAAU,QAAQ,EAAmC,MAAM,4BAA4B,CAAC;AAG/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,uBAAuB,EAAE,SAAS,CAAC;IACnF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC9E;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAsS5D,CAAC"}
@@ -147,13 +147,13 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
147
147
  }, []); // <-- EMPTY ARRAY GUARANTEES STABILITY
148
148
  // 5. THE UNBREAKABLE INTERVAL
149
149
  useEffect(() => {
150
- if (!showCamera || isProcessing)
150
+ // If we shouldn't scan, or if web (web handles its own stream), abort.
151
+ // We intentionally don't require `isInitialized` here, the try/catch inside
152
+ // captureSilentPhoto handles unready cameras gracefully without breaking the loop.
153
+ if (!showCamera || isProcessing || Platform.OS === 'web')
151
154
  return;
152
- if (Platform.OS === 'web')
153
- return; // Let web handle its own interval logic
154
155
  let active = true;
155
156
  let id;
156
- // Slight delay to let the UI mount before hammering the camera hardware
157
157
  const timer = setTimeout(() => {
158
158
  if (!active)
159
159
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"EnhancedCameraView.js","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { View, StyleSheet, Text, Platform, AppState, AppStateStatus } from 'react-native';\nimport { Camera, CodeType, useCameraDevice, useCodeScanner } from 'react-native-vision-camera';\nimport VisionCameraModule from '../modules/camera/VisionCameraModule';\nimport { useI18n } from '../hooks/useI18n';\nimport { EnhancedCameraViewProps } from './OverLay/type';\nimport { WebBarcodeScanner } from './WebBarcodeScanner';\n\nexport interface ExtendedCameraProps extends Omit<EnhancedCameraViewProps, 'onError'> {\n isScanningBarcode?: boolean;\n onBarcodeScanned?: (data: string) => void;\n barcodeTypes?: CodeType[];\n onError?: (error: { message: string; name?: string; code?: string }) => void; \n}\n\nexport const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({\n showCamera,\n cameraType: initialCameraType = 'front',\n style,\n onError,\n onSilentCapture,\n silentCaptureResult,\n isProcessing = false,\n overlayComponent,\n isScanningBarcode = false,\n onBarcodeScanned,\n barcodeTypes\n}) => {\n const { t } = useI18n();\n const camera = useRef<Camera>(null);\n const webVideoRef = useRef<HTMLVideoElement | null>(null);\n \n const isCapturingRef = useRef(false);\n const isProcessingRef = useRef(isProcessing);\n // Ref-tracked isAnalyzing so captureSilentPhoto always reads the latest\n // value — the prop-based closure goes stale on iOS between renders.\n const isAnalyzingRef = useRef(silentCaptureResult?.isAnalyzing ?? false);\n \n const [cameraType] = useState<'front' | 'back'>(initialCameraType);\n const [hasPermission, setHasPermission] = useState<boolean | null>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n const [refreshCamera] = useState(false);\n \n const [isVideoFound, setIsVideoFound] = useState(false);\n const scannedBarcodeRef = useRef<string | null>(null);\n const containerRef = useRef<any>(null);\n\n const [appState, setAppState] = useState<AppStateStatus>(AppState.currentState);\n\n const device = useCameraDevice(cameraType);\n\n useEffect(() => { isProcessingRef.current = isProcessing; }, [isProcessing]);\n useEffect(() => { isAnalyzingRef.current = silentCaptureResult?.isAnalyzing ?? false; }, [silentCaptureResult?.isAnalyzing]);\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', nextAppState => {\n setAppState(nextAppState);\n });\n return () => {\n subscription.remove();\n };\n }, []);\n\n const checkPermissions = async () => {\n try {\n // getCameraPermissionStatus is synchronous — no await\n const cameraStatus = Camera.getCameraPermissionStatus();\n\n if (cameraStatus === 'granted') {\n setHasPermission(true);\n return;\n }\n\n if (cameraStatus === 'not-determined') {\n const result = await Camera.requestCameraPermission();\n if (result === 'granted') {\n setHasPermission(true);\n return;\n }\n }\n\n // 'denied' or 'restricted' — user must enable in Settings\n setHasPermission(false);\n onError?.({\n message: t('camera.permissionRequired'),\n name: 'NotAllowedError',\n code: 'permission-denied'\n });\n } catch (e: any) {\n setHasPermission(false);\n onError?.({\n message: e.message || t('camera.errorOccurred'),\n name: e.name || 'UnknownError',\n code: e.code || 'unknown'\n });\n }\n };\n\n useEffect(() => {\n if (showCamera) checkPermissions();\n }, [showCamera, refreshCamera]);\n\n const onInitialized = useCallback(() => setIsInitialized(true), []);\n\n const onCameraError = useCallback((error: any) => {\n console.warn(\"🎥 [Vision Camera Error Caught]:\", error);\n onError?.({ \n message: error.message || t('camera.errorOccurred'),\n code: error.code, // Contains specific RNVC codes (e.g., 'session/camera-in-use')\n name: error.name // Contains Web standard names (e.g., 'NotReadableError')\n });\n }, [onError, t]);\n\n const codeScanner = useCodeScanner({\n codeTypes: barcodeTypes || ['pdf-417', 'qr', 'code-128', 'code-39'],\n onCodeScanned: (codes) => {\n if (!isProcessingRef.current && isScanningBarcode) {\n for (const code of codes) {\n if (code.value && scannedBarcodeRef.current !== code.value) {\n scannedBarcodeRef.current = code.value;\n onBarcodeScanned?.(code.value);\n break;\n }\n }\n }\n }\n });\n\n // 1. ISOLATE THE CALLBACK: This breaks the dependency death spiral for all platforms.\n const onSilentCaptureRef = useRef(onSilentCapture);\n useEffect(() => {\n onSilentCaptureRef.current = onSilentCapture;\n }, [onSilentCapture]);\n\n // 2. THE CAPTURE FUNCTION: Zero dependencies. Immune to re-renders.\n const captureSilentPhoto = useCallback(async () => {\n // Web handles its own stream via WebBarcodeScanner; do not run native camera methods on web.\n if (Platform.OS === 'web') return; \n \n // We intentionally ignore `isInitialized`. If AVFoundation (iOS) or CameraX (Android) \n // aren't ready, the try/catch will handle it gracefully.\n if (!camera.current || isProcessingRef.current || isCapturingRef.current) return;\n if (isAnalyzingRef.current) return;\n\n try {\n isCapturingRef.current = true;\n \n const photo = await camera.current.takePhoto({\n enableShutterSound: false,\n flash: 'off',\n // iOS requires aggressive compression to prevent RAM crashes during interval captures\n ...(Platform.OS === 'ios' ? { photoCodec: 'jpeg', qualityPrioritization: 'speed' } : {})\n });\n\n // 3. CROSS-PLATFORM PATH NORMALIZATION\n let finalPath = photo.path;\n let captureSuccess = true;\n\n // 4. DEFENSIVE NATIVE MODULE EXECUTION\n if (VisionCameraModule && VisionCameraModule.processPhotoResult) {\n try {\n const moduleResult = await VisionCameraModule.processPhotoResult(photo);\n if (moduleResult) {\n captureSuccess = moduleResult.success ?? true;\n finalPath = moduleResult.path || photo.path;\n }\n } catch (nativeError) {\n console.warn(\"⚠️ Native module failed, falling back to raw device path\");\n }\n }\n\n onSilentCaptureRef.current?.({\n success: captureSuccess,\n path: finalPath,\n barcode: scannedBarcodeRef.current\n });\n \n } catch (error: any) {\n // 📸 Silent fail: The camera is busy, focusing, or warming up. Just wait for the next tick.\n console.log(`📸 Frame dropped (${Platform.OS}):`, error?.message);\n } finally {\n isCapturingRef.current = false;\n }\n }, []); // <-- EMPTY ARRAY GUARANTEES STABILITY\n\n // 5. THE UNBREAKABLE INTERVAL\n useEffect(() => {\n if (!showCamera || isProcessing) return;\n if (Platform.OS === 'web') return; // Let web handle its own interval logic\n\n let active = true;\n let id: ReturnType<typeof setInterval>;\n \n // Slight delay to let the UI mount before hammering the camera hardware\n const timer = setTimeout(() => {\n if (!active) return;\n const intervalDelay = isScanningBarcode ? 3000 : 1500;\n id = setInterval(captureSilentPhoto, intervalDelay);\n }, 1500);\n\n return () => {\n active = false;\n clearTimeout(timer);\n if (id) clearInterval(id);\n };\n }, [showCamera, isProcessing, isScanningBarcode, captureSilentPhoto]);\n\n\n useEffect(() => {\n if (!showCamera || !isInitialized || isProcessing) return;\n let active = true;\n let id: ReturnType<typeof setInterval>;\n \n const timer = setTimeout(() => {\n if (!active) return;\n const intervalDelay = isScanningBarcode ? 3000 : 1500;\n id = setInterval(captureSilentPhoto, intervalDelay);\n }, 1500);\n\n return () => {\n active = false;\n clearTimeout(timer);\n if (id) clearInterval(id);\n };\n }, [showCamera, isInitialized, isProcessing, captureSilentPhoto, isScanningBarcode]);\n\n useEffect(() => {\n if (Platform.OS !== 'web' || !showCamera) return;\n \n let timeoutId: ReturnType<typeof setTimeout>;\n \n const findVideo = () => {\n let video: HTMLVideoElement | null = null;\n if (containerRef.current?.querySelector) {\n video = containerRef.current.querySelector('video');\n }\n if (!video) {\n video = document.querySelector('video');\n }\n \n if (video) {\n webVideoRef.current = video;\n setIsVideoFound(true);\n } else {\n timeoutId = setTimeout(findVideo, 500);\n }\n };\n \n findVideo();\n return () => clearTimeout(timeoutId);\n }, [showCamera]);\n\n const handleWebBarcodeScanned = useCallback((value: string) => {\n if (!isProcessingRef.current && value !== scannedBarcodeRef.current) {\n scannedBarcodeRef.current = value;\n onBarcodeScanned?.(value);\n }\n }, [onBarcodeScanned]);\n\n if (hasPermission === null) return <View style={[styles.container, style]} />;\n \n if (hasPermission === false) return (\n <View style={[styles.container, style]}>\n <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>\n </View>\n );\n\n if (!device && showCamera) {\n // We delay the missing device error slightly to account for the camera mounting delay\n setTimeout(() => {\n if (!device) {\n onError?.({ \n message: \"No camera detected\", \n name: \"NotFoundError\", \n code: \"device/not-found\" \n });\n }\n }, 1000);\n return <View style={[styles.container, style]} />;\n }\n\n if (!device || !showCamera) return <View style={[styles.container, style]} />;\n\n return (\n <View ref={containerRef} style={[styles.container, style]}>\n <Camera\n ref={camera}\n style={StyleSheet.absoluteFill}\n device={device}\n resizeMode=\"cover\"\n isActive={showCamera && !isProcessing && appState === 'active'}\n photo={true}\n video={false}\n audio={false}\n onInitialized={onInitialized}\n onError={onCameraError}\n codeScanner={Platform.OS !== 'web' && isScanningBarcode ? codeScanner : undefined}\n />\n {Platform.OS === 'web' && isScanningBarcode && isVideoFound && (\n <WebBarcodeScanner\n videoRef={webVideoRef as React.RefObject<HTMLVideoElement>}\n onBarcodeScanned={handleWebBarcodeScanned}\n active={!isProcessingRef.current}\n />\n )}\n {overlayComponent}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: { flex: 1, backgroundColor: 'black' },\n permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },\n});"]}
1
+ {"version":3,"file":"EnhancedCameraView.js","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { View, StyleSheet, Text, Platform, AppState, AppStateStatus } from 'react-native';\nimport { Camera, CodeType, useCameraDevice, useCodeScanner } from 'react-native-vision-camera';\nimport VisionCameraModule from '../modules/camera/VisionCameraModule';\nimport { useI18n } from '../hooks/useI18n';\nimport { EnhancedCameraViewProps } from './OverLay/type';\nimport { WebBarcodeScanner } from './WebBarcodeScanner';\n\nexport interface ExtendedCameraProps extends Omit<EnhancedCameraViewProps, 'onError'> {\n isScanningBarcode?: boolean;\n onBarcodeScanned?: (data: string) => void;\n barcodeTypes?: CodeType[];\n onError?: (error: { message: string; name?: string; code?: string }) => void; \n}\n\nexport const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({\n showCamera,\n cameraType: initialCameraType = 'front',\n style,\n onError,\n onSilentCapture,\n silentCaptureResult,\n isProcessing = false,\n overlayComponent,\n isScanningBarcode = false,\n onBarcodeScanned,\n barcodeTypes\n}) => {\n const { t } = useI18n();\n const camera = useRef<Camera>(null);\n const webVideoRef = useRef<HTMLVideoElement | null>(null);\n \n const isCapturingRef = useRef(false);\n const isProcessingRef = useRef(isProcessing);\n // Ref-tracked isAnalyzing so captureSilentPhoto always reads the latest\n // value — the prop-based closure goes stale on iOS between renders.\n const isAnalyzingRef = useRef(silentCaptureResult?.isAnalyzing ?? false);\n \n const [cameraType] = useState<'front' | 'back'>(initialCameraType);\n const [hasPermission, setHasPermission] = useState<boolean | null>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n const [refreshCamera] = useState(false);\n \n const [isVideoFound, setIsVideoFound] = useState(false);\n const scannedBarcodeRef = useRef<string | null>(null);\n const containerRef = useRef<any>(null);\n\n const [appState, setAppState] = useState<AppStateStatus>(AppState.currentState);\n\n const device = useCameraDevice(cameraType);\n\n useEffect(() => { isProcessingRef.current = isProcessing; }, [isProcessing]);\n useEffect(() => { isAnalyzingRef.current = silentCaptureResult?.isAnalyzing ?? false; }, [silentCaptureResult?.isAnalyzing]);\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', nextAppState => {\n setAppState(nextAppState);\n });\n return () => {\n subscription.remove();\n };\n }, []);\n\n const checkPermissions = async () => {\n try {\n // getCameraPermissionStatus is synchronous — no await\n const cameraStatus = Camera.getCameraPermissionStatus();\n\n if (cameraStatus === 'granted') {\n setHasPermission(true);\n return;\n }\n\n if (cameraStatus === 'not-determined') {\n const result = await Camera.requestCameraPermission();\n if (result === 'granted') {\n setHasPermission(true);\n return;\n }\n }\n\n // 'denied' or 'restricted' — user must enable in Settings\n setHasPermission(false);\n onError?.({\n message: t('camera.permissionRequired'),\n name: 'NotAllowedError',\n code: 'permission-denied'\n });\n } catch (e: any) {\n setHasPermission(false);\n onError?.({\n message: e.message || t('camera.errorOccurred'),\n name: e.name || 'UnknownError',\n code: e.code || 'unknown'\n });\n }\n };\n\n useEffect(() => {\n if (showCamera) checkPermissions();\n }, [showCamera, refreshCamera]);\n\n const onInitialized = useCallback(() => setIsInitialized(true), []);\n\n const onCameraError = useCallback((error: any) => {\n console.warn(\"🎥 [Vision Camera Error Caught]:\", error);\n onError?.({ \n message: error.message || t('camera.errorOccurred'),\n code: error.code, // Contains specific RNVC codes (e.g., 'session/camera-in-use')\n name: error.name // Contains Web standard names (e.g., 'NotReadableError')\n });\n }, [onError, t]);\n\n const codeScanner = useCodeScanner({\n codeTypes: barcodeTypes || ['pdf-417', 'qr', 'code-128', 'code-39'],\n onCodeScanned: (codes) => {\n if (!isProcessingRef.current && isScanningBarcode) {\n for (const code of codes) {\n if (code.value && scannedBarcodeRef.current !== code.value) {\n scannedBarcodeRef.current = code.value;\n onBarcodeScanned?.(code.value);\n break;\n }\n }\n }\n }\n });\n\n // 1. ISOLATE THE CALLBACK: This breaks the dependency death spiral for all platforms.\n const onSilentCaptureRef = useRef(onSilentCapture);\n useEffect(() => {\n onSilentCaptureRef.current = onSilentCapture;\n }, [onSilentCapture]);\n\n // 2. THE CAPTURE FUNCTION: Zero dependencies. Immune to re-renders.\n const captureSilentPhoto = useCallback(async () => {\n // Web handles its own stream via WebBarcodeScanner; do not run native camera methods on web.\n if (Platform.OS === 'web') return; \n \n // We intentionally ignore `isInitialized`. If AVFoundation (iOS) or CameraX (Android) \n // aren't ready, the try/catch will handle it gracefully.\n if (!camera.current || isProcessingRef.current || isCapturingRef.current) return;\n if (isAnalyzingRef.current) return;\n\n try {\n isCapturingRef.current = true;\n \n const photo = await camera.current.takePhoto({\n enableShutterSound: false,\n flash: 'off',\n // iOS requires aggressive compression to prevent RAM crashes during interval captures\n ...(Platform.OS === 'ios' ? { photoCodec: 'jpeg', qualityPrioritization: 'speed' } : {})\n });\n\n // 3. CROSS-PLATFORM PATH NORMALIZATION\n let finalPath = photo.path;\n let captureSuccess = true;\n\n // 4. DEFENSIVE NATIVE MODULE EXECUTION\n if (VisionCameraModule && VisionCameraModule.processPhotoResult) {\n try {\n const moduleResult = await VisionCameraModule.processPhotoResult(photo);\n if (moduleResult) {\n captureSuccess = moduleResult.success ?? true;\n finalPath = moduleResult.path || photo.path;\n }\n } catch (nativeError) {\n console.warn(\"⚠️ Native module failed, falling back to raw device path\");\n }\n }\n\n onSilentCaptureRef.current?.({\n success: captureSuccess,\n path: finalPath,\n barcode: scannedBarcodeRef.current\n });\n \n } catch (error: any) {\n // 📸 Silent fail: The camera is busy, focusing, or warming up. Just wait for the next tick.\n console.log(`📸 Frame dropped (${Platform.OS}):`, error?.message);\n } finally {\n isCapturingRef.current = false;\n }\n }, []); // <-- EMPTY ARRAY GUARANTEES STABILITY\n\n // 5. THE UNBREAKABLE INTERVAL\n useEffect(() => {\n // If we shouldn't scan, or if web (web handles its own stream), abort.\n // We intentionally don't require `isInitialized` here, the try/catch inside \n // captureSilentPhoto handles unready cameras gracefully without breaking the loop.\n if (!showCamera || isProcessing || Platform.OS === 'web') return; \n\n let active = true;\n let id: ReturnType<typeof setInterval>;\n\n const timer = setTimeout(() => {\n if (!active) return;\n const intervalDelay = isScanningBarcode ? 3000 : 1500;\n id = setInterval(captureSilentPhoto, intervalDelay);\n }, 1500);\n\n return () => {\n active = false;\n clearTimeout(timer);\n if (id) clearInterval(id);\n };\n }, [showCamera, isProcessing, isScanningBarcode, captureSilentPhoto]);\n\n\n useEffect(() => {\n if (!showCamera || !isInitialized || isProcessing) return;\n let active = true;\n let id: ReturnType<typeof setInterval>;\n \n const timer = setTimeout(() => {\n if (!active) return;\n const intervalDelay = isScanningBarcode ? 3000 : 1500;\n id = setInterval(captureSilentPhoto, intervalDelay);\n }, 1500);\n\n return () => {\n active = false;\n clearTimeout(timer);\n if (id) clearInterval(id);\n };\n }, [showCamera, isInitialized, isProcessing, captureSilentPhoto, isScanningBarcode]);\n\n useEffect(() => {\n if (Platform.OS !== 'web' || !showCamera) return;\n \n let timeoutId: ReturnType<typeof setTimeout>;\n \n const findVideo = () => {\n let video: HTMLVideoElement | null = null;\n if (containerRef.current?.querySelector) {\n video = containerRef.current.querySelector('video');\n }\n if (!video) {\n video = document.querySelector('video');\n }\n \n if (video) {\n webVideoRef.current = video;\n setIsVideoFound(true);\n } else {\n timeoutId = setTimeout(findVideo, 500);\n }\n };\n \n findVideo();\n return () => clearTimeout(timeoutId);\n }, [showCamera]);\n\n const handleWebBarcodeScanned = useCallback((value: string) => {\n if (!isProcessingRef.current && value !== scannedBarcodeRef.current) {\n scannedBarcodeRef.current = value;\n onBarcodeScanned?.(value);\n }\n }, [onBarcodeScanned]);\n\n if (hasPermission === null) return <View style={[styles.container, style]} />;\n \n if (hasPermission === false) return (\n <View style={[styles.container, style]}>\n <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>\n </View>\n );\n\n if (!device && showCamera) {\n // We delay the missing device error slightly to account for the camera mounting delay\n setTimeout(() => {\n if (!device) {\n onError?.({ \n message: \"No camera detected\", \n name: \"NotFoundError\", \n code: \"device/not-found\" \n });\n }\n }, 1000);\n return <View style={[styles.container, style]} />;\n }\n\n if (!device || !showCamera) return <View style={[styles.container, style]} />;\n\n return (\n <View ref={containerRef} style={[styles.container, style]}>\n <Camera\n ref={camera}\n style={StyleSheet.absoluteFill}\n device={device}\n resizeMode=\"cover\"\n isActive={showCamera && !isProcessing && appState === 'active'}\n photo={true}\n video={false}\n audio={false}\n onInitialized={onInitialized}\n onError={onCameraError}\n codeScanner={Platform.OS !== 'web' && isScanningBarcode ? codeScanner : undefined}\n />\n {Platform.OS === 'web' && isScanningBarcode && isVideoFound && (\n <WebBarcodeScanner\n videoRef={webVideoRef as React.RefObject<HTMLVideoElement>}\n onBarcodeScanned={handleWebBarcodeScanned}\n active={!isProcessingRef.current}\n />\n )}\n {overlayComponent}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: { flex: 1, backgroundColor: 'black' },\n permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },\n});"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanctum-key/react-native-sdk",
3
- "version": "1.0.39",
3
+ "version": "1.0.40",
4
4
  "description": "Sanctum Key React Native SDK",
5
5
  "main": "build/src/index.js",
6
6
  "types": "build/src/index.d.ts",
@@ -185,13 +185,14 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
185
185
 
186
186
  // 5. THE UNBREAKABLE INTERVAL
187
187
  useEffect(() => {
188
- if (!showCamera || isProcessing) return;
189
- if (Platform.OS === 'web') return; // Let web handle its own interval logic
188
+ // If we shouldn't scan, or if web (web handles its own stream), abort.
189
+ // We intentionally don't require `isInitialized` here, the try/catch inside
190
+ // captureSilentPhoto handles unready cameras gracefully without breaking the loop.
191
+ if (!showCamera || isProcessing || Platform.OS === 'web') return;
190
192
 
191
193
  let active = true;
192
194
  let id: ReturnType<typeof setInterval>;
193
-
194
- // Slight delay to let the UI mount before hammering the camera hardware
195
+
195
196
  const timer = setTimeout(() => {
196
197
  if (!active) return;
197
198
  const intervalDelay = isScanningBarcode ? 3000 : 1500;