@arfuhad/react-native-smart-camera 0.1.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 (95) hide show
  1. package/ARCHITECTURE.md +341 -0
  2. package/README.md +154 -0
  3. package/android/build.gradle +89 -0
  4. package/android/src/main/AndroidManifest.xml +2 -0
  5. package/android/src/main/java/expo/modules/smartcamera/ImageLoader.kt +106 -0
  6. package/android/src/main/java/expo/modules/smartcamera/MLKitFaceDetector.kt +273 -0
  7. package/android/src/main/java/expo/modules/smartcamera/SmartCameraModule.kt +205 -0
  8. package/android/src/main/java/expo/modules/smartcamera/SmartCameraView.kt +153 -0
  9. package/android/src/main/java/expo/modules/smartcamera/WebRTCFrameBridge.kt +184 -0
  10. package/app.plugin.js +17 -0
  11. package/build/SmartCamera.d.ts +17 -0
  12. package/build/SmartCamera.d.ts.map +1 -0
  13. package/build/SmartCamera.js +270 -0
  14. package/build/SmartCamera.js.map +1 -0
  15. package/build/SmartCameraModule.d.ts +112 -0
  16. package/build/SmartCameraModule.d.ts.map +1 -0
  17. package/build/SmartCameraModule.js +121 -0
  18. package/build/SmartCameraModule.js.map +1 -0
  19. package/build/SmartCameraView.d.ts +8 -0
  20. package/build/SmartCameraView.d.ts.map +1 -0
  21. package/build/SmartCameraView.js +7 -0
  22. package/build/SmartCameraView.js.map +1 -0
  23. package/build/detection/blinkProcessor.d.ts +23 -0
  24. package/build/detection/blinkProcessor.d.ts.map +1 -0
  25. package/build/detection/blinkProcessor.js +90 -0
  26. package/build/detection/blinkProcessor.js.map +1 -0
  27. package/build/detection/faceDetector.d.ts +16 -0
  28. package/build/detection/faceDetector.d.ts.map +1 -0
  29. package/build/detection/faceDetector.js +46 -0
  30. package/build/detection/faceDetector.js.map +1 -0
  31. package/build/detection/index.d.ts +4 -0
  32. package/build/detection/index.d.ts.map +1 -0
  33. package/build/detection/index.js +4 -0
  34. package/build/detection/index.js.map +1 -0
  35. package/build/detection/staticImageDetector.d.ts +25 -0
  36. package/build/detection/staticImageDetector.d.ts.map +1 -0
  37. package/build/detection/staticImageDetector.js +48 -0
  38. package/build/detection/staticImageDetector.js.map +1 -0
  39. package/build/hooks/index.d.ts +5 -0
  40. package/build/hooks/index.d.ts.map +1 -0
  41. package/build/hooks/index.js +5 -0
  42. package/build/hooks/index.js.map +1 -0
  43. package/build/hooks/useBlinkDetection.d.ts +39 -0
  44. package/build/hooks/useBlinkDetection.d.ts.map +1 -0
  45. package/build/hooks/useBlinkDetection.js +67 -0
  46. package/build/hooks/useBlinkDetection.js.map +1 -0
  47. package/build/hooks/useFaceDetection.d.ts +46 -0
  48. package/build/hooks/useFaceDetection.d.ts.map +1 -0
  49. package/build/hooks/useFaceDetection.js +80 -0
  50. package/build/hooks/useFaceDetection.js.map +1 -0
  51. package/build/hooks/useSmartCamera.d.ts +31 -0
  52. package/build/hooks/useSmartCamera.d.ts.map +1 -0
  53. package/build/hooks/useSmartCamera.js +75 -0
  54. package/build/hooks/useSmartCamera.js.map +1 -0
  55. package/build/hooks/useSmartCameraWebRTC.d.ts +58 -0
  56. package/build/hooks/useSmartCameraWebRTC.d.ts.map +1 -0
  57. package/build/hooks/useSmartCameraWebRTC.js +160 -0
  58. package/build/hooks/useSmartCameraWebRTC.js.map +1 -0
  59. package/build/index.d.ts +14 -0
  60. package/build/index.d.ts.map +1 -0
  61. package/build/index.js +20 -0
  62. package/build/index.js.map +1 -0
  63. package/build/types.d.ts +478 -0
  64. package/build/types.d.ts.map +1 -0
  65. package/build/types.js +2 -0
  66. package/build/types.js.map +1 -0
  67. package/build/utils/index.d.ts +98 -0
  68. package/build/utils/index.d.ts.map +1 -0
  69. package/build/utils/index.js +276 -0
  70. package/build/utils/index.js.map +1 -0
  71. package/build/webrtc/WebRTCBridge.d.ts +55 -0
  72. package/build/webrtc/WebRTCBridge.d.ts.map +1 -0
  73. package/build/webrtc/WebRTCBridge.js +113 -0
  74. package/build/webrtc/WebRTCBridge.js.map +1 -0
  75. package/build/webrtc/index.d.ts +3 -0
  76. package/build/webrtc/index.d.ts.map +1 -0
  77. package/build/webrtc/index.js +2 -0
  78. package/build/webrtc/index.js.map +1 -0
  79. package/build/webrtc/types.d.ts +64 -0
  80. package/build/webrtc/types.d.ts.map +1 -0
  81. package/build/webrtc/types.js +5 -0
  82. package/build/webrtc/types.js.map +1 -0
  83. package/expo-module.config.json +9 -0
  84. package/ios/MLKitFaceDetector.swift +310 -0
  85. package/ios/SmartCamera.podspec +33 -0
  86. package/ios/SmartCameraModule.swift +225 -0
  87. package/ios/SmartCameraView.swift +146 -0
  88. package/ios/WebRTCFrameBridge.swift +150 -0
  89. package/package.json +91 -0
  90. package/plugin/build/index.d.ts +28 -0
  91. package/plugin/build/index.js +33 -0
  92. package/plugin/build/withSmartCameraAndroid.d.ts +9 -0
  93. package/plugin/build/withSmartCameraAndroid.js +108 -0
  94. package/plugin/build/withSmartCameraIOS.d.ts +11 -0
  95. package/plugin/build/withSmartCameraIOS.js +92 -0
@@ -0,0 +1,46 @@
1
+ import type { Face, FaceDetectionOptions, UseFaceDetectionResult } from '../types';
2
+ /**
3
+ * Options for useFaceDetection hook
4
+ */
5
+ export interface UseFaceDetectionOptions extends FaceDetectionOptions {
6
+ /** Whether detection is enabled. Default: true */
7
+ enabled?: boolean;
8
+ /** Maximum number of faces to track. Default: 5 */
9
+ maxFaces?: number;
10
+ /** Callback when faces change */
11
+ onFacesChanged?: (faces: Face[]) => void;
12
+ }
13
+ /**
14
+ * Hook for managing face detection state
15
+ *
16
+ * Use this hook to get face detection results outside of the SmartCamera component.
17
+ *
18
+ * @param options - Face detection options
19
+ * @returns Face detection state
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * function FaceTracker() {
24
+ * const { faces, isDetecting } = useFaceDetection({
25
+ * performanceMode: 'fast',
26
+ * classificationMode: 'all',
27
+ * onFacesChanged: (faces) => {
28
+ * console.log('Detected faces:', faces.length);
29
+ * },
30
+ * });
31
+ *
32
+ * return (
33
+ * <View>
34
+ * <Text>Faces detected: {faces.length}</Text>
35
+ * {faces.map((face, i) => (
36
+ * <Text key={i}>
37
+ * Smiling: {(face.smilingProbability ?? 0) * 100}%
38
+ * </Text>
39
+ * ))}
40
+ * </View>
41
+ * );
42
+ * }
43
+ * ```
44
+ */
45
+ export declare function useFaceDetection(options?: UseFaceDetectionOptions): UseFaceDetectionResult;
46
+ //# sourceMappingURL=useFaceDetection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFaceDetection.d.ts","sourceRoot":"","sources":["../../src/hooks/useFaceDetection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,oBAAoB;IACnE,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,iCAAiC;IACjC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,sBAAsB,CAsD9F"}
@@ -0,0 +1,80 @@
1
+ import { useState, useCallback, useRef, useEffect } from 'react';
2
+ /**
3
+ * Hook for managing face detection state
4
+ *
5
+ * Use this hook to get face detection results outside of the SmartCamera component.
6
+ *
7
+ * @param options - Face detection options
8
+ * @returns Face detection state
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * function FaceTracker() {
13
+ * const { faces, isDetecting } = useFaceDetection({
14
+ * performanceMode: 'fast',
15
+ * classificationMode: 'all',
16
+ * onFacesChanged: (faces) => {
17
+ * console.log('Detected faces:', faces.length);
18
+ * },
19
+ * });
20
+ *
21
+ * return (
22
+ * <View>
23
+ * <Text>Faces detected: {faces.length}</Text>
24
+ * {faces.map((face, i) => (
25
+ * <Text key={i}>
26
+ * Smiling: {(face.smilingProbability ?? 0) * 100}%
27
+ * </Text>
28
+ * ))}
29
+ * </View>
30
+ * );
31
+ * }
32
+ * ```
33
+ */
34
+ export function useFaceDetection(options = {}) {
35
+ const { enabled = true, maxFaces = 5, onFacesChanged } = options;
36
+ const [faces, setFaces] = useState([]);
37
+ const [isDetecting, setIsDetecting] = useState(false);
38
+ const facesRef = useRef([]);
39
+ const callbackRef = useRef(onFacesChanged);
40
+ // Keep callback ref updated
41
+ useEffect(() => {
42
+ callbackRef.current = onFacesChanged;
43
+ }, [onFacesChanged]);
44
+ // Update faces (called from frame processor via native bridge)
45
+ const updateFaces = useCallback((newFaces) => {
46
+ // Limit number of faces
47
+ const limitedFaces = newFaces.slice(0, maxFaces);
48
+ // Only update if faces changed
49
+ const facesChanged = limitedFaces.length !== facesRef.current.length ||
50
+ limitedFaces.some((face, i) => face.trackingId !== facesRef.current[i]?.trackingId);
51
+ if (facesChanged) {
52
+ facesRef.current = limitedFaces;
53
+ setFaces(limitedFaces);
54
+ callbackRef.current?.(limitedFaces);
55
+ }
56
+ }, [maxFaces]);
57
+ // Detection state management
58
+ const startDetecting = useCallback(() => {
59
+ setIsDetecting(true);
60
+ }, []);
61
+ const stopDetecting = useCallback(() => {
62
+ setIsDetecting(false);
63
+ setFaces([]);
64
+ facesRef.current = [];
65
+ }, []);
66
+ // Effect to manage detection state based on enabled prop
67
+ useEffect(() => {
68
+ if (enabled) {
69
+ startDetecting();
70
+ }
71
+ else {
72
+ stopDetecting();
73
+ }
74
+ }, [enabled, startDetecting, stopDetecting]);
75
+ return {
76
+ faces,
77
+ isDetecting,
78
+ };
79
+ }
80
+ //# sourceMappingURL=useFaceDetection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFaceDetection.js","sourceRoot":"","sources":["../../src/hooks/useFaceDetection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAiBjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAmC,EAAE;IACpE,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,QAAQ,GAAG,CAAC,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAEjE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IAC/C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;IACpC,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;IAE3C,4BAA4B;IAC5B,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,OAAO,GAAG,cAAc,CAAC;IACvC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,+DAA+D;IAC/D,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,QAAgB,EAAE,EAAE;QACnD,wBAAwB;QACxB,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAEjD,+BAA+B;QAC/B,MAAM,YAAY,GAChB,YAAY,CAAC,MAAM,KAAK,QAAQ,CAAC,OAAO,CAAC,MAAM;YAC/C,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAEtF,IAAI,YAAY,EAAE,CAAC;YACjB,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC;YAChC,QAAQ,CAAC,YAAY,CAAC,CAAC;YACvB,WAAW,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,6BAA6B;IAC7B,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;QACtC,cAAc,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;QACrC,cAAc,CAAC,KAAK,CAAC,CAAC;QACtB,QAAQ,CAAC,EAAE,CAAC,CAAC;QACb,QAAQ,CAAC,OAAO,GAAG,EAAE,CAAC;IACxB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,yDAAyD;IACzD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,cAAc,EAAE,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,aAAa,EAAE,CAAC;QAClB,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC,CAAC;IAE7C,OAAO;QACL,KAAK;QACL,WAAW;KACZ,CAAC;AACJ,CAAC","sourcesContent":["import { useState, useCallback, useRef, useEffect } from 'react';\nimport type { Face, FaceDetectionOptions, UseFaceDetectionResult } from '../types';\n\n/**\n * Options for useFaceDetection hook\n */\nexport interface UseFaceDetectionOptions extends FaceDetectionOptions {\n /** Whether detection is enabled. Default: true */\n enabled?: boolean;\n \n /** Maximum number of faces to track. Default: 5 */\n maxFaces?: number;\n \n /** Callback when faces change */\n onFacesChanged?: (faces: Face[]) => void;\n}\n\n/**\n * Hook for managing face detection state\n * \n * Use this hook to get face detection results outside of the SmartCamera component.\n * \n * @param options - Face detection options\n * @returns Face detection state\n * \n * @example\n * ```tsx\n * function FaceTracker() {\n * const { faces, isDetecting } = useFaceDetection({\n * performanceMode: 'fast',\n * classificationMode: 'all',\n * onFacesChanged: (faces) => {\n * console.log('Detected faces:', faces.length);\n * },\n * });\n * \n * return (\n * <View>\n * <Text>Faces detected: {faces.length}</Text>\n * {faces.map((face, i) => (\n * <Text key={i}>\n * Smiling: {(face.smilingProbability ?? 0) * 100}%\n * </Text>\n * ))}\n * </View>\n * );\n * }\n * ```\n */\nexport function useFaceDetection(options: UseFaceDetectionOptions = {}): UseFaceDetectionResult {\n const { enabled = true, maxFaces = 5, onFacesChanged } = options;\n \n const [faces, setFaces] = useState<Face[]>([]);\n const [isDetecting, setIsDetecting] = useState(false);\n const facesRef = useRef<Face[]>([]);\n const callbackRef = useRef(onFacesChanged);\n\n // Keep callback ref updated\n useEffect(() => {\n callbackRef.current = onFacesChanged;\n }, [onFacesChanged]);\n\n // Update faces (called from frame processor via native bridge)\n const updateFaces = useCallback((newFaces: Face[]) => {\n // Limit number of faces\n const limitedFaces = newFaces.slice(0, maxFaces);\n \n // Only update if faces changed\n const facesChanged = \n limitedFaces.length !== facesRef.current.length ||\n limitedFaces.some((face, i) => face.trackingId !== facesRef.current[i]?.trackingId);\n \n if (facesChanged) {\n facesRef.current = limitedFaces;\n setFaces(limitedFaces);\n callbackRef.current?.(limitedFaces);\n }\n }, [maxFaces]);\n\n // Detection state management\n const startDetecting = useCallback(() => {\n setIsDetecting(true);\n }, []);\n\n const stopDetecting = useCallback(() => {\n setIsDetecting(false);\n setFaces([]);\n facesRef.current = [];\n }, []);\n\n // Effect to manage detection state based on enabled prop\n useEffect(() => {\n if (enabled) {\n startDetecting();\n } else {\n stopDetecting();\n }\n }, [enabled, startDetecting, stopDetecting]);\n\n return {\n faces,\n isDetecting,\n };\n}\n\n"]}
@@ -0,0 +1,31 @@
1
+ import type { UseSmartCameraResult, CameraDevice } from '../types';
2
+ /**
3
+ * Hook for managing SmartCamera state and permissions
4
+ *
5
+ * @returns Camera state, permission handlers, and device info
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * function CameraScreen() {
10
+ * const {
11
+ * hasPermission,
12
+ * requestPermission,
13
+ * device,
14
+ * switchCamera,
15
+ * currentCamera
16
+ * } = useSmartCamera();
17
+ *
18
+ * if (!hasPermission) {
19
+ * return <Button onPress={requestPermission} title="Grant Permission" />;
20
+ * }
21
+ *
22
+ * return <SmartCamera camera={currentCamera} />;
23
+ * }
24
+ * ```
25
+ */
26
+ export declare function useSmartCamera(): UseSmartCameraResult;
27
+ /**
28
+ * Get all available camera devices
29
+ */
30
+ export declare function getAvailableCameras(): Promise<CameraDevice[]>;
31
+ //# sourceMappingURL=useSmartCamera.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSmartCamera.d.ts","sourceRoot":"","sources":["../../src/hooks/useSmartCamera.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,oBAAoB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEjF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,CAqCrD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAWnE"}
@@ -0,0 +1,75 @@
1
+ import { useState, useCallback, useMemo } from 'react';
2
+ import { useCameraDevice, useCameraPermission, Camera } from 'react-native-vision-camera';
3
+ /**
4
+ * Hook for managing SmartCamera state and permissions
5
+ *
6
+ * @returns Camera state, permission handlers, and device info
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * function CameraScreen() {
11
+ * const {
12
+ * hasPermission,
13
+ * requestPermission,
14
+ * device,
15
+ * switchCamera,
16
+ * currentCamera
17
+ * } = useSmartCamera();
18
+ *
19
+ * if (!hasPermission) {
20
+ * return <Button onPress={requestPermission} title="Grant Permission" />;
21
+ * }
22
+ *
23
+ * return <SmartCamera camera={currentCamera} />;
24
+ * }
25
+ * ```
26
+ */
27
+ export function useSmartCamera() {
28
+ const [currentCamera, setCurrentCamera] = useState('front');
29
+ const { hasPermission, requestPermission: requestCameraPermission } = useCameraPermission();
30
+ const nativeDevice = useCameraDevice(currentCamera);
31
+ // Map native device to our CameraDevice type
32
+ const device = useMemo(() => {
33
+ if (!nativeDevice)
34
+ return undefined;
35
+ return {
36
+ id: nativeDevice.id,
37
+ name: nativeDevice.name,
38
+ position: nativeDevice.position === 'front' ? 'front' : 'back',
39
+ hasFlash: nativeDevice.hasFlash,
40
+ hasTorch: nativeDevice.hasTorch,
41
+ supportsLowLightBoost: nativeDevice.supportsLowLightBoost,
42
+ };
43
+ }, [nativeDevice]);
44
+ // Request camera permission
45
+ const requestPermission = useCallback(async () => {
46
+ const result = await requestCameraPermission();
47
+ return result;
48
+ }, [requestCameraPermission]);
49
+ // Switch between front and back camera
50
+ const switchCamera = useCallback(() => {
51
+ setCurrentCamera((prev) => (prev === 'front' ? 'back' : 'front'));
52
+ }, []);
53
+ return {
54
+ hasPermission,
55
+ requestPermission,
56
+ device,
57
+ switchCamera,
58
+ currentCamera,
59
+ };
60
+ }
61
+ /**
62
+ * Get all available camera devices
63
+ */
64
+ export async function getAvailableCameras() {
65
+ const devices = await Camera.getAvailableCameraDevices();
66
+ return devices.map((device) => ({
67
+ id: device.id,
68
+ name: device.name,
69
+ position: device.position === 'front' ? 'front' : 'back',
70
+ hasFlash: device.hasFlash,
71
+ hasTorch: device.hasTorch,
72
+ supportsLowLightBoost: device.supportsLowLightBoost,
73
+ }));
74
+ }
75
+ //# sourceMappingURL=useSmartCamera.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSmartCamera.js","sourceRoot":"","sources":["../../src/hooks/useSmartCamera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAG1F;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAe,OAAO,CAAC,CAAC;IAC1E,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,GAAG,mBAAmB,EAAE,CAAC;IAC5F,MAAM,YAAY,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;IAEpD,6CAA6C;IAC7C,MAAM,MAAM,GAA6B,OAAO,CAAC,GAAG,EAAE;QACpD,IAAI,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QAEpC,OAAO;YACL,EAAE,EAAE,YAAY,CAAC,EAAE;YACnB,IAAI,EAAE,YAAY,CAAC,IAAI;YACvB,QAAQ,EAAE,YAAY,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;YAC9D,QAAQ,EAAE,YAAY,CAAC,QAAQ;YAC/B,QAAQ,EAAE,YAAY,CAAC,QAAQ;YAC/B,qBAAqB,EAAE,YAAY,CAAC,qBAAqB;SAC1D,CAAC;IACJ,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,4BAA4B;IAC5B,MAAM,iBAAiB,GAAG,WAAW,CAAC,KAAK,IAAsB,EAAE;QACjE,MAAM,MAAM,GAAG,MAAM,uBAAuB,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAE9B,uCAAuC;IACvC,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE;QACpC,gBAAgB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,aAAa;QACb,iBAAiB;QACjB,MAAM;QACN,YAAY;QACZ,aAAa;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,yBAAyB,EAAE,CAAC;IAEzD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9B,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;QACxD,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;KACpD,CAAC,CAAC,CAAC;AACN,CAAC","sourcesContent":["import { useState, useCallback, useMemo } from 'react';\nimport { useCameraDevice, useCameraPermission, Camera } from 'react-native-vision-camera';\nimport type { CameraFacing, UseSmartCameraResult, CameraDevice } from '../types';\n\n/**\n * Hook for managing SmartCamera state and permissions\n * \n * @returns Camera state, permission handlers, and device info\n * \n * @example\n * ```tsx\n * function CameraScreen() {\n * const { \n * hasPermission, \n * requestPermission, \n * device, \n * switchCamera,\n * currentCamera \n * } = useSmartCamera();\n * \n * if (!hasPermission) {\n * return <Button onPress={requestPermission} title=\"Grant Permission\" />;\n * }\n * \n * return <SmartCamera camera={currentCamera} />;\n * }\n * ```\n */\nexport function useSmartCamera(): UseSmartCameraResult {\n const [currentCamera, setCurrentCamera] = useState<CameraFacing>('front');\n const { hasPermission, requestPermission: requestCameraPermission } = useCameraPermission();\n const nativeDevice = useCameraDevice(currentCamera);\n\n // Map native device to our CameraDevice type\n const device: CameraDevice | undefined = useMemo(() => {\n if (!nativeDevice) return undefined;\n\n return {\n id: nativeDevice.id,\n name: nativeDevice.name,\n position: nativeDevice.position === 'front' ? 'front' : 'back',\n hasFlash: nativeDevice.hasFlash,\n hasTorch: nativeDevice.hasTorch,\n supportsLowLightBoost: nativeDevice.supportsLowLightBoost,\n };\n }, [nativeDevice]);\n\n // Request camera permission\n const requestPermission = useCallback(async (): Promise<boolean> => {\n const result = await requestCameraPermission();\n return result;\n }, [requestCameraPermission]);\n\n // Switch between front and back camera\n const switchCamera = useCallback(() => {\n setCurrentCamera((prev) => (prev === 'front' ? 'back' : 'front'));\n }, []);\n\n return {\n hasPermission,\n requestPermission,\n device,\n switchCamera,\n currentCamera,\n };\n}\n\n/**\n * Get all available camera devices\n */\nexport async function getAvailableCameras(): Promise<CameraDevice[]> {\n const devices = await Camera.getAvailableCameraDevices();\n \n return devices.map((device) => ({\n id: device.id,\n name: device.name,\n position: device.position === 'front' ? 'front' : 'back',\n hasFlash: device.hasFlash,\n hasTorch: device.hasTorch,\n supportsLowLightBoost: device.supportsLowLightBoost,\n }));\n}\n\n"]}
@@ -0,0 +1,58 @@
1
+ import type { WebRTCConfig, UseSmartCameraWebRTCResult, CameraFacing } from '../types';
2
+ /**
3
+ * Options for useSmartCameraWebRTC hook
4
+ */
5
+ export interface UseSmartCameraWebRTCOptions extends Omit<WebRTCConfig, 'enabled'> {
6
+ /** Initial camera facing. Default: 'front' */
7
+ initialCamera?: CameraFacing;
8
+ /** Callback when streaming state changes */
9
+ onStreamingStateChange?: (isStreaming: boolean) => void;
10
+ /** Callback when an error occurs */
11
+ onError?: (error: Error) => void;
12
+ }
13
+ /**
14
+ * Hook for managing WebRTC streaming with SmartCamera
15
+ *
16
+ * This hook provides control over WebRTC video streaming, allowing you to
17
+ * start/stop streaming and switch cameras while streaming.
18
+ *
19
+ * @param options - WebRTC configuration options
20
+ * @returns WebRTC streaming controls and state
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * function VideoCall() {
25
+ * const peerConnection = useRef(new RTCPeerConnection(config)).current;
26
+ *
27
+ * const {
28
+ * videoTrack,
29
+ * isStreaming,
30
+ * startStreaming,
31
+ * stopStreaming,
32
+ * switchCamera,
33
+ * } = useSmartCameraWebRTC({
34
+ * peerConnection,
35
+ * mode: 'call',
36
+ * videoConstraints: {
37
+ * width: 1280,
38
+ * height: 720,
39
+ * frameRate: 30,
40
+ * },
41
+ * });
42
+ *
43
+ * return (
44
+ * <View>
45
+ * <SmartCamera
46
+ * webrtc={{ enabled: isStreaming, peerConnection, mode: 'call' }}
47
+ * />
48
+ * <Button
49
+ * onPress={isStreaming ? stopStreaming : startStreaming}
50
+ * title={isStreaming ? 'End Call' : 'Start Call'}
51
+ * />
52
+ * </View>
53
+ * );
54
+ * }
55
+ * ```
56
+ */
57
+ export declare function useSmartCameraWebRTC(options?: UseSmartCameraWebRTCOptions): UseSmartCameraWebRTCResult;
58
+ //# sourceMappingURL=useSmartCameraWebRTC.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSmartCameraWebRTC.d.ts","sourceRoot":"","sources":["../../src/hooks/useSmartCameraWebRTC.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAQvF;;GAEG;AACH,MAAM,WAAW,2BAA4B,SAAQ,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC;IAChF,8CAA8C;IAC9C,aAAa,CAAC,EAAE,YAAY,CAAC;IAE7B,4CAA4C;IAC5C,sBAAsB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;IAExD,oCAAoC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,2BAAgC,GACxC,0BAA0B,CAiI5B"}
@@ -0,0 +1,160 @@
1
+ import { useState, useCallback, useRef, useEffect } from 'react';
2
+ import { initializeWebRTC, startWebRTCStream, stopWebRTCStream, addWebRTCStateChangeListener, } from '../SmartCameraModule';
3
+ /**
4
+ * Hook for managing WebRTC streaming with SmartCamera
5
+ *
6
+ * This hook provides control over WebRTC video streaming, allowing you to
7
+ * start/stop streaming and switch cameras while streaming.
8
+ *
9
+ * @param options - WebRTC configuration options
10
+ * @returns WebRTC streaming controls and state
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * function VideoCall() {
15
+ * const peerConnection = useRef(new RTCPeerConnection(config)).current;
16
+ *
17
+ * const {
18
+ * videoTrack,
19
+ * isStreaming,
20
+ * startStreaming,
21
+ * stopStreaming,
22
+ * switchCamera,
23
+ * } = useSmartCameraWebRTC({
24
+ * peerConnection,
25
+ * mode: 'call',
26
+ * videoConstraints: {
27
+ * width: 1280,
28
+ * height: 720,
29
+ * frameRate: 30,
30
+ * },
31
+ * });
32
+ *
33
+ * return (
34
+ * <View>
35
+ * <SmartCamera
36
+ * webrtc={{ enabled: isStreaming, peerConnection, mode: 'call' }}
37
+ * />
38
+ * <Button
39
+ * onPress={isStreaming ? stopStreaming : startStreaming}
40
+ * title={isStreaming ? 'End Call' : 'Start Call'}
41
+ * />
42
+ * </View>
43
+ * );
44
+ * }
45
+ * ```
46
+ */
47
+ export function useSmartCameraWebRTC(options = {}) {
48
+ const { peerConnection, mode = 'call', videoConstraints = { width: 1280, height: 720, frameRate: 30 }, initialCamera = 'front', onStreamingStateChange, onError, } = options;
49
+ const [videoTrack, setVideoTrack] = useState(null);
50
+ const [isStreaming, setIsStreaming] = useState(false);
51
+ const [isInitialized, setIsInitialized] = useState(false);
52
+ const [currentCamera, setCurrentCamera] = useState(initialCamera);
53
+ const peerConnectionRef = useRef(peerConnection);
54
+ const callbacksRef = useRef({ onStreamingStateChange, onError });
55
+ const isMounted = useRef(true);
56
+ // Keep refs updated
57
+ useEffect(() => {
58
+ peerConnectionRef.current = peerConnection;
59
+ callbacksRef.current = { onStreamingStateChange, onError };
60
+ }, [peerConnection, onStreamingStateChange, onError]);
61
+ // Track mounted state
62
+ useEffect(() => {
63
+ isMounted.current = true;
64
+ return () => {
65
+ isMounted.current = false;
66
+ };
67
+ }, []);
68
+ // Subscribe to WebRTC state changes
69
+ useEffect(() => {
70
+ const subscription = addWebRTCStateChangeListener((state) => {
71
+ if (isMounted.current) {
72
+ setIsStreaming(state.isStreaming);
73
+ callbacksRef.current.onStreamingStateChange?.(state.isStreaming);
74
+ }
75
+ });
76
+ return () => {
77
+ subscription.remove();
78
+ };
79
+ }, []);
80
+ // Initialize WebRTC on first use
81
+ const ensureInitialized = useCallback(async () => {
82
+ if (isInitialized)
83
+ return;
84
+ try {
85
+ await initializeWebRTC();
86
+ if (isMounted.current) {
87
+ setIsInitialized(true);
88
+ }
89
+ }
90
+ catch (error) {
91
+ const err = error instanceof Error ? error : new Error(String(error));
92
+ callbacksRef.current.onError?.(err);
93
+ throw err;
94
+ }
95
+ }, [isInitialized]);
96
+ // Start streaming
97
+ const startStreaming = useCallback(async () => {
98
+ try {
99
+ // Ensure WebRTC is initialized
100
+ await ensureInitialized();
101
+ // Start the WebRTC stream with video constraints
102
+ await startWebRTCStream({
103
+ width: videoConstraints.width ?? 1280,
104
+ height: videoConstraints.height ?? 720,
105
+ frameRate: videoConstraints.frameRate ?? 30,
106
+ });
107
+ if (isMounted.current) {
108
+ setIsStreaming(true);
109
+ callbacksRef.current.onStreamingStateChange?.(true);
110
+ }
111
+ }
112
+ catch (error) {
113
+ const err = error instanceof Error ? error : new Error(String(error));
114
+ callbacksRef.current.onError?.(err);
115
+ throw err;
116
+ }
117
+ }, [videoConstraints, ensureInitialized]);
118
+ // Stop streaming
119
+ const stopStreaming = useCallback(() => {
120
+ try {
121
+ stopWebRTCStream();
122
+ if (isMounted.current) {
123
+ setVideoTrack(null);
124
+ setIsStreaming(false);
125
+ callbacksRef.current.onStreamingStateChange?.(false);
126
+ }
127
+ }
128
+ catch (error) {
129
+ const err = error instanceof Error ? error : new Error(String(error));
130
+ callbacksRef.current.onError?.(err);
131
+ }
132
+ }, []);
133
+ // Switch camera while streaming
134
+ const switchCamera = useCallback(() => {
135
+ setCurrentCamera((prev) => (prev === 'front' ? 'back' : 'front'));
136
+ // The camera switch will be handled by the SmartCamera component
137
+ // when the camera prop changes
138
+ }, []);
139
+ // Cleanup on unmount
140
+ useEffect(() => {
141
+ return () => {
142
+ if (isStreaming) {
143
+ try {
144
+ stopWebRTCStream();
145
+ }
146
+ catch {
147
+ // Ignore cleanup errors
148
+ }
149
+ }
150
+ };
151
+ }, [isStreaming]);
152
+ return {
153
+ videoTrack,
154
+ isStreaming,
155
+ startStreaming,
156
+ stopStreaming,
157
+ switchCamera,
158
+ };
159
+ }
160
+ //# sourceMappingURL=useSmartCameraWebRTC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSmartCameraWebRTC.js","sourceRoot":"","sources":["../../src/hooks/useSmartCameraWebRTC.ts"],"names":[],"mappings":"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","sourcesContent":["import { useState, useCallback, useRef, useEffect } from 'react';\nimport type { WebRTCConfig, UseSmartCameraWebRTCResult, CameraFacing } from '../types';\nimport {\n initializeWebRTC,\n startWebRTCStream,\n stopWebRTCStream,\n addWebRTCStateChangeListener,\n} from '../SmartCameraModule';\n\n/**\n * Options for useSmartCameraWebRTC hook\n */\nexport interface UseSmartCameraWebRTCOptions extends Omit<WebRTCConfig, 'enabled'> {\n /** Initial camera facing. Default: 'front' */\n initialCamera?: CameraFacing;\n \n /** Callback when streaming state changes */\n onStreamingStateChange?: (isStreaming: boolean) => void;\n \n /** Callback when an error occurs */\n onError?: (error: Error) => void;\n}\n\n/**\n * Hook for managing WebRTC streaming with SmartCamera\n * \n * This hook provides control over WebRTC video streaming, allowing you to\n * start/stop streaming and switch cameras while streaming.\n * \n * @param options - WebRTC configuration options\n * @returns WebRTC streaming controls and state\n * \n * @example\n * ```tsx\n * function VideoCall() {\n * const peerConnection = useRef(new RTCPeerConnection(config)).current;\n * \n * const {\n * videoTrack,\n * isStreaming,\n * startStreaming,\n * stopStreaming,\n * switchCamera,\n * } = useSmartCameraWebRTC({\n * peerConnection,\n * mode: 'call',\n * videoConstraints: {\n * width: 1280,\n * height: 720,\n * frameRate: 30,\n * },\n * });\n * \n * return (\n * <View>\n * <SmartCamera \n * webrtc={{ enabled: isStreaming, peerConnection, mode: 'call' }}\n * />\n * <Button \n * onPress={isStreaming ? stopStreaming : startStreaming} \n * title={isStreaming ? 'End Call' : 'Start Call'} \n * />\n * </View>\n * );\n * }\n * ```\n */\nexport function useSmartCameraWebRTC(\n options: UseSmartCameraWebRTCOptions = {}\n): UseSmartCameraWebRTCResult {\n const {\n peerConnection,\n mode = 'call',\n videoConstraints = { width: 1280, height: 720, frameRate: 30 },\n initialCamera = 'front',\n onStreamingStateChange,\n onError,\n } = options;\n\n const [videoTrack, setVideoTrack] = useState<MediaStreamTrack | null>(null);\n const [isStreaming, setIsStreaming] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [currentCamera, setCurrentCamera] = useState<CameraFacing>(initialCamera);\n \n const peerConnectionRef = useRef(peerConnection);\n const callbacksRef = useRef({ onStreamingStateChange, onError });\n const isMounted = useRef(true);\n\n // Keep refs updated\n useEffect(() => {\n peerConnectionRef.current = peerConnection;\n callbacksRef.current = { onStreamingStateChange, onError };\n }, [peerConnection, onStreamingStateChange, onError]);\n\n // Track mounted state\n useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n // Subscribe to WebRTC state changes\n useEffect(() => {\n const subscription = addWebRTCStateChangeListener((state) => {\n if (isMounted.current) {\n setIsStreaming(state.isStreaming);\n callbacksRef.current.onStreamingStateChange?.(state.isStreaming);\n }\n });\n\n return () => {\n subscription.remove();\n };\n }, []);\n\n // Initialize WebRTC on first use\n const ensureInitialized = useCallback(async (): Promise<void> => {\n if (isInitialized) return;\n\n try {\n await initializeWebRTC();\n if (isMounted.current) {\n setIsInitialized(true);\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n callbacksRef.current.onError?.(err);\n throw err;\n }\n }, [isInitialized]);\n\n // Start streaming\n const startStreaming = useCallback(async (): Promise<void> => {\n try {\n // Ensure WebRTC is initialized\n await ensureInitialized();\n\n // Start the WebRTC stream with video constraints\n await startWebRTCStream({\n width: videoConstraints.width ?? 1280,\n height: videoConstraints.height ?? 720,\n frameRate: videoConstraints.frameRate ?? 30,\n });\n\n if (isMounted.current) {\n setIsStreaming(true);\n callbacksRef.current.onStreamingStateChange?.(true);\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n callbacksRef.current.onError?.(err);\n throw err;\n }\n }, [videoConstraints, ensureInitialized]);\n\n // Stop streaming\n const stopStreaming = useCallback((): void => {\n try {\n stopWebRTCStream();\n if (isMounted.current) {\n setVideoTrack(null);\n setIsStreaming(false);\n callbacksRef.current.onStreamingStateChange?.(false);\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n callbacksRef.current.onError?.(err);\n }\n }, []);\n\n // Switch camera while streaming\n const switchCamera = useCallback((): void => {\n setCurrentCamera((prev) => (prev === 'front' ? 'back' : 'front'));\n // The camera switch will be handled by the SmartCamera component\n // when the camera prop changes\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (isStreaming) {\n try {\n stopWebRTCStream();\n } catch {\n // Ignore cleanup errors\n }\n }\n };\n }, [isStreaming]);\n\n return {\n videoTrack,\n isStreaming,\n startStreaming,\n stopStreaming,\n switchCamera,\n };\n}\n"]}
@@ -0,0 +1,14 @@
1
+ export { SmartCamera } from './SmartCamera';
2
+ export { default as SmartCameraModule } from './SmartCameraModule';
3
+ export { detectFacesInImage, updateFaceDetectionOptions, initializeWebRTC, startWebRTCStream, stopWebRTCStream, pushWebRTCFrame, isWebRTCStreaming, addFaceDetectionListener, addBlinkDetectionListener, addErrorListener, addWebRTCStateChangeListener, Constants, } from './SmartCameraModule';
4
+ export type { PerformanceMode, LandmarkMode, ContourMode, ClassificationMode, CameraFacing, FaceDetectionOptions, FrameProcessorOptions, StaticImageOptions, FaceDetectionConfig, Point, Bounds, FaceLandmarks, ContourType, FaceContours, Face, BlinkEvent, WebRTCMode, VideoConstraints, WebRTCConfig, SmartCameraProps, SmartCameraErrorCode, SmartCameraError, UseSmartCameraWebRTCResult, UseFaceDetectionResult, UseBlinkDetectionResult, UseSmartCameraResult, CameraDevice, Orientation, OutputOrientation, } from './types';
5
+ export { useSmartCamera, getAvailableCameras } from './hooks/useSmartCamera';
6
+ export { useFaceDetection } from './hooks/useFaceDetection';
7
+ export { useBlinkDetection } from './hooks/useBlinkDetection';
8
+ export { useSmartCameraWebRTC } from './hooks/useSmartCameraWebRTC';
9
+ export { detectFaces } from './detection/faceDetector';
10
+ export { processBlinkFromFaces, resetBlinkStates, getEyeState } from './detection/blinkProcessor';
11
+ export { detectFacesInImage as detectFacesInImageAsync } from './detection/staticImageDetector';
12
+ export { createFpsLimiter, debounce, throttle, createObjectPool, createSmartCameraError, safeExecute, validateFaceDetectionOptions, createPerformanceMonitor, } from './utils';
13
+ export { WebRTCBridge, getWebRTCBridge } from './webrtc';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGnE,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,4BAA4B,EAC5B,SAAS,GACV,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EAEV,eAAe,EACf,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EAGnB,KAAK,EACL,MAAM,EACN,aAAa,EACb,WAAW,EACX,YAAY,EACZ,IAAI,EAGJ,UAAU,EAGV,UAAU,EACV,gBAAgB,EAChB,YAAY,EAGZ,gBAAgB,EAGhB,oBAAoB,EACpB,gBAAgB,EAGhB,0BAA0B,EAC1B,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EAGpB,YAAY,EAGZ,WAAW,EACX,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGpE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGlG,OAAO,EAAE,kBAAkB,IAAI,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAGhG,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,sBAAsB,EACtB,WAAW,EACX,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
package/build/index.js ADDED
@@ -0,0 +1,20 @@
1
+ // Main component
2
+ export { SmartCamera } from './SmartCamera';
3
+ export { default as SmartCameraModule } from './SmartCameraModule';
4
+ // Native module functions
5
+ export { detectFacesInImage, updateFaceDetectionOptions, initializeWebRTC, startWebRTCStream, stopWebRTCStream, pushWebRTCFrame, isWebRTCStreaming, addFaceDetectionListener, addBlinkDetectionListener, addErrorListener, addWebRTCStateChangeListener, Constants, } from './SmartCameraModule';
6
+ // Hooks
7
+ export { useSmartCamera, getAvailableCameras } from './hooks/useSmartCamera';
8
+ export { useFaceDetection } from './hooks/useFaceDetection';
9
+ export { useBlinkDetection } from './hooks/useBlinkDetection';
10
+ export { useSmartCameraWebRTC } from './hooks/useSmartCameraWebRTC';
11
+ // Frame processors
12
+ export { detectFaces } from './detection/faceDetector';
13
+ export { processBlinkFromFaces, resetBlinkStates, getEyeState } from './detection/blinkProcessor';
14
+ // Static image detection
15
+ export { detectFacesInImage as detectFacesInImageAsync } from './detection/staticImageDetector';
16
+ // Utilities
17
+ export { createFpsLimiter, debounce, throttle, createObjectPool, createSmartCameraError, safeExecute, validateFaceDetectionOptions, createPerformanceMonitor, } from './utils';
18
+ // WebRTC Bridge
19
+ export { WebRTCBridge, getWebRTCBridge } from './webrtc';
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,0BAA0B;AAC1B,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,4BAA4B,EAC5B,SAAS,GACV,MAAM,qBAAqB,CAAC;AAoD7B,QAAQ;AACR,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,mBAAmB;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAElG,yBAAyB;AACzB,OAAO,EAAE,kBAAkB,IAAI,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAEhG,YAAY;AACZ,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,sBAAsB,EACtB,WAAW,EACX,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,SAAS,CAAC;AAEjB,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC","sourcesContent":["// Main component\nexport { SmartCamera } from './SmartCamera';\nexport { default as SmartCameraModule } from './SmartCameraModule';\n\n// Native module functions\nexport {\n detectFacesInImage,\n updateFaceDetectionOptions,\n initializeWebRTC,\n startWebRTCStream,\n stopWebRTCStream,\n pushWebRTCFrame,\n isWebRTCStreaming,\n addFaceDetectionListener,\n addBlinkDetectionListener,\n addErrorListener,\n addWebRTCStateChangeListener,\n Constants,\n} from './SmartCameraModule';\n\n// Types\nexport type {\n // Face Detection Options\n PerformanceMode,\n LandmarkMode,\n ContourMode,\n ClassificationMode,\n CameraFacing,\n FaceDetectionOptions,\n FrameProcessorOptions,\n StaticImageOptions,\n FaceDetectionConfig,\n\n // Face Detection Results\n Point,\n Bounds,\n FaceLandmarks,\n ContourType,\n FaceContours,\n Face,\n\n // Blink Detection\n BlinkEvent,\n\n // WebRTC\n WebRTCMode,\n VideoConstraints,\n WebRTCConfig,\n\n // Component Props\n SmartCameraProps,\n\n // Error Handling\n SmartCameraErrorCode,\n SmartCameraError,\n\n // Hook Return Types\n UseSmartCameraWebRTCResult,\n UseFaceDetectionResult,\n UseBlinkDetectionResult,\n UseSmartCameraResult,\n\n // Camera Device\n CameraDevice,\n\n // Orientation\n Orientation,\n OutputOrientation,\n} from './types';\n\n// Hooks\nexport { useSmartCamera, getAvailableCameras } from './hooks/useSmartCamera';\nexport { useFaceDetection } from './hooks/useFaceDetection';\nexport { useBlinkDetection } from './hooks/useBlinkDetection';\nexport { useSmartCameraWebRTC } from './hooks/useSmartCameraWebRTC';\n\n// Frame processors\nexport { detectFaces } from './detection/faceDetector';\nexport { processBlinkFromFaces, resetBlinkStates, getEyeState } from './detection/blinkProcessor';\n\n// Static image detection\nexport { detectFacesInImage as detectFacesInImageAsync } from './detection/staticImageDetector';\n\n// Utilities\nexport {\n createFpsLimiter,\n debounce,\n throttle,\n createObjectPool,\n createSmartCameraError,\n safeExecute,\n validateFaceDetectionOptions,\n createPerformanceMonitor,\n} from './utils';\n\n// WebRTC Bridge\nexport { WebRTCBridge, getWebRTCBridge } from './webrtc';\n"]}