@uploadista/react-native-core 0.0.20-beta.1 → 0.0.20-beta.3

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.
@@ -6,6 +6,7 @@ export {
6
6
  export { useCameraUpload } from "./use-camera-upload";
7
7
  export { useFileUpload } from "./use-file-upload";
8
8
  // Flow hooks
9
+ // useFlow is the primary hook for flow operations (replaces useFlowUpload)
9
10
  export type {
10
11
  FlowInputMetadata,
11
12
  FlowUploadState,
@@ -15,7 +16,6 @@ export type {
15
16
  UseFlowReturn,
16
17
  } from "./use-flow";
17
18
  export { useFlow } from "./use-flow";
18
- export { useFlowUpload } from "./use-flow-upload";
19
19
  export { useGalleryUpload } from "./use-gallery-upload";
20
20
  // Multi-upload hooks
21
21
  export type {
package/src/index.ts CHANGED
@@ -46,21 +46,26 @@ export {
46
46
  useFlowManagerContext,
47
47
  } from "./contexts/flow-manager-context";
48
48
  // Export hooks
49
+ // useFlow is the primary hook for flow operations (replaces useFlowUpload)
49
50
  export {
50
51
  UploadistaContext,
51
52
  type UploadistaContextType,
52
53
  useCameraUpload,
53
54
  useFileUpload,
54
- useFlowUpload,
55
+ useFlow,
55
56
  useGalleryUpload,
56
57
  useMultiUpload,
57
58
  useUploadistaContext,
58
59
  useUploadMetrics,
59
60
  } from "./hooks";
60
61
  export type {
62
+ FlowInputMetadata,
61
63
  FlowUploadState,
62
64
  FlowUploadStatus,
63
- } from "./hooks/use-flow-upload";
65
+ InputExecutionState,
66
+ UseFlowOptions,
67
+ UseFlowReturn,
68
+ } from "./hooks/use-flow";
64
69
  export type {
65
70
  MultiUploadState,
66
71
  UploadItemState,
@@ -80,7 +85,6 @@ export type {
80
85
  UploadMetrics,
81
86
  UseCameraUploadOptions,
82
87
  UseFileUploadOptions,
83
- UseFlowUploadOptions,
84
88
  UseGalleryUploadOptions,
85
89
  UseMultiUploadOptions,
86
90
  } from "./types";
@@ -1,223 +0,0 @@
1
- import type {
2
- FlowManager,
3
- FlowUploadState,
4
- FlowUploadStatus,
5
- } from "@uploadista/client-core";
6
- import type { TypedOutput } from "@uploadista/core/flow";
7
- import { useCallback, useEffect, useRef, useState } from "react";
8
- import { useFlowManagerContext } from "../contexts/flow-manager-context";
9
- import type { FilePickResult, UseFlowUploadOptions } from "../types";
10
- import { createBlobFromBuffer } from "../types/platform-types";
11
- import { useUploadistaContext } from "./use-uploadista-context";
12
-
13
- // Re-export types from core for convenience
14
- export type { FlowUploadState, FlowUploadStatus };
15
-
16
- const initialState: FlowUploadState = {
17
- status: "idle",
18
- progress: 0,
19
- bytesUploaded: 0,
20
- totalBytes: null,
21
- error: null,
22
- jobId: null,
23
- flowStarted: false,
24
- currentNodeName: null,
25
- currentNodeType: null,
26
- flowOutputs: null,
27
- };
28
-
29
- /**
30
- * Hook for uploading files through a flow pipeline with full state management.
31
- * Provides upload progress tracking, flow execution monitoring, error handling, and abort functionality.
32
- *
33
- * Must be used within FlowManagerProvider (which must be within UploadistaProvider).
34
- * Flow events are automatically routed by the provider to the appropriate manager.
35
- *
36
- * @param options - Flow upload configuration
37
- * @returns Flow upload state and control methods
38
- *
39
- * @example
40
- * ```tsx
41
- * function MyComponent() {
42
- * const flowUpload = useFlowUpload({
43
- * flowId: 'image-processing-flow',
44
- * storageId: 'my-storage',
45
- * onSuccess: (result) => console.log('Flow complete:', result),
46
- * onError: (error) => console.error('Flow failed:', error),
47
- * onProgress: (progress) => console.log('Progress:', progress + '%'),
48
- * });
49
- *
50
- * const handlePickFile = async () => {
51
- * const file = await fileSystemProvider.pickDocument();
52
- * if (file) {
53
- * await flowUpload.upload(file);
54
- * }
55
- * };
56
- *
57
- * return (
58
- * <View>
59
- * <Button title="Pick File" onPress={handlePickFile} />
60
- * {flowUpload.isUploading && <Text>Progress: {flowUpload.state.progress}%</Text>}
61
- * {flowUpload.state.jobId && <Text>Job ID: {flowUpload.state.jobId}</Text>}
62
- * {flowUpload.state.error && <Text>Error: {flowUpload.state.error.message}</Text>}
63
- * <Button title="Abort" onPress={flowUpload.abort} disabled={!flowUpload.isActive} />
64
- * </View>
65
- * );
66
- * }
67
- * ```
68
- */
69
- export function useFlowUpload(options: UseFlowUploadOptions) {
70
- const { getManager, releaseManager } = useFlowManagerContext();
71
- const { fileSystemProvider } = useUploadistaContext();
72
- const [state, setState] = useState<FlowUploadState>(initialState);
73
- const managerRef = useRef<FlowManager<unknown> | null>(null);
74
- const lastFileRef = useRef<FilePickResult | null>(null);
75
-
76
- // Store callbacks in refs so they can be updated without recreating the manager
77
- const callbacksRef = useRef(options);
78
-
79
- // Update refs on every render to capture latest callbacks
80
- useEffect(() => {
81
- callbacksRef.current = options;
82
- });
83
-
84
- // Get or create manager from context when component mounts
85
- // Manager lifecycle is now handled by FlowManagerProvider
86
- useEffect(() => {
87
- const flowId = options.flowId;
88
-
89
- // Create stable callback wrappers that call the latest callbacks via refs
90
- const stableCallbacks = {
91
- onStateChange: setState,
92
- onProgress: (
93
- _uploadId: string,
94
- bytesUploaded: number,
95
- totalBytes: number | null,
96
- ) => {
97
- if (callbacksRef.current.onProgress) {
98
- const progress = totalBytes
99
- ? Math.round((bytesUploaded / totalBytes) * 100)
100
- : 0;
101
- callbacksRef.current.onProgress(progress, bytesUploaded, totalBytes);
102
- }
103
- },
104
- onChunkComplete: (
105
- chunkSize: number,
106
- bytesAccepted: number,
107
- bytesTotal: number | null,
108
- ) => {
109
- callbacksRef.current.onChunkComplete?.(
110
- chunkSize,
111
- bytesAccepted,
112
- bytesTotal,
113
- );
114
- },
115
- onFlowComplete: (outputs: TypedOutput[]) => {
116
- callbacksRef.current.onFlowComplete?.(outputs);
117
- },
118
- onSuccess: (outputs: TypedOutput[]) => {
119
- callbacksRef.current.onSuccess?.(outputs);
120
- },
121
- onError: (error: Error) => {
122
- callbacksRef.current.onError?.(error);
123
- },
124
- onAbort: () => {
125
- // onAbort is not exposed in the public API
126
- },
127
- };
128
-
129
- // Get manager from context (creates if doesn't exist, increments ref count)
130
- managerRef.current = getManager(flowId, stableCallbacks, {
131
- flowConfig: {
132
- flowId: options.flowId,
133
- storageId: options.storageId,
134
- outputNodeId: options.outputNodeId,
135
- metadata: options.metadata as Record<string, string> | undefined,
136
- },
137
- onChunkComplete: options.onChunkComplete,
138
- onSuccess: options.onSuccess,
139
- onError: options.onError,
140
- });
141
-
142
- // Release manager when component unmounts or flowId changes
143
- return () => {
144
- releaseManager(flowId);
145
- managerRef.current = null;
146
- };
147
- }, [
148
- options.flowId,
149
- options.storageId,
150
- options.outputNodeId,
151
- getManager,
152
- releaseManager,
153
- ]);
154
-
155
- const upload = useCallback(
156
- async (file: FilePickResult) => {
157
- // Handle cancelled picker
158
- if (file.status === "cancelled") {
159
- return;
160
- }
161
-
162
- // Handle picker error
163
- if (file.status === "error") {
164
- options.onError?.(file.error);
165
- return;
166
- }
167
-
168
- lastFileRef.current = file;
169
-
170
- try {
171
- // Read file content
172
- const fileContent = await fileSystemProvider.readFile(file.data.uri);
173
-
174
- // Create a Blob from the file content using platform-aware utility
175
- // Handles differences between React Native and browser Blob APIs
176
- const blob = createBlobFromBuffer(fileContent, {
177
- type: file.data.mimeType || "application/octet-stream",
178
- });
179
-
180
- // Start the upload using the manager
181
- await managerRef.current?.upload(blob);
182
- } catch (error) {
183
- options.onError?.(error as Error);
184
- }
185
- },
186
- [fileSystemProvider, options],
187
- );
188
-
189
- const reset = useCallback(() => {
190
- managerRef.current?.reset();
191
- lastFileRef.current = null;
192
- }, []);
193
-
194
- const abort = useCallback(() => {
195
- managerRef.current?.abort();
196
- }, []);
197
-
198
- const retry = useCallback(() => {
199
- if (
200
- lastFileRef.current &&
201
- (state.status === "error" || state.status === "aborted")
202
- ) {
203
- upload(lastFileRef.current);
204
- }
205
- }, [upload, state.status]);
206
-
207
- // Derive computed values from state (reactive to state changes)
208
- const isActive =
209
- state.status === "uploading" || state.status === "processing";
210
- const canRetry =
211
- (state.status === "error" || state.status === "aborted") &&
212
- lastFileRef.current !== null;
213
-
214
- return {
215
- state,
216
- upload,
217
- abort,
218
- reset,
219
- retry,
220
- isActive,
221
- canRetry,
222
- };
223
- }