catalyst-core 0.2.0-beta.3 → 0.3.0-beta.2

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 (167) hide show
  1. package/babel.native.config.cjs +8 -0
  2. package/bin/catalyst.js +49 -105
  3. package/changelog.md +8 -0
  4. package/dist/caching.js +1 -1
  5. package/dist/globals.d.ts +7 -0
  6. package/dist/index.jsx +8 -0
  7. package/dist/logger.js +74 -3
  8. package/dist/native/androidProject/app/build.gradle.kts +45 -4
  9. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/NativeBridge.kt +86 -0
  10. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/BridgeUtils.kt +8 -0
  11. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FrameworkServerUtils.kt +173 -13
  12. package/dist/native/androidProject/settings.gradle.kts +10 -0
  13. package/dist/native/androidSetup.js +300 -8
  14. package/dist/native/bridge/WebBridge.js +481 -59
  15. package/dist/native/bridge/constants/NativeInterfaces.js +304 -45
  16. package/dist/native/bridge/errors.js +250 -26
  17. package/dist/native/bridge/hooks/index.js +132 -1
  18. package/dist/native/bridge/hooks/useAI.js +94 -0
  19. package/dist/native/bridge/hooks/useCamera.js +347 -9
  20. package/dist/native/bridge/hooks/useDataProtection.js +200 -2
  21. package/dist/native/bridge/hooks/useDeviceInfo.js +71 -2
  22. package/dist/native/bridge/hooks/useFilePicker.js +429 -2
  23. package/dist/native/bridge/hooks/useGoogleSignIn.js +81 -1
  24. package/dist/native/bridge/hooks/useHapticFeedback.js +196 -1
  25. package/dist/native/bridge/hooks/useIntent.js +95 -1
  26. package/dist/native/bridge/hooks/useNativeTransition.js +202 -27
  27. package/dist/native/bridge/hooks/useNetworkStatus.js +84 -3
  28. package/dist/native/bridge/hooks/useNotification.js +318 -2
  29. package/dist/native/bridge/hooks/useSafeArea.js +84 -2
  30. package/dist/native/bridge/hooks/useVideoStream.js +434 -6
  31. package/dist/native/bridge/hooks/utils.js +27 -1
  32. package/dist/native/bridge/hooks.js +16 -1
  33. package/dist/native/bridge/perf/collectors/ApiCollector.js +66 -3
  34. package/dist/native/bridge/perf/collectors/CacheCollector.js +186 -11
  35. package/dist/native/bridge/perf/collectors/HookCollector.js +141 -19
  36. package/dist/native/bridge/perf/collectors/InsightsCollector.js +481 -23
  37. package/dist/native/bridge/perf/collectors/InteractionCollector.js +245 -10
  38. package/dist/native/bridge/perf/collectors/KeyboardCollector.js +107 -8
  39. package/dist/native/bridge/perf/collectors/NavigationCollector.js +273 -32
  40. package/dist/native/bridge/perf/collectors/NetworkTimingCollector.js +178 -2
  41. package/dist/native/bridge/perf/collectors/RenderCollector.js +258 -14
  42. package/dist/native/bridge/perf/collectors/ScrollCollector.js +95 -9
  43. package/dist/native/bridge/perf/collectors/ThreadCollector.js +90 -6
  44. package/dist/native/bridge/perf/core/constants.js +103 -20
  45. package/dist/native/bridge/perf/core/measure.js +179 -30
  46. package/dist/native/bridge/perf/core/session.js +89 -23
  47. package/dist/native/bridge/perf/core/store.js +554 -1
  48. package/dist/native/bridge/perf/core/summary.js +174 -1
  49. package/dist/native/bridge/perf/core/traceExport.js +240 -1
  50. package/dist/native/bridge/perf/core/waterfalls.js +146 -1
  51. package/dist/native/bridge/perf/index.js +359 -38
  52. package/dist/native/bridge/safeArea.js +53 -5
  53. package/dist/native/bridge/standardizedHooks.js +595 -82
  54. package/dist/native/bridge/useBaseHook.js +274 -38
  55. package/dist/native/bridge/utils/CameraUtils.js +201 -56
  56. package/dist/native/bridge/utils/FileObjectConverter.js +129 -18
  57. package/dist/native/bridge/utils/NativeBridge.js +425 -141
  58. package/dist/native/buildAndroid/assets.js +510 -13
  59. package/dist/native/buildAndroid/build.js +296 -19
  60. package/dist/native/buildAndroid/config.js +87 -1
  61. package/dist/native/buildAndroid/index.js +406 -1
  62. package/dist/native/buildAppAndroid.js +34 -2
  63. package/dist/native/buildAppIos.js +62 -2
  64. package/dist/native/buildIos/assets.js +609 -8
  65. package/dist/native/buildIos/build.js +639 -20
  66. package/dist/native/buildIos/config.js +294 -12
  67. package/dist/native/buildIos/index.js +343 -6
  68. package/dist/native/buildIos/plugins.js +343 -16
  69. package/dist/native/internal-plugins/device-info-plugin/android/DeviceInfoPlugin.kt +43 -0
  70. package/dist/native/internal-plugins/device-info-plugin/ios/DeviceInfoPlugin.swift +28 -0
  71. package/dist/native/internal-plugins/device-info-plugin/manifest.json +19 -0
  72. package/dist/native/internalPluginUtils.js +232 -7
  73. package/dist/native/package.json +3 -0
  74. package/dist/native/plugin-bridge/PluginBridge.js +227 -1
  75. package/dist/native/pluginComposerAndroid.js +407 -23
  76. package/dist/native/pluginComposerIos.js +435 -11
  77. package/dist/native/renameAndroidProject.js +1094 -88
  78. package/dist/native/setupEmulatorIos.js +289 -22
  79. package/dist/native/setupServer.js +160 -19
  80. package/dist/native/terminalProgress.js +199 -11
  81. package/dist/native/utils.js +193 -15
  82. package/dist/offline/catalyst-sw.js +145 -1
  83. package/dist/offline/registerServiceWorker.js +33 -1
  84. package/dist/otel.js +375 -46
  85. package/dist/router/ClientRouter.js +14 -2
  86. package/dist/router/ServerRouter.js +9 -1
  87. package/dist/router.js +1 -1
  88. package/dist/scripts/build.js +112 -3
  89. package/dist/scripts/checkVersion.js +3 -1
  90. package/dist/scripts/cleanCache.js +30 -1
  91. package/dist/scripts/generateOfflineManifest.js +116 -1
  92. package/dist/scripts/loadEnvironmentVariables.js +32 -6
  93. package/dist/scripts/plugins.js +309 -1
  94. package/dist/scripts/preServerInit.js +13 -0
  95. package/dist/scripts/scriptUtils.js +54 -3
  96. package/dist/scripts/serve.js +51 -4
  97. package/dist/scripts/start.js +47 -10
  98. package/dist/scripts/validator.js +149 -1
  99. package/dist/sentry.cjs +127 -0
  100. package/dist/sentry.js +125 -5
  101. package/dist/server/expressServer.js +296 -5
  102. package/dist/server/manifestCache.js +36 -0
  103. package/dist/server/renderer/ChunkExtractor.js +144 -0
  104. package/dist/server/renderer/document/Body.jsx +59 -0
  105. package/dist/server/renderer/document/FastRefresh.jsx +20 -0
  106. package/dist/server/renderer/document/Head.jsx +60 -0
  107. package/dist/server/renderer/document/index.jsx +2 -0
  108. package/dist/server/renderer/extract.js +149 -31
  109. package/dist/server/renderer/handler.jsx +450 -0
  110. package/dist/server/renderer/index.js +8 -1
  111. package/dist/server/renderer/render.js +47 -0
  112. package/dist/server/utils/botDetectionMiddleware.js +29 -0
  113. package/dist/server/utils/cjsRequire.js +10 -0
  114. package/dist/server/utils/userAgentUtil.js +87 -9
  115. package/dist/server/utils/validator.js +164 -1
  116. package/dist/vite/FastRefresh.jsx +20 -0
  117. package/dist/vite/inject-cache-key-plugin.js +276 -0
  118. package/dist/vite/loadCustomViteConfig.js +22 -0
  119. package/dist/vite/manifest-categorization-plugin.js +455 -0
  120. package/dist/vite/node-loader.mjs +458 -0
  121. package/dist/vite/scssParams.js +21 -0
  122. package/dist/vite/vite.config.client.js +130 -0
  123. package/dist/vite/vite.config.js +498 -0
  124. package/dist/vite/vite.config.server.js +84 -0
  125. package/dist/web-router/components/MetaTag.jsx +34 -0
  126. package/dist/web-router/components/RouterDataProvider.jsx +332 -0
  127. package/dist/web-router/components/Split.jsx +200 -0
  128. package/dist/web-router/components/SplitInview.jsx +106 -0
  129. package/dist/web-router/components/SsrRequestContext.jsx +14 -0
  130. package/dist/web-router/context.jsx +12 -0
  131. package/dist/web-router/hooks.jsx +72 -0
  132. package/dist/web-router/types/components/MetaTag.d.ts +2 -0
  133. package/dist/web-router/types/components/RouterDataProvider.d.ts +95 -0
  134. package/dist/web-router/types/context.d.ts +14 -0
  135. package/dist/web-router/types/hooks.d.ts +1 -0
  136. package/dist/web-router/types/index.d.ts +3 -0
  137. package/dist/web-router/types/utils/metaDataUtils.d.ts +24 -0
  138. package/dist/web-router/utils/metaDataUtils.jsx +119 -0
  139. package/mcp_v2/conversion-tasks.json +35 -17
  140. package/mcp_v2/knowledge-base.json +176 -17
  141. package/mcp_v2/lib/helpers.js +10 -0
  142. package/mcp_v2/mcp.js +40 -8
  143. package/mcp_v2/package.json +1 -0
  144. package/mcp_v2/tools/build.js +161 -37
  145. package/mcp_v2/tools/conversion.js +106 -5
  146. package/mcp_v2/tools/tasks.js +18 -14
  147. package/package.json +35 -68
  148. package/babel.config.js +0 -32
  149. package/dist/index.js +0 -1
  150. package/dist/scripts/devBuild.js +0 -3
  151. package/dist/scripts/devServe.js +0 -3
  152. package/dist/scripts/loadScriptsBeforeServerStarts.js +0 -4
  153. package/dist/scripts/registerAliases.js +0 -6
  154. package/dist/server/renderer/document/Body.js +0 -11
  155. package/dist/server/renderer/document/Head.js +0 -9
  156. package/dist/server/renderer/document/index.js +0 -1
  157. package/dist/server/renderer/handler.js +0 -47
  158. package/dist/server/startServer.js +0 -57
  159. package/dist/webpack/babel-plugins/remove-client.plugin.js +0 -5
  160. package/dist/webpack/babel-plugins/remove-ssr.plugin.js +0 -5
  161. package/dist/webpack/babel.config.client.js +0 -1
  162. package/dist/webpack/babel.config.ssr.js +0 -1
  163. package/dist/webpack/base.babel.js +0 -7
  164. package/dist/webpack/development.client.babel.js +0 -10
  165. package/dist/webpack/production.client.babel.js +0 -4
  166. package/dist/webpack/production.ssr.babel.js +0 -8
  167. package/dist/webpack/scssParams.js +0 -9
@@ -1,9 +1,347 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.useCameraPermission=exports.useCamera=exports.requestCameraPermission=void 0;var _react=require("react");var _NativeBridge=_interopRequireDefault(require("../utils/NativeBridge.js"));var _NativeInterfaces=require("../constants/NativeInterfaces.js");var _useBaseHook=require("../useBaseHook.js");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e};}/* eslint-disable react-compiler/react-compiler, react-hooks/exhaustive-deps */const useCamera=({webFallback}={})=>{const base=(0,_useBaseHook.useBaseHook)("useCamera",{hasWebFallback:true,webFallback});const[permission,setPermission]=(0,_react.useState)(null);if(typeof window==="undefined"){return{data:null,loading:false,progress:null,error:null,isWeb:true,isNative:false,webFallbackActive:false,webFallbackDisabled:false,setWebFallback:()=>{},execute:()=>{},clear:()=>{},clearError:()=>{},permission:null,photo:null,takePhoto:()=>{},isLoading:false,clearPhoto:()=>{}};}if(base.webFallbackDisabled){return{data:null,loading:false,progress:null,error:null,isWeb:true,isNative:false,webFallbackActive:false,webFallbackDisabled:true,setWebFallback:base.setWebFallback,execute:()=>{},clear:()=>{},clearError:()=>{},permission:null,photo:null,takePhoto:()=>{},isLoading:false,clearPhoto:()=>{}};}// Web fallback callback — always declared (Rules of Hooks)
2
- const webTakePhoto=(0,_react.useCallback)(()=>{const input=document.createElement("input");input.type="file";input.accept="image/*";input.capture="environment";input.onchange=()=>{const file=input.files?.[0];if(!file)return;const fileSrc=URL.createObjectURL(file);base.setDataAndComplete({fileSrc,fileName:file.name,size:file.size,mimeType:file.type,transport:"OBJECT_URL",source:"camera"});};input.click();},[base]);if(base.webFallbackActive){return{data:base.data,loading:base.loading,progress:base.progress,error:base.error,isWeb:true,isNative:false,webFallbackActive:true,webFallbackDisabled:false,setWebFallback:base.setWebFallback,execute:webTakePhoto,clear:base.clear,clearError:base.clearError,permission:null,photo:base.data,takePhoto:webTakePhoto,isLoading:base.loading,clearPhoto:base.clear};}(0,_react.useEffect)(()=>{window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.ON_CAMERA_CAPTURE,data=>{try{const result=typeof data==="string"?JSON.parse(data):data;console.log("📷 Camera capture result:",result);const photoData=result.fileSrc?{fileSrc:result.fileSrc,fileName:result.fileName,size:result.size,mimeType:result.mimeType,transport:result.transport,source:result.source}:{fileSrc:result.imageUrl,fileName:"camera_photo.jpg",size:0,mimeType:"image/jpeg",transport:"LEGACY",source:"camera"};base.setDataAndComplete(photoData);if(photoData.transport){base.updateProgress({transport:photoData.transport,bytesTotal:photoData.size||null});}console.log("📷 Photo captured successfully via transport:",photoData.transport);}catch(parseError){console.error("📷 Error parsing camera capture data:",parseError);base.handleNativeError("Failed to process captured photo");}});window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS,data=>{setPermission(data);console.log("📷 Camera permission status:",data);});window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.ON_CAMERA_ERROR,data=>{console.error("📷 Camera error:",data);base.handleNativeError(data);});return()=>{window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS);window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.ON_CAMERA_CAPTURE);window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.ON_CAMERA_ERROR);};},[base.setDataAndComplete,base.handleNativeError,base.updateProgress]);const takePhoto=()=>{console.log("📷 Camera open requested");base.executeOperation(()=>{base.updateProgress({state:"capturing",phase:"requesting",message:"Opening camera..."});_NativeBridge.default.camera.open();},"camera capture");};return{data:base.data,loading:base.loading,progress:base.progress,error:base.error,isWeb:base.isWeb,isNative:base.isNative,webFallbackActive:false,webFallbackDisabled:false,setWebFallback:base.setWebFallback,execute:takePhoto,clear:base.clear,clearError:base.clearError,permission,photo:base.data,takePhoto,isLoading:base.loading,clearPhoto:base.clear};};exports.useCamera=useCamera;const requestCameraPermission=()=>{if(typeof window==="undefined"){return Promise.resolve(null);}if(!window.WebBridge){throw new Error("WebBridge is not initialized. Call WebBridge.init() first.");}return new Promise((resolve,reject)=>{try{if(!_NativeBridge.default.isAvailable()){reject(new Error("Native bridge not available"));return;}const handlePermissionStatus=data=>{window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS);if(data===_NativeInterfaces.PERMISSION_STATUS.GRANTED){resolve(data);}else{reject(new Error(`Camera permission ${data.toLowerCase()}`));}};window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS,handlePermissionStatus);_NativeBridge.default.camera.requestPermission();console.log("📷 Camera permission requested");}catch(error){reject(error);}});};exports.requestCameraPermission=requestCameraPermission;const useCameraPermission=({webFallback}={})=>{const isWeb=typeof window==="undefined"?true:!_NativeBridge.default.isAvailable();// All hooks unconditionally at top level (Rules of Hooks)
3
- const[webFallbackState,setWebFallback]=(0,_react.useState)(true);const webFallbackResolved=webFallback!==undefined?webFallback!==false:webFallbackState;const webFallbackActive=isWeb&&webFallbackResolved;const webFallbackDisabled=isWeb&&!webFallbackResolved;const[permission,setPermission]=(0,_react.useState)(null);const[isLoading,setIsLoading]=(0,_react.useState)(true);const permResultRef=(0,_react.useRef)(null);(0,_react.useEffect)(()=>{if(typeof window==="undefined"){setIsLoading(false);return;}if(webFallbackDisabled){setIsLoading(false);return;}if(!window.WebBridge){// Web fallback: navigator.permissions API (query only — never prompts)
4
- if(typeof navigator==="undefined"||!navigator.permissions){setPermission(_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);setIsLoading(false);return;}const PERM_MAP={granted:_NativeInterfaces.PERMISSION_STATUS.GRANTED,denied:_NativeInterfaces.PERMISSION_STATUS.DENIED,prompt:_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED};navigator.permissions.query({name:"camera"}).then(result=>{permResultRef.current=result;setPermission(PERM_MAP[result.state]??_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);setIsLoading(false);result.onchange=()=>{setPermission(PERM_MAP[result.state]??_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);};}).catch(()=>{setPermission(_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);setIsLoading(false);});return;}// Native path
5
- const requestPermission=async()=>{try{if(!_NativeBridge.default.isAvailable()){setPermission(_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);setIsLoading(false);return;}window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS,data=>{setPermission(data);setIsLoading(false);console.log("📷 Camera permission status updated:",data);});_NativeBridge.default.camera.requestPermission();}catch(error){console.error("📷 Error requesting camera permission:",error);setPermission(_NativeInterfaces.PERMISSION_STATUS.DENIED);setIsLoading(false);}};requestPermission();return()=>{if(window.WebBridge&&_NativeBridge.default.isAvailable()){window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS);}};},[webFallbackDisabled]);// Web: navigator.permissions.query() never prompts. request() triggers getUserMedia
6
- // which causes the browser to show the permission dialog, then re-reads permission state.
7
- const request=(0,_react.useCallback)(async()=>{if(!isWeb||typeof window==="undefined")return;if(!navigator.mediaDevices?.getUserMedia)return;try{setIsLoading(true);const stream=await navigator.mediaDevices.getUserMedia({video:true,audio:false});stream.getTracks().forEach(t=>t.stop());}catch(_){// Ignore — the permission state change fires via permResultRef.current.onchange
8
- }// Re-query to get the authoritative state after the prompt
9
- if(navigator.permissions){try{const result=await navigator.permissions.query({name:"camera"});const PERM_MAP={granted:_NativeInterfaces.PERMISSION_STATUS.GRANTED,denied:_NativeInterfaces.PERMISSION_STATUS.DENIED,prompt:_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED};setPermission(PERM_MAP[result.state]??_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);}catch(_){/* permission query not supported */}}setIsLoading(false);},[isWeb]);if(typeof window==="undefined"){return{permission:null,isLoading:false,webFallbackActive:false,webFallbackDisabled:false,setWebFallback:()=>{},request:()=>{}};}return{permission,isLoading,webFallbackActive,webFallbackDisabled,setWebFallback,request};};exports.useCameraPermission=useCameraPermission;
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useCameraPermission = exports.useCamera = exports.requestCameraPermission = void 0;
7
+ var _react = require("react");
8
+ var _NativeBridge = _interopRequireDefault(require("../utils/NativeBridge.js"));
9
+ var _NativeInterfaces = require("../constants/NativeInterfaces.js");
10
+ var _useBaseHook = require("../useBaseHook.js");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ /* eslint-disable react-compiler/react-compiler, react-hooks/exhaustive-deps */
13
+
14
+ const useCamera = ({
15
+ webFallback
16
+ } = {}) => {
17
+ const base = (0, _useBaseHook.useBaseHook)("useCamera", {
18
+ hasWebFallback: true,
19
+ webFallback
20
+ });
21
+ const [permission, setPermission] = (0, _react.useState)(null);
22
+ if (typeof window === "undefined") {
23
+ return {
24
+ data: null,
25
+ loading: false,
26
+ progress: null,
27
+ error: null,
28
+ isWeb: true,
29
+ isNative: false,
30
+ webFallbackActive: false,
31
+ webFallbackDisabled: false,
32
+ setWebFallback: () => {},
33
+ execute: () => {},
34
+ clear: () => {},
35
+ clearError: () => {},
36
+ permission: null,
37
+ photo: null,
38
+ takePhoto: () => {},
39
+ isLoading: false,
40
+ clearPhoto: () => {}
41
+ };
42
+ }
43
+ if (base.webFallbackDisabled) {
44
+ return {
45
+ data: null,
46
+ loading: false,
47
+ progress: null,
48
+ error: null,
49
+ isWeb: true,
50
+ isNative: false,
51
+ webFallbackActive: false,
52
+ webFallbackDisabled: true,
53
+ setWebFallback: base.setWebFallback,
54
+ execute: () => {},
55
+ clear: () => {},
56
+ clearError: () => {},
57
+ permission: null,
58
+ photo: null,
59
+ takePhoto: () => {},
60
+ isLoading: false,
61
+ clearPhoto: () => {}
62
+ };
63
+ }
64
+
65
+ // Web fallback callback — always declared (Rules of Hooks)
66
+ const webTakePhoto = (0, _react.useCallback)(() => {
67
+ const input = document.createElement("input");
68
+ input.type = "file";
69
+ input.accept = "image/*";
70
+ input.capture = "environment";
71
+ input.onchange = () => {
72
+ const file = input.files?.[0];
73
+ if (!file) return;
74
+ const fileSrc = URL.createObjectURL(file);
75
+ base.setDataAndComplete({
76
+ fileSrc,
77
+ fileName: file.name,
78
+ size: file.size,
79
+ mimeType: file.type,
80
+ transport: "OBJECT_URL",
81
+ source: "camera"
82
+ });
83
+ };
84
+ input.click();
85
+ }, [base]);
86
+ if (base.webFallbackActive) {
87
+ return {
88
+ data: base.data,
89
+ loading: base.loading,
90
+ progress: base.progress,
91
+ error: base.error,
92
+ isWeb: true,
93
+ isNative: false,
94
+ webFallbackActive: true,
95
+ webFallbackDisabled: false,
96
+ setWebFallback: base.setWebFallback,
97
+ execute: webTakePhoto,
98
+ clear: base.clear,
99
+ clearError: base.clearError,
100
+ permission: null,
101
+ photo: base.data,
102
+ takePhoto: webTakePhoto,
103
+ isLoading: base.loading,
104
+ clearPhoto: base.clear
105
+ };
106
+ }
107
+ (0, _react.useEffect)(() => {
108
+ window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.ON_CAMERA_CAPTURE, data => {
109
+ try {
110
+ const result = typeof data === "string" ? JSON.parse(data) : data;
111
+ console.log("📷 Camera capture result:", result);
112
+ const photoData = result.fileSrc ? {
113
+ fileSrc: result.fileSrc,
114
+ fileName: result.fileName,
115
+ size: result.size,
116
+ mimeType: result.mimeType,
117
+ transport: result.transport,
118
+ source: result.source
119
+ } : {
120
+ fileSrc: result.imageUrl,
121
+ fileName: "camera_photo.jpg",
122
+ size: 0,
123
+ mimeType: "image/jpeg",
124
+ transport: "LEGACY",
125
+ source: "camera"
126
+ };
127
+ base.setDataAndComplete(photoData);
128
+ if (photoData.transport) {
129
+ base.updateProgress({
130
+ transport: photoData.transport,
131
+ bytesTotal: photoData.size || null
132
+ });
133
+ }
134
+ console.log("📷 Photo captured successfully via transport:", photoData.transport);
135
+ } catch (parseError) {
136
+ console.error("📷 Error parsing camera capture data:", parseError);
137
+ base.handleNativeError("Failed to process captured photo");
138
+ }
139
+ });
140
+ window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS, data => {
141
+ setPermission(data);
142
+ console.log("📷 Camera permission status:", data);
143
+ });
144
+ window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.ON_CAMERA_ERROR, data => {
145
+ console.error("📷 Camera error:", data);
146
+ base.handleNativeError(data);
147
+ });
148
+ return () => {
149
+ window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS);
150
+ window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.ON_CAMERA_CAPTURE);
151
+ window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.ON_CAMERA_ERROR);
152
+ };
153
+ }, [base.setDataAndComplete, base.handleNativeError, base.updateProgress]);
154
+ const takePhoto = () => {
155
+ console.log("📷 Camera open requested");
156
+ base.executeOperation(() => {
157
+ base.updateProgress({
158
+ state: "capturing",
159
+ phase: "requesting",
160
+ message: "Opening camera..."
161
+ });
162
+ _NativeBridge.default.camera.open();
163
+ }, "camera capture");
164
+ };
165
+ return {
166
+ data: base.data,
167
+ loading: base.loading,
168
+ progress: base.progress,
169
+ error: base.error,
170
+ isWeb: base.isWeb,
171
+ isNative: base.isNative,
172
+ webFallbackActive: false,
173
+ webFallbackDisabled: false,
174
+ setWebFallback: base.setWebFallback,
175
+ execute: takePhoto,
176
+ clear: base.clear,
177
+ clearError: base.clearError,
178
+ permission,
179
+ photo: base.data,
180
+ takePhoto,
181
+ isLoading: base.loading,
182
+ clearPhoto: base.clear
183
+ };
184
+ };
185
+ exports.useCamera = useCamera;
186
+ const requestCameraPermission = () => {
187
+ if (typeof window === "undefined") {
188
+ return Promise.resolve(null);
189
+ }
190
+ if (!window.WebBridge) {
191
+ throw new Error("WebBridge is not initialized. Call WebBridge.init() first.");
192
+ }
193
+ return new Promise((resolve, reject) => {
194
+ try {
195
+ if (!_NativeBridge.default.isAvailable()) {
196
+ reject(new Error("Native bridge not available"));
197
+ return;
198
+ }
199
+ const handlePermissionStatus = data => {
200
+ window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS);
201
+ if (data === _NativeInterfaces.PERMISSION_STATUS.GRANTED) {
202
+ resolve(data);
203
+ } else {
204
+ reject(new Error(`Camera permission ${data.toLowerCase()}`));
205
+ }
206
+ };
207
+ window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS, handlePermissionStatus);
208
+ _NativeBridge.default.camera.requestPermission();
209
+ console.log("📷 Camera permission requested");
210
+ } catch (error) {
211
+ reject(error);
212
+ }
213
+ });
214
+ };
215
+ exports.requestCameraPermission = requestCameraPermission;
216
+ const useCameraPermission = ({
217
+ webFallback
218
+ } = {}) => {
219
+ const isWeb = typeof window === "undefined" ? true : !_NativeBridge.default.isAvailable();
220
+
221
+ // All hooks unconditionally at top level (Rules of Hooks)
222
+ const [webFallbackState, setWebFallback] = (0, _react.useState)(true);
223
+ const webFallbackResolved = webFallback !== undefined ? webFallback !== false : webFallbackState;
224
+ const webFallbackActive = isWeb && webFallbackResolved;
225
+ const webFallbackDisabled = isWeb && !webFallbackResolved;
226
+ const [permission, setPermission] = (0, _react.useState)(null);
227
+ const [isLoading, setIsLoading] = (0, _react.useState)(true);
228
+ const permResultRef = (0, _react.useRef)(null);
229
+ (0, _react.useEffect)(() => {
230
+ if (typeof window === "undefined") {
231
+ setIsLoading(false);
232
+ return;
233
+ }
234
+ if (webFallbackDisabled) {
235
+ setIsLoading(false);
236
+ return;
237
+ }
238
+ if (!window.WebBridge) {
239
+ // Web fallback: navigator.permissions API (query only — never prompts)
240
+ if (typeof navigator === "undefined" || !navigator.permissions) {
241
+ setPermission(_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);
242
+ setIsLoading(false);
243
+ return;
244
+ }
245
+ const PERM_MAP = {
246
+ granted: _NativeInterfaces.PERMISSION_STATUS.GRANTED,
247
+ denied: _NativeInterfaces.PERMISSION_STATUS.DENIED,
248
+ prompt: _NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED
249
+ };
250
+ navigator.permissions.query({
251
+ name: "camera"
252
+ }).then(result => {
253
+ permResultRef.current = result;
254
+ setPermission(PERM_MAP[result.state] ?? _NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);
255
+ setIsLoading(false);
256
+ result.onchange = () => {
257
+ setPermission(PERM_MAP[result.state] ?? _NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);
258
+ };
259
+ }).catch(() => {
260
+ setPermission(_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);
261
+ setIsLoading(false);
262
+ });
263
+ return;
264
+ }
265
+
266
+ // Native path
267
+ const requestPermission = async () => {
268
+ try {
269
+ if (!_NativeBridge.default.isAvailable()) {
270
+ setPermission(_NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);
271
+ setIsLoading(false);
272
+ return;
273
+ }
274
+ window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS, data => {
275
+ setPermission(data);
276
+ setIsLoading(false);
277
+ console.log("📷 Camera permission status updated:", data);
278
+ });
279
+ _NativeBridge.default.camera.requestPermission();
280
+ } catch (error) {
281
+ console.error("📷 Error requesting camera permission:", error);
282
+ setPermission(_NativeInterfaces.PERMISSION_STATUS.DENIED);
283
+ setIsLoading(false);
284
+ }
285
+ };
286
+ requestPermission();
287
+ return () => {
288
+ if (window.WebBridge && _NativeBridge.default.isAvailable()) {
289
+ window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.CAMERA_PERMISSION_STATUS);
290
+ }
291
+ };
292
+ }, [webFallbackDisabled]);
293
+
294
+ // Web: navigator.permissions.query() never prompts. request() triggers getUserMedia
295
+ // which causes the browser to show the permission dialog, then re-reads permission state.
296
+ const request = (0, _react.useCallback)(async () => {
297
+ if (!isWeb || typeof window === "undefined") return;
298
+ if (!navigator.mediaDevices?.getUserMedia) return;
299
+ try {
300
+ setIsLoading(true);
301
+ const stream = await navigator.mediaDevices.getUserMedia({
302
+ video: true,
303
+ audio: false
304
+ });
305
+ stream.getTracks().forEach(t => t.stop());
306
+ } catch (_) {
307
+ // Ignore — the permission state change fires via permResultRef.current.onchange
308
+ }
309
+
310
+ // Re-query to get the authoritative state after the prompt
311
+ if (navigator.permissions) {
312
+ try {
313
+ const result = await navigator.permissions.query({
314
+ name: "camera"
315
+ });
316
+ const PERM_MAP = {
317
+ granted: _NativeInterfaces.PERMISSION_STATUS.GRANTED,
318
+ denied: _NativeInterfaces.PERMISSION_STATUS.DENIED,
319
+ prompt: _NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED
320
+ };
321
+ setPermission(PERM_MAP[result.state] ?? _NativeInterfaces.PERMISSION_STATUS.NOT_DETERMINED);
322
+ } catch (_) {
323
+ /* permission query not supported */
324
+ }
325
+ }
326
+ setIsLoading(false);
327
+ }, [isWeb]);
328
+ if (typeof window === "undefined") {
329
+ return {
330
+ permission: null,
331
+ isLoading: false,
332
+ webFallbackActive: false,
333
+ webFallbackDisabled: false,
334
+ setWebFallback: () => {},
335
+ request: () => {}
336
+ };
337
+ }
338
+ return {
339
+ permission,
340
+ isLoading,
341
+ webFallbackActive,
342
+ webFallbackDisabled,
343
+ setWebFallback,
344
+ request
345
+ };
346
+ };
347
+ exports.useCameraPermission = useCameraPermission;
@@ -1,2 +1,200 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.useDataProtection=void 0;var _react=require("react");var _NativeBridge=_interopRequireDefault(require("../utils/NativeBridge.js"));var _NativeInterfaces=require("../constants/NativeInterfaces.js");var _useBaseHook=require("../useBaseHook.js");var _utils=require("./utils.js");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e};}/* eslint-disable react-compiler/react-compiler, react-hooks/exhaustive-deps */const useDataProtection=({webFallback}={})=>{const base=(0,_useBaseHook.useBaseHook)("useDataProtection",{hasWebFallback:true,webFallback});const[screenSecure,setScreenSecureState]=(0,_react.useState)(false);// Web fallback state — always declared (Rules of Hooks)
2
- const[screenSecureWeb,setScreenSecureWeb]=(0,_react.useState)(false);const secureOverlayRef=(0,_react.useRef)(null);(0,_react.useEffect)(()=>{if(!base.webFallbackActive||!screenSecureWeb)return;const overlay=document.createElement("div");overlay.style.cssText="position:fixed;inset:0;background:#000;z-index:2147483647;display:none";document.body.appendChild(overlay);secureOverlayRef.current=overlay;const onVisibilityChange=()=>{overlay.style.display=document.hidden?"block":"none";};document.addEventListener("visibilitychange",onVisibilityChange);return()=>{document.removeEventListener("visibilitychange",onVisibilityChange);overlay.remove();secureOverlayRef.current=null;};},[base.webFallbackActive,screenSecureWeb]);const webSetScreenSecure=(0,_react.useCallback)(enable=>{setScreenSecureWeb(Boolean(enable));},[]);const webClearWebData=(0,_react.useCallback)(async()=>{try{localStorage.clear();sessionStorage.clear();}catch(_){/* storage may be unavailable in restricted contexts */}document.cookie.split(";").forEach(c=>{document.cookie=c.trim().split("=")[0]+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";});if(window.indexedDB?.databases){const dbs=await window.indexedDB.databases().catch(()=>[]);await Promise.all(dbs.map(db=>new Promise(res=>{const req=window.indexedDB.deleteDatabase(db.name);req.onsuccess=req.onerror=res;})));}},[]);if(typeof window==="undefined"){return{screenSecure:false,setScreenSecure:()=>{},clearWebData:()=>{},data:null,loading:false,progress:null,error:null,isWeb:true,isNative:false,webFallbackActive:false,webFallbackDisabled:false,setWebFallback:()=>{},clear:()=>{},clearError:()=>{}};}if(base.webFallbackDisabled){return{screenSecure:false,setScreenSecure:()=>{},clearWebData:()=>{},data:null,loading:false,progress:null,error:null,isWeb:true,isNative:false,webFallbackActive:false,webFallbackDisabled:true,setWebFallback:base.setWebFallback,clear:()=>{},clearError:()=>{}};}if(base.webFallbackActive){return{screenSecure:screenSecureWeb,setScreenSecure:webSetScreenSecure,clearWebData:webClearWebData,data:null,loading:false,progress:null,error:null,isWeb:true,isNative:false,webFallbackActive:true,webFallbackDisabled:false,setWebFallback:base.setWebFallback,clear:()=>{},clearError:()=>{}};}(0,_react.useEffect)(()=>{if(!_NativeBridge.default.isAvailable())return;const handleScreenSecureSet=data=>{try{const result=typeof data==="string"?JSON.parse(data):data;if(result?.error){base.handleNativeError(result.error);return;}setScreenSecureState(Boolean(result?.secure));base.setDataAndComplete(result);}catch(error){base.handleNativeError(error);}};const handleScreenSecureError=data=>{try{const result=typeof data==="string"?JSON.parse(data):data;base.handleNativeError(result?.error||"setScreenSecure failed");}catch(error){base.handleNativeError(error);}};const handleWebDataCleared=data=>{try{const result=typeof data==="string"?JSON.parse(data):data;if(result?.error){base.handleNativeError(result.error);return;}base.setDataAndComplete(result);}catch(error){base.handleNativeError(error);}};const handleWebDataClearError=data=>{try{const result=typeof data==="string"?JSON.parse(data):data;base.handleNativeError(result?.error||"clearWebData failed");}catch(error){base.handleNativeError(error);}};const handleScreenSecureStatus=data=>{try{const result=typeof data==="string"?JSON.parse(data):data;if(result?.error){base.handleNativeError(result.error);return;}setScreenSecureState(Boolean(result?.secure));}catch(error){base.handleNativeError(error);}};const cleanup=(0,_utils.registerNativeHandlers)([[_NativeInterfaces.NATIVE_CALLBACKS.ON_SCREEN_SECURE_SET,handleScreenSecureSet],[_NativeInterfaces.NATIVE_CALLBACKS.ON_SCREEN_SECURE_STATUS,handleScreenSecureStatus],[_NativeInterfaces.NATIVE_CALLBACKS.ON_SCREEN_SECURE_ERROR,handleScreenSecureError],[_NativeInterfaces.NATIVE_CALLBACKS.ON_WEB_DATA_CLEARED,handleWebDataCleared],[_NativeInterfaces.NATIVE_CALLBACKS.ON_WEB_DATA_CLEAR_ERROR,handleWebDataClearError]]);base.callNative(()=>_NativeBridge.default.security.getScreenSecure());return cleanup;},[base.setDataAndComplete,base.handleNativeError]);const setScreenSecure=(0,_react.useCallback)(enable=>{base.callNative(()=>_NativeBridge.default.security.setScreenSecure(enable));},[base.callNative]);const clearWebData=(0,_react.useCallback)(()=>{base.callNative(()=>_NativeBridge.default.security.clearWebData());},[base.callNative]);return{data:base.data,loading:base.loading,progress:base.progress,error:base.error,isWeb:base.isWeb,isNative:base.isNative,webFallbackActive:false,webFallbackDisabled:false,setWebFallback:base.setWebFallback,clear:base.clear,clearError:base.clearError,screenSecure,setScreenSecure,clearWebData};};exports.useDataProtection=useDataProtection;
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useDataProtection = void 0;
7
+ var _react = require("react");
8
+ var _NativeBridge = _interopRequireDefault(require("../utils/NativeBridge.js"));
9
+ var _NativeInterfaces = require("../constants/NativeInterfaces.js");
10
+ var _useBaseHook = require("../useBaseHook.js");
11
+ var _utils = require("./utils.js");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ /* eslint-disable react-compiler/react-compiler, react-hooks/exhaustive-deps */
14
+
15
+ const useDataProtection = ({
16
+ webFallback
17
+ } = {}) => {
18
+ const base = (0, _useBaseHook.useBaseHook)("useDataProtection", {
19
+ hasWebFallback: true,
20
+ webFallback
21
+ });
22
+ const [screenSecure, setScreenSecureState] = (0, _react.useState)(false);
23
+
24
+ // Web fallback state — always declared (Rules of Hooks)
25
+ const [screenSecureWeb, setScreenSecureWeb] = (0, _react.useState)(false);
26
+ const secureOverlayRef = (0, _react.useRef)(null);
27
+ (0, _react.useEffect)(() => {
28
+ if (!base.webFallbackActive || !screenSecureWeb) return;
29
+ const overlay = document.createElement("div");
30
+ overlay.style.cssText = "position:fixed;inset:0;background:#000;z-index:2147483647;display:none";
31
+ document.body.appendChild(overlay);
32
+ secureOverlayRef.current = overlay;
33
+ const onVisibilityChange = () => {
34
+ overlay.style.display = document.hidden ? "block" : "none";
35
+ };
36
+ document.addEventListener("visibilitychange", onVisibilityChange);
37
+ return () => {
38
+ document.removeEventListener("visibilitychange", onVisibilityChange);
39
+ overlay.remove();
40
+ secureOverlayRef.current = null;
41
+ };
42
+ }, [base.webFallbackActive, screenSecureWeb]);
43
+ const webSetScreenSecure = (0, _react.useCallback)(enable => {
44
+ setScreenSecureWeb(Boolean(enable));
45
+ }, []);
46
+ const webClearWebData = (0, _react.useCallback)(async () => {
47
+ try {
48
+ localStorage.clear();
49
+ sessionStorage.clear();
50
+ } catch (_) {
51
+ /* storage may be unavailable in restricted contexts */
52
+ }
53
+ document.cookie.split(";").forEach(c => {
54
+ document.cookie = c.trim().split("=")[0] + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
55
+ });
56
+ if (window.indexedDB?.databases) {
57
+ const dbs = await window.indexedDB.databases().catch(() => []);
58
+ await Promise.all(dbs.map(db => new Promise(res => {
59
+ const req = window.indexedDB.deleteDatabase(db.name);
60
+ req.onsuccess = req.onerror = res;
61
+ })));
62
+ }
63
+ }, []);
64
+ if (typeof window === "undefined") {
65
+ return {
66
+ screenSecure: false,
67
+ setScreenSecure: () => {},
68
+ clearWebData: () => {},
69
+ data: null,
70
+ loading: false,
71
+ progress: null,
72
+ error: null,
73
+ isWeb: true,
74
+ isNative: false,
75
+ webFallbackActive: false,
76
+ webFallbackDisabled: false,
77
+ setWebFallback: () => {},
78
+ clear: () => {},
79
+ clearError: () => {}
80
+ };
81
+ }
82
+ if (base.webFallbackDisabled) {
83
+ return {
84
+ screenSecure: false,
85
+ setScreenSecure: () => {},
86
+ clearWebData: () => {},
87
+ data: null,
88
+ loading: false,
89
+ progress: null,
90
+ error: null,
91
+ isWeb: true,
92
+ isNative: false,
93
+ webFallbackActive: false,
94
+ webFallbackDisabled: true,
95
+ setWebFallback: base.setWebFallback,
96
+ clear: () => {},
97
+ clearError: () => {}
98
+ };
99
+ }
100
+ if (base.webFallbackActive) {
101
+ return {
102
+ screenSecure: screenSecureWeb,
103
+ setScreenSecure: webSetScreenSecure,
104
+ clearWebData: webClearWebData,
105
+ data: null,
106
+ loading: false,
107
+ progress: null,
108
+ error: null,
109
+ isWeb: true,
110
+ isNative: false,
111
+ webFallbackActive: true,
112
+ webFallbackDisabled: false,
113
+ setWebFallback: base.setWebFallback,
114
+ clear: () => {},
115
+ clearError: () => {}
116
+ };
117
+ }
118
+ (0, _react.useEffect)(() => {
119
+ if (!_NativeBridge.default.isAvailable()) return;
120
+ const handleScreenSecureSet = data => {
121
+ try {
122
+ const result = typeof data === "string" ? JSON.parse(data) : data;
123
+ if (result?.error) {
124
+ base.handleNativeError(result.error);
125
+ return;
126
+ }
127
+ setScreenSecureState(Boolean(result?.secure));
128
+ base.setDataAndComplete(result);
129
+ } catch (error) {
130
+ base.handleNativeError(error);
131
+ }
132
+ };
133
+ const handleScreenSecureError = data => {
134
+ try {
135
+ const result = typeof data === "string" ? JSON.parse(data) : data;
136
+ base.handleNativeError(result?.error || "setScreenSecure failed");
137
+ } catch (error) {
138
+ base.handleNativeError(error);
139
+ }
140
+ };
141
+ const handleWebDataCleared = data => {
142
+ try {
143
+ const result = typeof data === "string" ? JSON.parse(data) : data;
144
+ if (result?.error) {
145
+ base.handleNativeError(result.error);
146
+ return;
147
+ }
148
+ base.setDataAndComplete(result);
149
+ } catch (error) {
150
+ base.handleNativeError(error);
151
+ }
152
+ };
153
+ const handleWebDataClearError = data => {
154
+ try {
155
+ const result = typeof data === "string" ? JSON.parse(data) : data;
156
+ base.handleNativeError(result?.error || "clearWebData failed");
157
+ } catch (error) {
158
+ base.handleNativeError(error);
159
+ }
160
+ };
161
+ const handleScreenSecureStatus = data => {
162
+ try {
163
+ const result = typeof data === "string" ? JSON.parse(data) : data;
164
+ if (result?.error) {
165
+ base.handleNativeError(result.error);
166
+ return;
167
+ }
168
+ setScreenSecureState(Boolean(result?.secure));
169
+ } catch (error) {
170
+ base.handleNativeError(error);
171
+ }
172
+ };
173
+ const cleanup = (0, _utils.registerNativeHandlers)([[_NativeInterfaces.NATIVE_CALLBACKS.ON_SCREEN_SECURE_SET, handleScreenSecureSet], [_NativeInterfaces.NATIVE_CALLBACKS.ON_SCREEN_SECURE_STATUS, handleScreenSecureStatus], [_NativeInterfaces.NATIVE_CALLBACKS.ON_SCREEN_SECURE_ERROR, handleScreenSecureError], [_NativeInterfaces.NATIVE_CALLBACKS.ON_WEB_DATA_CLEARED, handleWebDataCleared], [_NativeInterfaces.NATIVE_CALLBACKS.ON_WEB_DATA_CLEAR_ERROR, handleWebDataClearError]]);
174
+ base.callNative(() => _NativeBridge.default.security.getScreenSecure());
175
+ return cleanup;
176
+ }, [base.setDataAndComplete, base.handleNativeError]);
177
+ const setScreenSecure = (0, _react.useCallback)(enable => {
178
+ base.callNative(() => _NativeBridge.default.security.setScreenSecure(enable));
179
+ }, [base.callNative]);
180
+ const clearWebData = (0, _react.useCallback)(() => {
181
+ base.callNative(() => _NativeBridge.default.security.clearWebData());
182
+ }, [base.callNative]);
183
+ return {
184
+ data: base.data,
185
+ loading: base.loading,
186
+ progress: base.progress,
187
+ error: base.error,
188
+ isWeb: base.isWeb,
189
+ isNative: base.isNative,
190
+ webFallbackActive: false,
191
+ webFallbackDisabled: false,
192
+ setWebFallback: base.setWebFallback,
193
+ clear: base.clear,
194
+ clearError: base.clearError,
195
+ screenSecure,
196
+ setScreenSecure,
197
+ clearWebData
198
+ };
199
+ };
200
+ exports.useDataProtection = useDataProtection;
@@ -1,2 +1,71 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.useDeviceInfo=void 0;var _react=require("react");var _NativeBridge=_interopRequireDefault(require("../utils/NativeBridge.js"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e};}/* eslint-disable react-compiler/react-compiler, react-hooks/exhaustive-deps */const useDeviceInfo=({webFallback}={})=>{const[deviceInfo,setDeviceInfo]=(0,_react.useState)(null);const[loading,setLoading]=(0,_react.useState)(true);const[error,setError]=(0,_react.useState)(null);const isNative=_NativeBridge.default.isAvailable();const[webFallbackState,setWebFallback]=(0,_react.useState)(true);const webFallbackResolved=webFallback!==undefined?webFallback!==false:webFallbackState;const webFallbackActive=!isNative&&webFallbackResolved;const webFallbackDisabled=!isNative&&!webFallbackResolved;(0,_react.useEffect)(()=>{if(typeof window==="undefined"){setLoading(false);return;}if(!_NativeBridge.default.isAvailable()){if(webFallbackDisabled){setLoading(false);return;}// Web fallback: derive info from browser APIs
2
- const ua=navigator.userAgent||"";setDeviceInfo({model:ua,manufacturer:"browser",platform:"web",screenWidth:screen.width*(window.devicePixelRatio||1),screenHeight:screen.height*(window.devicePixelRatio||1),screenDensity:window.devicePixelRatio||1,appInfo:null});setLoading(false);return;}if(!window.WebBridge){setError("WebBridge not initialized");setLoading(false);return;}window.WebBridge.getDeviceInfo().then(info=>{setDeviceInfo(info);setLoading(false);}).catch(err=>{setError(err.message||"Failed to get device info");setLoading(false);});},[webFallbackDisabled]);return{deviceInfo,loading,error,isNative,isWeb:!isNative,webFallbackActive,webFallbackDisabled,setWebFallback};};exports.useDeviceInfo=useDeviceInfo;
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useDeviceInfo = void 0;
7
+ var _react = require("react");
8
+ var _NativeBridge = _interopRequireDefault(require("../utils/NativeBridge.js"));
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ /* eslint-disable react-compiler/react-compiler, react-hooks/exhaustive-deps */
11
+
12
+ const useDeviceInfo = ({
13
+ webFallback
14
+ } = {}) => {
15
+ const [deviceInfo, setDeviceInfo] = (0, _react.useState)(null);
16
+ const [loading, setLoading] = (0, _react.useState)(true);
17
+ const [error, setError] = (0, _react.useState)(null);
18
+ const isNative = _NativeBridge.default.isAvailable();
19
+ const [webFallbackState, setWebFallback] = (0, _react.useState)(true);
20
+ const webFallbackResolved = webFallback !== undefined ? webFallback !== false : webFallbackState;
21
+ const webFallbackActive = !isNative && webFallbackResolved;
22
+ const webFallbackDisabled = !isNative && !webFallbackResolved;
23
+ (0, _react.useEffect)(() => {
24
+ if (typeof window === "undefined") {
25
+ setLoading(false);
26
+ return;
27
+ }
28
+ if (!_NativeBridge.default.isAvailable()) {
29
+ if (webFallbackDisabled) {
30
+ setLoading(false);
31
+ return;
32
+ }
33
+ // Web fallback: derive info from browser APIs
34
+ const ua = navigator.userAgent || "";
35
+ setDeviceInfo({
36
+ model: ua,
37
+ manufacturer: "browser",
38
+ platform: "web",
39
+ screenWidth: screen.width * (window.devicePixelRatio || 1),
40
+ screenHeight: screen.height * (window.devicePixelRatio || 1),
41
+ screenDensity: window.devicePixelRatio || 1,
42
+ appInfo: null
43
+ });
44
+ setLoading(false);
45
+ return;
46
+ }
47
+ if (!window.WebBridge) {
48
+ setError("WebBridge not initialized");
49
+ setLoading(false);
50
+ return;
51
+ }
52
+ window.WebBridge.getDeviceInfo().then(info => {
53
+ setDeviceInfo(info);
54
+ setLoading(false);
55
+ }).catch(err => {
56
+ setError(err.message || "Failed to get device info");
57
+ setLoading(false);
58
+ });
59
+ }, [webFallbackDisabled]);
60
+ return {
61
+ deviceInfo,
62
+ loading,
63
+ error,
64
+ isNative,
65
+ isWeb: !isNative,
66
+ webFallbackActive,
67
+ webFallbackDisabled,
68
+ setWebFallback
69
+ };
70
+ };
71
+ exports.useDeviceInfo = useDeviceInfo;