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

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 (160) 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/index.jsx +8 -0
  6. package/dist/logger.js +74 -3
  7. package/dist/native/androidSetup.js +300 -8
  8. package/dist/native/bridge/WebBridge.js +481 -59
  9. package/dist/native/bridge/constants/NativeInterfaces.js +290 -45
  10. package/dist/native/bridge/errors.js +250 -26
  11. package/dist/native/bridge/hooks/index.js +125 -1
  12. package/dist/native/bridge/hooks/useCamera.js +347 -9
  13. package/dist/native/bridge/hooks/useDataProtection.js +200 -2
  14. package/dist/native/bridge/hooks/useDeviceInfo.js +71 -2
  15. package/dist/native/bridge/hooks/useFilePicker.js +429 -2
  16. package/dist/native/bridge/hooks/useGoogleSignIn.js +81 -1
  17. package/dist/native/bridge/hooks/useHapticFeedback.js +196 -1
  18. package/dist/native/bridge/hooks/useIntent.js +95 -1
  19. package/dist/native/bridge/hooks/useNativeTransition.js +202 -27
  20. package/dist/native/bridge/hooks/useNetworkStatus.js +84 -3
  21. package/dist/native/bridge/hooks/useNotification.js +318 -2
  22. package/dist/native/bridge/hooks/useSafeArea.js +84 -2
  23. package/dist/native/bridge/hooks/useVideoStream.js +434 -6
  24. package/dist/native/bridge/hooks/utils.js +27 -1
  25. package/dist/native/bridge/hooks.js +16 -1
  26. package/dist/native/bridge/perf/collectors/ApiCollector.js +66 -3
  27. package/dist/native/bridge/perf/collectors/CacheCollector.js +186 -11
  28. package/dist/native/bridge/perf/collectors/HookCollector.js +141 -19
  29. package/dist/native/bridge/perf/collectors/InsightsCollector.js +481 -23
  30. package/dist/native/bridge/perf/collectors/InteractionCollector.js +245 -10
  31. package/dist/native/bridge/perf/collectors/KeyboardCollector.js +107 -8
  32. package/dist/native/bridge/perf/collectors/NavigationCollector.js +273 -32
  33. package/dist/native/bridge/perf/collectors/NetworkTimingCollector.js +178 -2
  34. package/dist/native/bridge/perf/collectors/RenderCollector.js +258 -14
  35. package/dist/native/bridge/perf/collectors/ScrollCollector.js +95 -9
  36. package/dist/native/bridge/perf/collectors/ThreadCollector.js +90 -6
  37. package/dist/native/bridge/perf/core/constants.js +103 -20
  38. package/dist/native/bridge/perf/core/measure.js +179 -30
  39. package/dist/native/bridge/perf/core/session.js +89 -23
  40. package/dist/native/bridge/perf/core/store.js +554 -1
  41. package/dist/native/bridge/perf/core/summary.js +174 -1
  42. package/dist/native/bridge/perf/core/traceExport.js +240 -1
  43. package/dist/native/bridge/perf/core/waterfalls.js +146 -1
  44. package/dist/native/bridge/perf/index.js +359 -38
  45. package/dist/native/bridge/safeArea.js +53 -5
  46. package/dist/native/bridge/standardizedHooks.js +595 -82
  47. package/dist/native/bridge/useBaseHook.js +274 -38
  48. package/dist/native/bridge/utils/CameraUtils.js +201 -56
  49. package/dist/native/bridge/utils/FileObjectConverter.js +129 -18
  50. package/dist/native/bridge/utils/NativeBridge.js +425 -141
  51. package/dist/native/buildAndroid/assets.js +510 -13
  52. package/dist/native/buildAndroid/build.js +296 -19
  53. package/dist/native/buildAndroid/config.js +87 -1
  54. package/dist/native/buildAndroid/index.js +374 -1
  55. package/dist/native/buildAppAndroid.js +34 -2
  56. package/dist/native/buildAppIos.js +62 -2
  57. package/dist/native/buildIos/assets.js +609 -8
  58. package/dist/native/buildIos/build.js +639 -20
  59. package/dist/native/buildIos/config.js +294 -12
  60. package/dist/native/buildIos/index.js +343 -6
  61. package/dist/native/buildIos/plugins.js +343 -16
  62. package/dist/native/internal-plugins/device-info-plugin/android/DeviceInfoPlugin.kt +43 -0
  63. package/dist/native/internal-plugins/device-info-plugin/ios/DeviceInfoPlugin.swift +28 -0
  64. package/dist/native/internal-plugins/device-info-plugin/manifest.json +19 -0
  65. package/dist/native/internalPluginUtils.js +232 -7
  66. package/dist/native/package.json +3 -0
  67. package/dist/native/plugin-bridge/PluginBridge.js +227 -1
  68. package/dist/native/pluginComposerAndroid.js +407 -23
  69. package/dist/native/pluginComposerIos.js +435 -11
  70. package/dist/native/renameAndroidProject.js +1094 -88
  71. package/dist/native/setupEmulatorIos.js +289 -22
  72. package/dist/native/setupServer.js +160 -19
  73. package/dist/native/terminalProgress.js +199 -11
  74. package/dist/native/utils.js +193 -15
  75. package/dist/offline/catalyst-sw.js +145 -1
  76. package/dist/offline/registerServiceWorker.js +33 -1
  77. package/dist/otel.js +375 -46
  78. package/dist/router/ClientRouter.js +14 -2
  79. package/dist/router/ServerRouter.js +9 -1
  80. package/dist/router.js +1 -1
  81. package/dist/scripts/build.js +112 -3
  82. package/dist/scripts/checkVersion.js +3 -1
  83. package/dist/scripts/cleanCache.js +30 -1
  84. package/dist/scripts/generateOfflineManifest.js +116 -1
  85. package/dist/scripts/loadEnvironmentVariables.js +32 -6
  86. package/dist/scripts/plugins.js +309 -1
  87. package/dist/scripts/preServerInit.js +13 -0
  88. package/dist/scripts/scriptUtils.js +54 -3
  89. package/dist/scripts/serve.js +51 -4
  90. package/dist/scripts/start.js +47 -10
  91. package/dist/scripts/validator.js +149 -1
  92. package/dist/sentry.cjs +127 -0
  93. package/dist/sentry.js +125 -5
  94. package/dist/server/expressServer.js +250 -5
  95. package/dist/server/manifestCache.js +36 -0
  96. package/dist/server/renderer/ChunkExtractor.js +144 -0
  97. package/dist/server/renderer/document/Body.jsx +59 -0
  98. package/dist/server/renderer/document/FastRefresh.jsx +20 -0
  99. package/dist/server/renderer/document/Head.jsx +60 -0
  100. package/dist/server/renderer/document/index.jsx +2 -0
  101. package/dist/server/renderer/extract.js +149 -31
  102. package/dist/server/renderer/handler.jsx +433 -0
  103. package/dist/server/renderer/index.js +8 -1
  104. package/dist/server/renderer/render.js +47 -0
  105. package/dist/server/utils/botDetectionMiddleware.js +29 -0
  106. package/dist/server/utils/cjsRequire.js +10 -0
  107. package/dist/server/utils/userAgentUtil.js +87 -9
  108. package/dist/server/utils/validator.js +164 -1
  109. package/dist/vite/FastRefresh.jsx +20 -0
  110. package/dist/vite/inject-cache-key-plugin.js +276 -0
  111. package/dist/vite/loadCustomViteConfig.js +22 -0
  112. package/dist/vite/manifest-categorization-plugin.js +455 -0
  113. package/dist/vite/node-loader.mjs +458 -0
  114. package/dist/vite/scssParams.js +21 -0
  115. package/dist/vite/vite.config.client.js +130 -0
  116. package/dist/vite/vite.config.js +422 -0
  117. package/dist/vite/vite.config.server.js +84 -0
  118. package/dist/web-router/components/MetaTag.jsx +34 -0
  119. package/dist/web-router/components/RouterDataProvider.jsx +332 -0
  120. package/dist/web-router/components/Split.jsx +200 -0
  121. package/dist/web-router/components/SplitInview.jsx +106 -0
  122. package/dist/web-router/components/SsrRequestContext.jsx +14 -0
  123. package/dist/web-router/context.jsx +12 -0
  124. package/dist/web-router/hooks.jsx +72 -0
  125. package/dist/web-router/types/components/MetaTag.d.ts +2 -0
  126. package/dist/web-router/types/components/RouterDataProvider.d.ts +95 -0
  127. package/dist/web-router/types/context.d.ts +14 -0
  128. package/dist/web-router/types/hooks.d.ts +1 -0
  129. package/dist/web-router/types/index.d.ts +3 -0
  130. package/dist/web-router/types/utils/metaDataUtils.d.ts +24 -0
  131. package/dist/web-router/utils/metaDataUtils.jsx +119 -0
  132. package/mcp_v2/conversion-tasks.json +35 -17
  133. package/mcp_v2/knowledge-base.json +124 -13
  134. package/mcp_v2/lib/helpers.js +10 -0
  135. package/mcp_v2/mcp.js +4 -4
  136. package/mcp_v2/package.json +1 -0
  137. package/mcp_v2/tools/build.js +116 -20
  138. package/mcp_v2/tools/conversion.js +106 -5
  139. package/mcp_v2/tools/tasks.js +18 -14
  140. package/package.json +35 -68
  141. package/babel.config.js +0 -32
  142. package/dist/index.js +0 -1
  143. package/dist/scripts/devBuild.js +0 -3
  144. package/dist/scripts/devServe.js +0 -3
  145. package/dist/scripts/loadScriptsBeforeServerStarts.js +0 -4
  146. package/dist/scripts/registerAliases.js +0 -6
  147. package/dist/server/renderer/document/Body.js +0 -11
  148. package/dist/server/renderer/document/Head.js +0 -9
  149. package/dist/server/renderer/document/index.js +0 -1
  150. package/dist/server/renderer/handler.js +0 -47
  151. package/dist/server/startServer.js +0 -57
  152. package/dist/webpack/babel-plugins/remove-client.plugin.js +0 -5
  153. package/dist/webpack/babel-plugins/remove-ssr.plugin.js +0 -5
  154. package/dist/webpack/babel.config.client.js +0 -1
  155. package/dist/webpack/babel.config.ssr.js +0 -1
  156. package/dist/webpack/base.babel.js +0 -7
  157. package/dist/webpack/development.client.babel.js +0 -10
  158. package/dist/webpack/production.client.babel.js +0 -4
  159. package/dist/webpack/production.ssr.babel.js +0 -8
  160. package/dist/webpack/scssParams.js +0 -9
@@ -1,2 +1,429 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.useFilePicker=exports.sanitizeFilePickerOptions=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 _FileObjectConverter=require("../utils/FileObjectConverter.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 SSR_FILE_PICKER_STUB={data:null,loading:false,progress:null,error:null,isWeb:true,isNative:false,execute:_utils.noop,clear:_utils.noop,clearError:_utils.noop,getFileObject:(0,_utils.createSSRUnavailable)("getFileObject"),getAllFileObjects:(0,_utils.createSSRUnavailable)("getAllFileObjects"),canCreateFileObject:false,canCreateFileObjects:[],selectedFile:null,selectedFiles:[],pickFile:_utils.noop,isLoading:false,processingState:null,clearFile:_utils.noop};const extractFiles=value=>{if(!value)return[];if(Array.isArray(value))return value.filter(Boolean);if(Array.isArray(value.files))return value.files.filter(Boolean);if(value.files)return[value.files];return[value].filter(Boolean);};const sanitizeFilePickerOptions=input=>{const options={...input};const mime=typeof options.mimeType==="string"?options.mimeType.trim():"";options.mimeType=mime.length>0?mime:"*/*";const coerceInteger=(value,min)=>{if(value==null)return undefined;const numeric=typeof value==="string"?Number(value.trim()):Number(value);if(!Number.isFinite(numeric)){throw new Error("File picker numeric options must be valid numbers");}if(!Number.isInteger(numeric)){throw new Error("File picker numeric options must be integers");}if(numeric<min){throw new Error(`File picker numeric options must be ≥ ${min}`);}return numeric;};const minFiles=coerceInteger(options.minFiles,1);const maxFiles=coerceInteger(options.maxFiles,1);const minFileSize=coerceInteger(options.minFileSize,0);const maxFileSize=coerceInteger(options.maxFileSize,0);if(minFiles!==undefined)options.minFiles=minFiles;if(maxFiles!==undefined)options.maxFiles=maxFiles;if(minFileSize!==undefined)options.minFileSize=minFileSize;if(maxFileSize!==undefined)options.maxFileSize=maxFileSize;if(minFiles!==undefined&&maxFiles!==undefined&&minFiles>maxFiles){throw new Error("minFiles cannot be greater than maxFiles");}if(minFileSize!==undefined&&maxFileSize!==undefined&&minFileSize>maxFileSize){throw new Error("minFileSize cannot be greater than maxFileSize");}const multiple=typeof options.multiple==="boolean"?options.multiple:Boolean(options.multiple);options.multiple=multiple||minFiles&&minFiles>1||maxFiles&&maxFiles>1;return options;};exports.sanitizeFilePickerOptions=sanitizeFilePickerOptions;const resolvePickPayload=input=>{if(input==null)return"*/*";if(typeof input==="string")return input.trim()||"*/*";return sanitizeFilePickerOptions(input);};const normalizeFilePickResult=payload=>{const parsed=(0,_utils.parseNativePayload)(payload);if(!parsed)return null;const files=extractFiles(parsed);if(!files.length)return null;const first=files[0];const rawOptions=!Array.isArray(parsed)&&parsed&&typeof parsed.options==="object"?parsed.options:null;let normalizedOptions=rawOptions||null;if(rawOptions){try{normalizedOptions=sanitizeFilePickerOptions(rawOptions);}catch(_error){normalizedOptions=rawOptions;}}const totalSize=parsed.totalSize??files.reduce((sum,file)=>{const size=typeof file?.size==="number"?file.size:0;return sum+size;},0);const base=Array.isArray(parsed)?{}:parsed;return{...base,files,multiple:parsed.multiple??files.length>1,count:parsed.count??files.length,totalSize,fileName:parsed.fileName??first?.fileName??first?.name??null,fileSrc:parsed.fileSrc??first?.fileSrc??first?.src??null,filePath:parsed.filePath??first?.filePath??null,size:parsed.size??first?.size??null,mimeType:parsed.mimeType??first?.mimeType??first?.type??null,transport:parsed.transport??first?.transport??null,options:normalizedOptions};};const updateProgressFromResult=(updateProgress,result)=>{if(!result)return;const first=result.files?.[0];const transport=result.transport??first?.transport??null;const bytesTotal=result.totalSize??result.size??(typeof first?.size==="number"?first.size:null);if(transport||bytesTotal!=null){updateProgress({transport:transport??null,bytesTotal});}};const mapStateToProgress=state=>{if(state==null){return{state:"starting",phase:null,message:"File picker: starting..."};}const rawState=String(state);const normalized=rawState.toLowerCase();const allowedStates=new Set(["opening","processing","routing"]);const progressState=allowedStates.has(normalized)?normalized:"starting";return{state:progressState,phase:rawState,message:`File picker: ${rawState}...`};};const useFilePicker=({webFallback}={})=>{const base=(0,_useBaseHook.useBaseHook)("useFilePicker",{hasWebFallback:true,webFallback});const fileObjectCache=(0,_react.useRef)(new Map());// Web fallback callbacks — always declared (Rules of Hooks)
2
- const webPickFile=(0,_react.useCallback)((input=null)=>{let accept="*/*";let multiple=false;if(typeof input==="string"){accept=input.trim()||"*/*";}else if(input&&typeof input==="object"){try{const opts=sanitizeFilePickerOptions(input);accept=opts.mimeType||"*/*";multiple=Boolean(opts.multiple);}catch(err){base.handleNativeError(err instanceof Error?err.message:"Invalid file picker options");return;}}const el=document.createElement("input");el.type="file";el.accept=accept;el.multiple=multiple;el.onchange=()=>{const fileList=Array.from(el.files||[]);if(!fileList.length)return;const files=fileList.map(f=>({fileName:f.name,fileSrc:URL.createObjectURL(f),size:f.size,mimeType:f.type,transport:"OBJECT_URL"}));base.setDataAndComplete({files,multiple:files.length>1,count:files.length,totalSize:files.reduce((sum,f)=>sum+(f.size||0),0),fileName:files[0].fileName,fileSrc:files[0].fileSrc,filePath:null,size:files[0].size,mimeType:files[0].mimeType,transport:"OBJECT_URL",options:null});};el.click();},[base]);const webFiles=(0,_react.useMemo)(()=>extractFiles(base.data),[base.data]);if(typeof window==="undefined"){return SSR_FILE_PICKER_STUB;}if(base.webFallbackDisabled){return{data:null,loading:false,progress:null,error:null,isWeb:true,isNative:false,webFallbackActive:false,webFallbackDisabled:true,setWebFallback:base.setWebFallback,execute:_utils.noop,clear:_utils.noop,clearError:_utils.noop,getFileObject:(0,_utils.createSSRUnavailable)("getFileObject"),getAllFileObjects:(0,_utils.createSSRUnavailable)("getAllFileObjects"),canCreateFileObject:false,canCreateFileObjects:[],selectedFile:null,selectedFiles:[],pickFile:_utils.noop,isLoading:false,processingState:null,clearFile:_utils.noop};}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:webPickFile,clear:base.clear,clearError:base.clearError,getFileObject:(0,_utils.createSSRUnavailable)("getFileObject"),getAllFileObjects:(0,_utils.createSSRUnavailable)("getAllFileObjects"),canCreateFileObject:false,canCreateFileObjects:[],selectedFile:webFiles[0]||null,selectedFiles:webFiles,pickFile:webPickFile,isLoading:base.loading,processingState:null,clearFile:base.clear};}const{data,loading,progress,error,isWeb,isNative,setWebFallback,clear:baseClear,clearError,updateProgress,resetProgress,setDataAndComplete,handleNativeError,executeOperation,setLoading}=base;(0,_react.useEffect)(()=>{const handleFilePicked=payload=>{try{fileObjectCache.current.clear();const normalizedData=normalizeFilePickResult(payload);console.log("📁 File picked:",normalizedData);if(!normalizedData){throw new Error("No file data received from native file picker");}setDataAndComplete(normalizedData);updateProgressFromResult(updateProgress,normalizedData);}catch(error){console.error("📁 Error processing file data:",error);handleNativeError("Error processing selected file");}};const handleFilePickError=nativeError=>{console.error("📁 File pick error:",nativeError);handleNativeError(nativeError);};const handleFilePickCancelled=data=>{console.log("📁 File pick cancelled:",data);setLoading(false);resetProgress();};const handleFilePickStateUpdate=stateData=>{try{const parsedState=(0,_utils.parseNativePayload)(stateData);console.log("📁 File picker state:",parsedState?.state);const progressUpdate=mapStateToProgress(parsedState?.state);updateProgress(progressUpdate);if(parsedState?.state){setLoading(true);}}catch(parseError){console.error("📁 Error parsing state data:",parseError);}};return(0,_utils.registerNativeHandlers)([[_NativeInterfaces.NATIVE_CALLBACKS.ON_FILE_PICKED,handleFilePicked],[_NativeInterfaces.NATIVE_CALLBACKS.ON_FILE_PICK_ERROR,handleFilePickError],[_NativeInterfaces.NATIVE_CALLBACKS.ON_FILE_PICK_CANCELLED,handleFilePickCancelled],[_NativeInterfaces.NATIVE_CALLBACKS.ON_FILE_PICK_STATE_UPDATE,handleFilePickStateUpdate]]);},[handleNativeError,resetProgress,setDataAndComplete,setLoading,updateProgress]);const pickFile=(0,_react.useCallback)((input=null)=>{let payload;try{payload=resolvePickPayload(input);}catch(error){const message=error instanceof Error?error.message:"Invalid file picker options";handleNativeError(message);return;}if(typeof payload==="string"){console.log("📁 Picking file with MIME type:",payload);}else{console.log("📁 Picking file with options:",payload);}executeOperation(()=>{_NativeBridge.default.file.pick(payload);},"file pick");},[executeOperation,handleNativeError]);const files=(0,_react.useMemo)(()=>extractFiles(data),[data]);const getFileObject=(0,_react.useCallback)(async(index=0)=>{if(!files.length){throw new Error("No file data available. Please pick a file first.");}const targetIndex=Number(index);const fileEntry=files[targetIndex];if(!fileEntry){throw new Error(`No file data available at index ${targetIndex}.`);}if(fileObjectCache.current.has(targetIndex)){console.log("📁 Returning cached File object",{index:targetIndex});return fileObjectCache.current.get(targetIndex);}const{fileSrc,fileName,mimeType,transport}=fileEntry;if(!(0,_FileObjectConverter.canCreateFileObject)(transport)){const errorMessage=(0,_FileObjectConverter.getUnsupportedTransportMessage)(transport);console.error("❌",errorMessage);throw new Error(errorMessage);}console.log("📁 Converting to File object",{index:targetIndex,transport,fileName,mimeType});try{let fileObject;if(transport==="BRIDGE_BASE64"){fileObject=(0,_FileObjectConverter.base64ToFile)(fileSrc,fileName,mimeType);}else if(transport==="FRAMEWORK_SERVER"){fileObject=await(0,_FileObjectConverter.urlToFile)(fileSrc,fileName,mimeType);}fileObjectCache.current.set(targetIndex,fileObject);console.log("✅ File object created successfully",{index:targetIndex,name:fileObject.name,size:fileObject.size,type:fileObject.type});return fileObject;}catch(error){console.error("❌ Failed to create File object:",error);throw new Error(`Failed to create File object: ${error.message}`);}},[files]);const getAllFileObjects=(0,_react.useCallback)(async()=>{if(!files.length){throw new Error("No file data available. Please pick a file first.");}return Promise.all(files.map((_,index)=>getFileObject(index)));},[files,getFileObject]);const canCreateFileObjectForCurrentFile=(0,_react.useMemo)(()=>files.length>0?(0,_FileObjectConverter.canCreateFileObject)(files[0].transport):false,[files]);const canCreateFileObjectsList=(0,_react.useMemo)(()=>files.map(file=>(0,_FileObjectConverter.canCreateFileObject)(file.transport)),[files]);const clear=(0,_react.useCallback)(()=>{fileObjectCache.current.clear();baseClear();},[baseClear]);return{data,loading,progress,error,isWeb,isNative,webFallbackActive:false,webFallbackDisabled:false,setWebFallback,execute:pickFile,clear,clearError,getFileObject,getAllFileObjects,canCreateFileObject:canCreateFileObjectForCurrentFile,canCreateFileObjects:canCreateFileObjectsList,selectedFile:files[0]||null,selectedFiles:files,pickFile,isLoading:loading,processingState:progress?.phase||null,clearFile:clear};};exports.useFilePicker=useFilePicker;
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useFilePicker = exports.sanitizeFilePickerOptions = 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 _FileObjectConverter = require("../utils/FileObjectConverter.js");
12
+ var _utils = require("./utils.js");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ /* eslint-disable react-compiler/react-compiler, react-hooks/exhaustive-deps */
15
+
16
+ const SSR_FILE_PICKER_STUB = {
17
+ data: null,
18
+ loading: false,
19
+ progress: null,
20
+ error: null,
21
+ isWeb: true,
22
+ isNative: false,
23
+ execute: _utils.noop,
24
+ clear: _utils.noop,
25
+ clearError: _utils.noop,
26
+ getFileObject: (0, _utils.createSSRUnavailable)("getFileObject"),
27
+ getAllFileObjects: (0, _utils.createSSRUnavailable)("getAllFileObjects"),
28
+ canCreateFileObject: false,
29
+ canCreateFileObjects: [],
30
+ selectedFile: null,
31
+ selectedFiles: [],
32
+ pickFile: _utils.noop,
33
+ isLoading: false,
34
+ processingState: null,
35
+ clearFile: _utils.noop
36
+ };
37
+ const extractFiles = value => {
38
+ if (!value) return [];
39
+ if (Array.isArray(value)) return value.filter(Boolean);
40
+ if (Array.isArray(value.files)) return value.files.filter(Boolean);
41
+ if (value.files) return [value.files];
42
+ return [value].filter(Boolean);
43
+ };
44
+ const sanitizeFilePickerOptions = input => {
45
+ const options = {
46
+ ...input
47
+ };
48
+ const mime = typeof options.mimeType === "string" ? options.mimeType.trim() : "";
49
+ options.mimeType = mime.length > 0 ? mime : "*/*";
50
+ const coerceInteger = (value, min) => {
51
+ if (value == null) return undefined;
52
+ const numeric = typeof value === "string" ? Number(value.trim()) : Number(value);
53
+ if (!Number.isFinite(numeric)) {
54
+ throw new Error("File picker numeric options must be valid numbers");
55
+ }
56
+ if (!Number.isInteger(numeric)) {
57
+ throw new Error("File picker numeric options must be integers");
58
+ }
59
+ if (numeric < min) {
60
+ throw new Error(`File picker numeric options must be ≥ ${min}`);
61
+ }
62
+ return numeric;
63
+ };
64
+ const minFiles = coerceInteger(options.minFiles, 1);
65
+ const maxFiles = coerceInteger(options.maxFiles, 1);
66
+ const minFileSize = coerceInteger(options.minFileSize, 0);
67
+ const maxFileSize = coerceInteger(options.maxFileSize, 0);
68
+ if (minFiles !== undefined) options.minFiles = minFiles;
69
+ if (maxFiles !== undefined) options.maxFiles = maxFiles;
70
+ if (minFileSize !== undefined) options.minFileSize = minFileSize;
71
+ if (maxFileSize !== undefined) options.maxFileSize = maxFileSize;
72
+ if (minFiles !== undefined && maxFiles !== undefined && minFiles > maxFiles) {
73
+ throw new Error("minFiles cannot be greater than maxFiles");
74
+ }
75
+ if (minFileSize !== undefined && maxFileSize !== undefined && minFileSize > maxFileSize) {
76
+ throw new Error("minFileSize cannot be greater than maxFileSize");
77
+ }
78
+ const multiple = typeof options.multiple === "boolean" ? options.multiple : Boolean(options.multiple);
79
+ options.multiple = multiple || minFiles && minFiles > 1 || maxFiles && maxFiles > 1;
80
+ return options;
81
+ };
82
+ exports.sanitizeFilePickerOptions = sanitizeFilePickerOptions;
83
+ const resolvePickPayload = input => {
84
+ if (input == null) return "*/*";
85
+ if (typeof input === "string") return input.trim() || "*/*";
86
+ return sanitizeFilePickerOptions(input);
87
+ };
88
+ const normalizeFilePickResult = payload => {
89
+ const parsed = (0, _utils.parseNativePayload)(payload);
90
+ if (!parsed) return null;
91
+ const files = extractFiles(parsed);
92
+ if (!files.length) return null;
93
+ const first = files[0];
94
+ const rawOptions = !Array.isArray(parsed) && parsed && typeof parsed.options === "object" ? parsed.options : null;
95
+ let normalizedOptions = rawOptions || null;
96
+ if (rawOptions) {
97
+ try {
98
+ normalizedOptions = sanitizeFilePickerOptions(rawOptions);
99
+ } catch (_error) {
100
+ normalizedOptions = rawOptions;
101
+ }
102
+ }
103
+ const totalSize = parsed.totalSize ?? files.reduce((sum, file) => {
104
+ const size = typeof file?.size === "number" ? file.size : 0;
105
+ return sum + size;
106
+ }, 0);
107
+ const base = Array.isArray(parsed) ? {} : parsed;
108
+ return {
109
+ ...base,
110
+ files,
111
+ multiple: parsed.multiple ?? files.length > 1,
112
+ count: parsed.count ?? files.length,
113
+ totalSize,
114
+ fileName: parsed.fileName ?? first?.fileName ?? first?.name ?? null,
115
+ fileSrc: parsed.fileSrc ?? first?.fileSrc ?? first?.src ?? null,
116
+ filePath: parsed.filePath ?? first?.filePath ?? null,
117
+ size: parsed.size ?? first?.size ?? null,
118
+ mimeType: parsed.mimeType ?? first?.mimeType ?? first?.type ?? null,
119
+ transport: parsed.transport ?? first?.transport ?? null,
120
+ options: normalizedOptions
121
+ };
122
+ };
123
+ const updateProgressFromResult = (updateProgress, result) => {
124
+ if (!result) return;
125
+ const first = result.files?.[0];
126
+ const transport = result.transport ?? first?.transport ?? null;
127
+ const bytesTotal = result.totalSize ?? result.size ?? (typeof first?.size === "number" ? first.size : null);
128
+ if (transport || bytesTotal != null) {
129
+ updateProgress({
130
+ transport: transport ?? null,
131
+ bytesTotal
132
+ });
133
+ }
134
+ };
135
+ const mapStateToProgress = state => {
136
+ if (state == null) {
137
+ return {
138
+ state: "starting",
139
+ phase: null,
140
+ message: "File picker: starting..."
141
+ };
142
+ }
143
+ const rawState = String(state);
144
+ const normalized = rawState.toLowerCase();
145
+ const allowedStates = new Set(["opening", "processing", "routing"]);
146
+ const progressState = allowedStates.has(normalized) ? normalized : "starting";
147
+ return {
148
+ state: progressState,
149
+ phase: rawState,
150
+ message: `File picker: ${rawState}...`
151
+ };
152
+ };
153
+ const useFilePicker = ({
154
+ webFallback
155
+ } = {}) => {
156
+ const base = (0, _useBaseHook.useBaseHook)("useFilePicker", {
157
+ hasWebFallback: true,
158
+ webFallback
159
+ });
160
+ const fileObjectCache = (0, _react.useRef)(new Map());
161
+
162
+ // Web fallback callbacks — always declared (Rules of Hooks)
163
+ const webPickFile = (0, _react.useCallback)((input = null) => {
164
+ let accept = "*/*";
165
+ let multiple = false;
166
+ if (typeof input === "string") {
167
+ accept = input.trim() || "*/*";
168
+ } else if (input && typeof input === "object") {
169
+ try {
170
+ const opts = sanitizeFilePickerOptions(input);
171
+ accept = opts.mimeType || "*/*";
172
+ multiple = Boolean(opts.multiple);
173
+ } catch (err) {
174
+ base.handleNativeError(err instanceof Error ? err.message : "Invalid file picker options");
175
+ return;
176
+ }
177
+ }
178
+ const el = document.createElement("input");
179
+ el.type = "file";
180
+ el.accept = accept;
181
+ el.multiple = multiple;
182
+ el.onchange = () => {
183
+ const fileList = Array.from(el.files || []);
184
+ if (!fileList.length) return;
185
+ const files = fileList.map(f => ({
186
+ fileName: f.name,
187
+ fileSrc: URL.createObjectURL(f),
188
+ size: f.size,
189
+ mimeType: f.type,
190
+ transport: "OBJECT_URL"
191
+ }));
192
+ base.setDataAndComplete({
193
+ files,
194
+ multiple: files.length > 1,
195
+ count: files.length,
196
+ totalSize: files.reduce((sum, f) => sum + (f.size || 0), 0),
197
+ fileName: files[0].fileName,
198
+ fileSrc: files[0].fileSrc,
199
+ filePath: null,
200
+ size: files[0].size,
201
+ mimeType: files[0].mimeType,
202
+ transport: "OBJECT_URL",
203
+ options: null
204
+ });
205
+ };
206
+ el.click();
207
+ }, [base]);
208
+ const webFiles = (0, _react.useMemo)(() => extractFiles(base.data), [base.data]);
209
+ if (typeof window === "undefined") {
210
+ return SSR_FILE_PICKER_STUB;
211
+ }
212
+ if (base.webFallbackDisabled) {
213
+ return {
214
+ data: null,
215
+ loading: false,
216
+ progress: null,
217
+ error: null,
218
+ isWeb: true,
219
+ isNative: false,
220
+ webFallbackActive: false,
221
+ webFallbackDisabled: true,
222
+ setWebFallback: base.setWebFallback,
223
+ execute: _utils.noop,
224
+ clear: _utils.noop,
225
+ clearError: _utils.noop,
226
+ getFileObject: (0, _utils.createSSRUnavailable)("getFileObject"),
227
+ getAllFileObjects: (0, _utils.createSSRUnavailable)("getAllFileObjects"),
228
+ canCreateFileObject: false,
229
+ canCreateFileObjects: [],
230
+ selectedFile: null,
231
+ selectedFiles: [],
232
+ pickFile: _utils.noop,
233
+ isLoading: false,
234
+ processingState: null,
235
+ clearFile: _utils.noop
236
+ };
237
+ }
238
+ if (base.webFallbackActive) {
239
+ return {
240
+ data: base.data,
241
+ loading: base.loading,
242
+ progress: base.progress,
243
+ error: base.error,
244
+ isWeb: true,
245
+ isNative: false,
246
+ webFallbackActive: true,
247
+ webFallbackDisabled: false,
248
+ setWebFallback: base.setWebFallback,
249
+ execute: webPickFile,
250
+ clear: base.clear,
251
+ clearError: base.clearError,
252
+ getFileObject: (0, _utils.createSSRUnavailable)("getFileObject"),
253
+ getAllFileObjects: (0, _utils.createSSRUnavailable)("getAllFileObjects"),
254
+ canCreateFileObject: false,
255
+ canCreateFileObjects: [],
256
+ selectedFile: webFiles[0] || null,
257
+ selectedFiles: webFiles,
258
+ pickFile: webPickFile,
259
+ isLoading: base.loading,
260
+ processingState: null,
261
+ clearFile: base.clear
262
+ };
263
+ }
264
+ const {
265
+ data,
266
+ loading,
267
+ progress,
268
+ error,
269
+ isWeb,
270
+ isNative,
271
+ setWebFallback,
272
+ clear: baseClear,
273
+ clearError,
274
+ updateProgress,
275
+ resetProgress,
276
+ setDataAndComplete,
277
+ handleNativeError,
278
+ executeOperation,
279
+ setLoading
280
+ } = base;
281
+ (0, _react.useEffect)(() => {
282
+ const handleFilePicked = payload => {
283
+ try {
284
+ fileObjectCache.current.clear();
285
+ const normalizedData = normalizeFilePickResult(payload);
286
+ console.log("📁 File picked:", normalizedData);
287
+ if (!normalizedData) {
288
+ throw new Error("No file data received from native file picker");
289
+ }
290
+ setDataAndComplete(normalizedData);
291
+ updateProgressFromResult(updateProgress, normalizedData);
292
+ } catch (error) {
293
+ console.error("📁 Error processing file data:", error);
294
+ handleNativeError("Error processing selected file");
295
+ }
296
+ };
297
+ const handleFilePickError = nativeError => {
298
+ console.error("📁 File pick error:", nativeError);
299
+ handleNativeError(nativeError);
300
+ };
301
+ const handleFilePickCancelled = data => {
302
+ console.log("📁 File pick cancelled:", data);
303
+ setLoading(false);
304
+ resetProgress();
305
+ };
306
+ const handleFilePickStateUpdate = stateData => {
307
+ try {
308
+ const parsedState = (0, _utils.parseNativePayload)(stateData);
309
+ console.log("📁 File picker state:", parsedState?.state);
310
+ const progressUpdate = mapStateToProgress(parsedState?.state);
311
+ updateProgress(progressUpdate);
312
+ if (parsedState?.state) {
313
+ setLoading(true);
314
+ }
315
+ } catch (parseError) {
316
+ console.error("📁 Error parsing state data:", parseError);
317
+ }
318
+ };
319
+ return (0, _utils.registerNativeHandlers)([[_NativeInterfaces.NATIVE_CALLBACKS.ON_FILE_PICKED, handleFilePicked], [_NativeInterfaces.NATIVE_CALLBACKS.ON_FILE_PICK_ERROR, handleFilePickError], [_NativeInterfaces.NATIVE_CALLBACKS.ON_FILE_PICK_CANCELLED, handleFilePickCancelled], [_NativeInterfaces.NATIVE_CALLBACKS.ON_FILE_PICK_STATE_UPDATE, handleFilePickStateUpdate]]);
320
+ }, [handleNativeError, resetProgress, setDataAndComplete, setLoading, updateProgress]);
321
+ const pickFile = (0, _react.useCallback)((input = null) => {
322
+ let payload;
323
+ try {
324
+ payload = resolvePickPayload(input);
325
+ } catch (error) {
326
+ const message = error instanceof Error ? error.message : "Invalid file picker options";
327
+ handleNativeError(message);
328
+ return;
329
+ }
330
+ if (typeof payload === "string") {
331
+ console.log("📁 Picking file with MIME type:", payload);
332
+ } else {
333
+ console.log("📁 Picking file with options:", payload);
334
+ }
335
+ executeOperation(() => {
336
+ _NativeBridge.default.file.pick(payload);
337
+ }, "file pick");
338
+ }, [executeOperation, handleNativeError]);
339
+ const files = (0, _react.useMemo)(() => extractFiles(data), [data]);
340
+ const getFileObject = (0, _react.useCallback)(async (index = 0) => {
341
+ if (!files.length) {
342
+ throw new Error("No file data available. Please pick a file first.");
343
+ }
344
+ const targetIndex = Number(index);
345
+ const fileEntry = files[targetIndex];
346
+ if (!fileEntry) {
347
+ throw new Error(`No file data available at index ${targetIndex}.`);
348
+ }
349
+ if (fileObjectCache.current.has(targetIndex)) {
350
+ console.log("📁 Returning cached File object", {
351
+ index: targetIndex
352
+ });
353
+ return fileObjectCache.current.get(targetIndex);
354
+ }
355
+ const {
356
+ fileSrc,
357
+ fileName,
358
+ mimeType,
359
+ transport
360
+ } = fileEntry;
361
+ if (!(0, _FileObjectConverter.canCreateFileObject)(transport)) {
362
+ const errorMessage = (0, _FileObjectConverter.getUnsupportedTransportMessage)(transport);
363
+ console.error("❌", errorMessage);
364
+ throw new Error(errorMessage);
365
+ }
366
+ console.log("📁 Converting to File object", {
367
+ index: targetIndex,
368
+ transport,
369
+ fileName,
370
+ mimeType
371
+ });
372
+ try {
373
+ let fileObject;
374
+ if (transport === "BRIDGE_BASE64") {
375
+ fileObject = (0, _FileObjectConverter.base64ToFile)(fileSrc, fileName, mimeType);
376
+ } else if (transport === "FRAMEWORK_SERVER") {
377
+ fileObject = await (0, _FileObjectConverter.urlToFile)(fileSrc, fileName, mimeType);
378
+ }
379
+ fileObjectCache.current.set(targetIndex, fileObject);
380
+ console.log("✅ File object created successfully", {
381
+ index: targetIndex,
382
+ name: fileObject.name,
383
+ size: fileObject.size,
384
+ type: fileObject.type
385
+ });
386
+ return fileObject;
387
+ } catch (error) {
388
+ console.error("❌ Failed to create File object:", error);
389
+ throw new Error(`Failed to create File object: ${error.message}`);
390
+ }
391
+ }, [files]);
392
+ const getAllFileObjects = (0, _react.useCallback)(async () => {
393
+ if (!files.length) {
394
+ throw new Error("No file data available. Please pick a file first.");
395
+ }
396
+ return Promise.all(files.map((_, index) => getFileObject(index)));
397
+ }, [files, getFileObject]);
398
+ const canCreateFileObjectForCurrentFile = (0, _react.useMemo)(() => files.length > 0 ? (0, _FileObjectConverter.canCreateFileObject)(files[0].transport) : false, [files]);
399
+ const canCreateFileObjectsList = (0, _react.useMemo)(() => files.map(file => (0, _FileObjectConverter.canCreateFileObject)(file.transport)), [files]);
400
+ const clear = (0, _react.useCallback)(() => {
401
+ fileObjectCache.current.clear();
402
+ baseClear();
403
+ }, [baseClear]);
404
+ return {
405
+ data,
406
+ loading,
407
+ progress,
408
+ error,
409
+ isWeb,
410
+ isNative,
411
+ webFallbackActive: false,
412
+ webFallbackDisabled: false,
413
+ setWebFallback,
414
+ execute: pickFile,
415
+ clear,
416
+ clearError,
417
+ getFileObject,
418
+ getAllFileObjects,
419
+ canCreateFileObject: canCreateFileObjectForCurrentFile,
420
+ canCreateFileObjects: canCreateFileObjectsList,
421
+ selectedFile: files[0] || null,
422
+ selectedFiles: files,
423
+ pickFile,
424
+ isLoading: loading,
425
+ processingState: progress?.phase || null,
426
+ clearFile: clear
427
+ };
428
+ };
429
+ exports.useFilePicker = useFilePicker;
@@ -1 +1,81 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.useGoogleSignIn=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 _errors=require("../errors.js");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e};}/* eslint-disable react-compiler/react-compiler, react-hooks/exhaustive-deps */const useGoogleSignIn=(defaultOptions={})=>{const base=(0,_useBaseHook.useBaseHook)("useGoogleSignIn");if(typeof window==="undefined"){return{data:null,loading:false,error:null,progress:null,isWeb:true,isNative:false,signIn:()=>{},execute:()=>{},clear:()=>{},clearError:()=>{}};}if(!window.WebBridge){throw new Error("WebBridge is not initialized. Call WebBridge.init() first.");}(0,_react.useEffect)(()=>{const handleSuccess=payload=>{try{const parsed=typeof payload==="string"?JSON.parse(payload):payload;base.setDataAndComplete(parsed);}catch(err){base.handleNativeError(err);}};const handleError=nativeError=>{base.handleNativeError(nativeError);};const handleCancelled=()=>{const error=(0,_errors.createStandardError)(_errors.ERROR_CODES.OPERATION_CANCELLED,"Google sign-in cancelled",null,"User dismissed Google sign-in");base.handleNativeError(error);};window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_SUCCESS,handleSuccess);window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_ERROR,handleError);window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_CANCELLED,handleCancelled);return()=>{window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_SUCCESS);window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_ERROR);window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_CANCELLED);};},[base]);const signIn=(0,_react.useCallback)((options={})=>{base.executeOperation(()=>{const payload={...defaultOptions,...options};_NativeBridge.default.auth.googleSignIn(payload);},"google sign-in");},[base,defaultOptions]);return{data:base.data,loading:base.loading,progress:base.progress,error:base.error,isWeb:base.isWeb,isNative:base.isNative,signIn,execute:signIn,clear:base.clear,clearError:base.clearError};};exports.useGoogleSignIn=useGoogleSignIn;
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useGoogleSignIn = 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 _errors = require("../errors.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 useGoogleSignIn = (defaultOptions = {}) => {
16
+ const base = (0, _useBaseHook.useBaseHook)("useGoogleSignIn");
17
+ if (typeof window === "undefined") {
18
+ return {
19
+ data: null,
20
+ loading: false,
21
+ error: null,
22
+ progress: null,
23
+ isWeb: true,
24
+ isNative: false,
25
+ signIn: () => {},
26
+ execute: () => {},
27
+ clear: () => {},
28
+ clearError: () => {}
29
+ };
30
+ }
31
+ if (!window.WebBridge) {
32
+ throw new Error("WebBridge is not initialized. Call WebBridge.init() first.");
33
+ }
34
+ (0, _react.useEffect)(() => {
35
+ const handleSuccess = payload => {
36
+ try {
37
+ const parsed = typeof payload === "string" ? JSON.parse(payload) : payload;
38
+ base.setDataAndComplete(parsed);
39
+ } catch (err) {
40
+ base.handleNativeError(err);
41
+ }
42
+ };
43
+ const handleError = nativeError => {
44
+ base.handleNativeError(nativeError);
45
+ };
46
+ const handleCancelled = () => {
47
+ const error = (0, _errors.createStandardError)(_errors.ERROR_CODES.OPERATION_CANCELLED, "Google sign-in cancelled", null, "User dismissed Google sign-in");
48
+ base.handleNativeError(error);
49
+ };
50
+ window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_SUCCESS, handleSuccess);
51
+ window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_ERROR, handleError);
52
+ window.WebBridge.register(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_CANCELLED, handleCancelled);
53
+ return () => {
54
+ window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_SUCCESS);
55
+ window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_ERROR);
56
+ window.WebBridge.unregister(_NativeInterfaces.NATIVE_CALLBACKS.ON_GOOGLE_SIGN_IN_CANCELLED);
57
+ };
58
+ }, [base]);
59
+ const signIn = (0, _react.useCallback)((options = {}) => {
60
+ base.executeOperation(() => {
61
+ const payload = {
62
+ ...defaultOptions,
63
+ ...options
64
+ };
65
+ _NativeBridge.default.auth.googleSignIn(payload);
66
+ }, "google sign-in");
67
+ }, [base, defaultOptions]);
68
+ return {
69
+ data: base.data,
70
+ loading: base.loading,
71
+ progress: base.progress,
72
+ error: base.error,
73
+ isWeb: base.isWeb,
74
+ isNative: base.isNative,
75
+ signIn,
76
+ execute: signIn,
77
+ clear: base.clear,
78
+ clearError: base.clearError
79
+ };
80
+ };
81
+ exports.useGoogleSignIn = useGoogleSignIn;