react-native-rectangle-doc-scanner 3.107.0 → 3.108.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.
@@ -45,6 +45,7 @@ const react_native_fs_1 = __importDefault(require("react-native-fs"));
45
45
  const DocScanner_1 = require("./DocScanner");
46
46
  let ImageManipulator = null;
47
47
  let ImageRotate = null;
48
+ const ImageStoreManager = react_native_1.NativeModules.ImageStoreManager;
48
49
  try {
49
50
  ImageManipulator = require('expo-image-manipulator');
50
51
  }
@@ -63,6 +64,24 @@ const isImageRotateAvailable = !!ImageRotate?.rotateImage;
63
64
  const isImageRotationSupported = isExpoImageManipulatorAvailable || isImageRotateAvailable;
64
65
  const stripFileUri = (value) => value.replace(/^file:\/\//, '');
65
66
  const ensureFileUri = (value) => (value.startsWith('file://') ? value : `file://${value}`);
67
+ const getBase64FromImageStore = async (uri) => {
68
+ const getBase64ForTag = ImageStoreManager?.getBase64ForTag?.bind(ImageStoreManager);
69
+ if (!getBase64ForTag) {
70
+ throw new Error('ImageStoreManager.getBase64ForTag unavailable');
71
+ }
72
+ return new Promise((resolve, reject) => {
73
+ getBase64ForTag(uri, (base64) => resolve(base64), (error) => {
74
+ const message = typeof error === 'string'
75
+ ? error
76
+ : error && typeof error === 'object' && 'message' in error
77
+ ? String(error.message)
78
+ : 'Failed to read from ImageStore';
79
+ reject(new Error(message));
80
+ });
81
+ }).finally(() => {
82
+ ImageStoreManager?.removeImageForTag?.(uri);
83
+ });
84
+ };
66
85
  const CROPPER_TIMEOUT_MS = 8000;
67
86
  const CROPPER_TIMEOUT_CODE = 'cropper_timeout';
68
87
  const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -433,16 +452,20 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
433
452
  if (isImageRotateAvailable && ImageRotate?.rotateImage) {
434
453
  const sourceUri = ensureFileUri(croppedImageData.path);
435
454
  const rotatedUri = await rotateImageWithFallback(sourceUri, rotationNormalized);
455
+ let finalPath = croppedImageData.path;
436
456
  let base64Result = croppedImageData.base64;
437
457
  try {
438
- base64Result = await react_native_fs_1.default.readFile(stripFileUri(rotatedUri), 'base64');
458
+ const base64FromStore = await getBase64FromImageStore(rotatedUri);
459
+ const destinationPath = `${react_native_fs_1.default.CachesDirectoryPath}/full-doc-scanner-rotated-${Date.now()}-${Math.floor(Math.random() * 10000)}.jpg`;
460
+ await react_native_fs_1.default.writeFile(destinationPath, base64FromStore, 'base64');
461
+ finalPath = destinationPath;
462
+ base64Result = base64FromStore;
439
463
  }
440
464
  catch (readError) {
441
- console.warn('[FullDocScanner] Failed to generate base64 for rotated image:', readError);
442
- base64Result = undefined;
465
+ console.warn('[FullDocScanner] Failed to persist rotated image from ImageStore:', readError);
443
466
  }
444
467
  onResult({
445
- path: rotatedUri,
468
+ path: finalPath,
446
469
  base64: base64Result,
447
470
  });
448
471
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "3.107.0",
3
+ "version": "3.108.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -8,6 +8,7 @@ import {
8
8
  Text,
9
9
  TouchableOpacity,
10
10
  View,
11
+ NativeModules,
11
12
  } from 'react-native';
12
13
  import { launchImageLibrary } from 'react-native-image-picker';
13
14
  import ImageCropPicker from 'react-native-image-crop-picker';
@@ -31,8 +32,18 @@ type ImageRotateModule = {
31
32
  ) => void;
32
33
  } | null;
33
34
 
35
+ type ImageStoreModule = {
36
+ getBase64ForTag?: (
37
+ uri: string,
38
+ success: (base64: string) => void,
39
+ failure: (error: unknown) => void,
40
+ ) => void;
41
+ removeImageForTag?: (uri: string) => void;
42
+ } | undefined;
43
+
34
44
  let ImageManipulator: ImageManipulatorModule | null = null;
35
45
  let ImageRotate: ImageRotateModule = null;
46
+ const ImageStoreManager: ImageStoreModule = NativeModules.ImageStoreManager;
36
47
 
37
48
  try {
38
49
  ImageManipulator = require('expo-image-manipulator') as ImageManipulatorModule;
@@ -60,6 +71,32 @@ const isImageRotationSupported = isExpoImageManipulatorAvailable || isImageRotat
60
71
  const stripFileUri = (value: string) => value.replace(/^file:\/\//, '');
61
72
  const ensureFileUri = (value: string) => (value.startsWith('file://') ? value : `file://${value}`);
62
73
 
74
+ const getBase64FromImageStore = async (uri: string): Promise<string> => {
75
+ const getBase64ForTag = ImageStoreManager?.getBase64ForTag?.bind(ImageStoreManager);
76
+
77
+ if (!getBase64ForTag) {
78
+ throw new Error('ImageStoreManager.getBase64ForTag unavailable');
79
+ }
80
+
81
+ return new Promise<string>((resolve, reject) => {
82
+ getBase64ForTag(
83
+ uri,
84
+ (base64: string) => resolve(base64),
85
+ (error: unknown) => {
86
+ const message =
87
+ typeof error === 'string'
88
+ ? error
89
+ : error && typeof error === 'object' && 'message' in error
90
+ ? String((error as any).message)
91
+ : 'Failed to read from ImageStore';
92
+ reject(new Error(message));
93
+ },
94
+ );
95
+ }).finally(() => {
96
+ ImageStoreManager?.removeImageForTag?.(uri);
97
+ });
98
+ };
99
+
63
100
  const CROPPER_TIMEOUT_MS = 8000;
64
101
  const CROPPER_TIMEOUT_CODE = 'cropper_timeout';
65
102
 
@@ -587,17 +624,23 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
587
624
  if (isImageRotateAvailable && ImageRotate?.rotateImage) {
588
625
  const sourceUri = ensureFileUri(croppedImageData.path);
589
626
  const rotatedUri = await rotateImageWithFallback(sourceUri, rotationNormalized);
590
- let base64Result = croppedImageData.base64;
627
+
628
+ let finalPath = croppedImageData.path;
629
+ let base64Result: string | undefined = croppedImageData.base64;
591
630
 
592
631
  try {
593
- base64Result = await RNFS.readFile(stripFileUri(rotatedUri), 'base64');
632
+ const base64FromStore = await getBase64FromImageStore(rotatedUri);
633
+ const destinationPath = `${RNFS.CachesDirectoryPath}/full-doc-scanner-rotated-${Date.now()}-${Math.floor(Math.random() * 10000)}.jpg`;
634
+
635
+ await RNFS.writeFile(destinationPath, base64FromStore, 'base64');
636
+ finalPath = destinationPath;
637
+ base64Result = base64FromStore;
594
638
  } catch (readError) {
595
- console.warn('[FullDocScanner] Failed to generate base64 for rotated image:', readError);
596
- base64Result = undefined;
639
+ console.warn('[FullDocScanner] Failed to persist rotated image from ImageStore:', readError);
597
640
  }
598
641
 
599
642
  onResult({
600
- path: rotatedUri,
643
+ path: finalPath,
601
644
  base64: base64Result,
602
645
  });
603
646
  return;