@uploadista/react 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.
- package/dist/components/index.d.mts +3 -3
- package/dist/components/index.mjs +1 -1
- package/dist/flow-upload-list-SbpCaxRq.mjs +2 -0
- package/dist/flow-upload-list-SbpCaxRq.mjs.map +1 -0
- package/dist/hooks/index.d.mts +3 -3
- package/dist/hooks/index.mjs +1 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +1 -1
- package/dist/{uploadista-provider-CM48PPSp.d.mts → uploadista-provider-C1l0iBc9.d.mts} +503 -309
- package/dist/uploadista-provider-C1l0iBc9.d.mts.map +1 -0
- package/dist/use-upload-BvvGROMR.mjs +2 -0
- package/dist/use-upload-BvvGROMR.mjs.map +1 -0
- package/dist/{use-uploadista-client-m9nF-irM.d.mts → use-uploadista-client-DHbLSpIb.d.mts} +120 -286
- package/dist/use-uploadista-client-DHbLSpIb.d.mts.map +1 -0
- package/dist/use-uploadista-events-BwUD-2Ck.mjs +2 -0
- package/dist/use-uploadista-events-BwUD-2Ck.mjs.map +1 -0
- package/dist/{use-upload-metrics-DhzS4lhG.d.mts → use-uploadista-events-CtDXJYrR.d.mts} +169 -371
- package/dist/use-uploadista-events-CtDXJYrR.d.mts.map +1 -0
- package/package.json +6 -6
- package/src/components/flow-primitives.tsx +839 -0
- package/src/components/index.tsx +31 -13
- package/src/hooks/index.ts +25 -37
- package/src/index.ts +90 -81
- package/dist/upload-zone-BjWHuP7p.mjs +0 -6
- package/dist/upload-zone-BjWHuP7p.mjs.map +0 -1
- package/dist/uploadista-provider-CM48PPSp.d.mts.map +0 -1
- package/dist/use-upload-BDHVhQsI.mjs +0 -2
- package/dist/use-upload-BDHVhQsI.mjs.map +0 -1
- package/dist/use-upload-metrics-Df90wIos.mjs +0 -2
- package/dist/use-upload-metrics-Df90wIos.mjs.map +0 -1
- package/dist/use-upload-metrics-DhzS4lhG.d.mts.map +0 -1
- package/dist/use-uploadista-client-m9nF-irM.d.mts.map +0 -1
- package/src/components/flow-input.tsx +0 -299
- package/src/components/flow-upload-zone.tsx +0 -441
- package/src/hooks/use-flow-execution.ts +0 -502
- package/src/hooks/use-flow-upload.ts +0 -299
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
import type { FlowUploadOptions } from "@uploadista/client-browser";
|
|
2
|
-
import type {
|
|
3
|
-
FlowManager,
|
|
4
|
-
FlowUploadState,
|
|
5
|
-
FlowUploadStatus,
|
|
6
|
-
} from "@uploadista/client-core";
|
|
7
|
-
import type { TypedOutput } from "@uploadista/core/flow";
|
|
8
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
9
|
-
import { useFlowManagerContext } from "../contexts/flow-manager-context";
|
|
10
|
-
|
|
11
|
-
// Re-export types from core for convenience
|
|
12
|
-
export type { FlowUploadState, FlowUploadStatus };
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Return value from the useFlowUpload hook with upload control methods and state.
|
|
16
|
-
*
|
|
17
|
-
* @property state - Complete flow upload state with progress and outputs
|
|
18
|
-
* @property upload - Function to initiate file upload through the flow
|
|
19
|
-
* @property abort - Cancel the current upload and flow execution
|
|
20
|
-
* @property pause - Pause the current upload
|
|
21
|
-
* @property reset - Reset state to idle (clears all data)
|
|
22
|
-
* @property isUploading - True when upload or processing is active
|
|
23
|
-
* @property isUploadingFile - True only during file upload phase
|
|
24
|
-
* @property isProcessing - True only during flow processing phase
|
|
25
|
-
*/
|
|
26
|
-
export interface UseFlowUploadReturn {
|
|
27
|
-
/**
|
|
28
|
-
* Current upload state
|
|
29
|
-
*/
|
|
30
|
-
state: FlowUploadState;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Upload a file through the flow
|
|
34
|
-
*/
|
|
35
|
-
upload: (file: File | Blob) => Promise<void>;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Abort the current upload
|
|
39
|
-
*/
|
|
40
|
-
abort: () => void;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Pause the current upload
|
|
44
|
-
*/
|
|
45
|
-
pause: () => void;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Reset the upload state
|
|
49
|
-
*/
|
|
50
|
-
reset: () => void;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Whether an upload or flow execution is in progress (uploading OR processing)
|
|
54
|
-
*/
|
|
55
|
-
isUploading: boolean;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Whether the file is currently being uploaded (chunks being sent)
|
|
59
|
-
*/
|
|
60
|
-
isUploadingFile: boolean;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Whether the flow is currently processing (after upload completes)
|
|
64
|
-
*/
|
|
65
|
-
isProcessing: boolean;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const initialState: FlowUploadState = {
|
|
69
|
-
status: "idle",
|
|
70
|
-
progress: 0,
|
|
71
|
-
bytesUploaded: 0,
|
|
72
|
-
totalBytes: null,
|
|
73
|
-
error: null,
|
|
74
|
-
jobId: null,
|
|
75
|
-
flowStarted: false,
|
|
76
|
-
currentNodeName: null,
|
|
77
|
-
currentNodeType: null,
|
|
78
|
-
flowOutputs: null,
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* React hook for uploading files through a flow with automatic flow execution.
|
|
83
|
-
* Handles both the file upload phase and the flow processing phase, providing
|
|
84
|
-
* real-time progress updates and flow node execution tracking.
|
|
85
|
-
*
|
|
86
|
-
* This is a convenience wrapper around the generic useFlowExecution hook,
|
|
87
|
-
* specialized for the common case of file uploads. For more flexible input types
|
|
88
|
-
* (URLs, structured data), use useFlowExecution directly with an inputBuilder.
|
|
89
|
-
*
|
|
90
|
-
* The flow engine processes the uploaded file through a DAG of nodes, which can
|
|
91
|
-
* perform operations like image optimization, storage saving, webhooks, etc.
|
|
92
|
-
*
|
|
93
|
-
* Must be used within FlowManagerProvider (which must be within UploadistaProvider).
|
|
94
|
-
* Flow events are automatically routed by the provider to the appropriate manager.
|
|
95
|
-
*
|
|
96
|
-
* @param options - Flow upload configuration including flow ID and event handlers
|
|
97
|
-
* @returns Flow upload state and control methods
|
|
98
|
-
*
|
|
99
|
-
* @remarks
|
|
100
|
-
* **Future refactoring**: This hook could be implemented as a thin wrapper around
|
|
101
|
-
* useFlowExecution with a file-specific inputBuilder:
|
|
102
|
-
* ```typescript
|
|
103
|
-
* return useFlowExecution<File | Blob>({
|
|
104
|
-
* ...options,
|
|
105
|
-
* inputBuilder: async (file) => {
|
|
106
|
-
* const { inputNodes } = await client.findInputNode(options.flowConfig.flowId);
|
|
107
|
-
* return {
|
|
108
|
-
* [inputNodes[0].id]: {
|
|
109
|
-
* operation: "init",
|
|
110
|
-
* storageId: options.flowConfig.storageId,
|
|
111
|
-
* metadata: { originalName: file.name, mimeType: file.type, size: file.size }
|
|
112
|
-
* }
|
|
113
|
-
* };
|
|
114
|
-
* }
|
|
115
|
-
* });
|
|
116
|
-
* ```
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* ```tsx
|
|
120
|
-
* // Basic flow upload with progress tracking
|
|
121
|
-
* function ImageUploader() {
|
|
122
|
-
* const flowUpload = useFlowUpload({
|
|
123
|
-
* flowConfig: {
|
|
124
|
-
* flowId: "image-optimization-flow",
|
|
125
|
-
* storageId: "s3-images",
|
|
126
|
-
* },
|
|
127
|
-
* onSuccess: (outputs) => {
|
|
128
|
-
* console.log("Flow outputs:", outputs);
|
|
129
|
-
* // Access all outputs from the flow
|
|
130
|
-
* for (const output of outputs) {
|
|
131
|
-
* console.log(`${output.nodeId}:`, output.data);
|
|
132
|
-
* }
|
|
133
|
-
* },
|
|
134
|
-
* onFlowComplete: (outputs) => {
|
|
135
|
-
* console.log("All flow outputs:", outputs);
|
|
136
|
-
* },
|
|
137
|
-
* onError: (error) => {
|
|
138
|
-
* console.error("Upload or processing failed:", error);
|
|
139
|
-
* },
|
|
140
|
-
* });
|
|
141
|
-
*
|
|
142
|
-
* return (
|
|
143
|
-
* <div>
|
|
144
|
-
* <input
|
|
145
|
-
* type="file"
|
|
146
|
-
* accept="image/*"
|
|
147
|
-
* onChange={(e) => {
|
|
148
|
-
* const file = e.target.files?.[0];
|
|
149
|
-
* if (file) flowUpload.upload(file);
|
|
150
|
-
* }}
|
|
151
|
-
* />
|
|
152
|
-
*
|
|
153
|
-
* {flowUpload.isUploadingFile && (
|
|
154
|
-
* <div>Uploading... {flowUpload.state.progress}%</div>
|
|
155
|
-
* )}
|
|
156
|
-
*
|
|
157
|
-
* {flowUpload.isProcessing && (
|
|
158
|
-
* <div>
|
|
159
|
-
* Processing...
|
|
160
|
-
* {flowUpload.state.currentNodeName && (
|
|
161
|
-
* <span>Current step: {flowUpload.state.currentNodeName}</span>
|
|
162
|
-
* )}
|
|
163
|
-
* </div>
|
|
164
|
-
* )}
|
|
165
|
-
*
|
|
166
|
-
* {flowUpload.state.status === "success" && (
|
|
167
|
-
* <div>
|
|
168
|
-
* <p>Upload complete!</p>
|
|
169
|
-
* {flowUpload.state.flowOutputs && (
|
|
170
|
-
* <div>
|
|
171
|
-
* {flowUpload.state.flowOutputs.map((output) => (
|
|
172
|
-
* <div key={output.nodeId}>{output.nodeId}: {JSON.stringify(output.data)}</div>
|
|
173
|
-
* ))}
|
|
174
|
-
* </div>
|
|
175
|
-
* )}
|
|
176
|
-
* </div>
|
|
177
|
-
* )}
|
|
178
|
-
*
|
|
179
|
-
* {flowUpload.state.status === "error" && (
|
|
180
|
-
* <div>
|
|
181
|
-
* <p>Error: {flowUpload.state.error?.message}</p>
|
|
182
|
-
* <button onClick={flowUpload.reset}>Try Again</button>
|
|
183
|
-
* </div>
|
|
184
|
-
* )}
|
|
185
|
-
*
|
|
186
|
-
* {flowUpload.isUploading && (
|
|
187
|
-
* <button onClick={flowUpload.abort}>Cancel</button>
|
|
188
|
-
* )}
|
|
189
|
-
* </div>
|
|
190
|
-
* );
|
|
191
|
-
* }
|
|
192
|
-
* ```
|
|
193
|
-
*
|
|
194
|
-
* @see {@link useMultiFlowUpload} for uploading multiple files through a flow
|
|
195
|
-
* @see {@link useUpload} for simple uploads without flow processing
|
|
196
|
-
*/
|
|
197
|
-
export function useFlowUpload(options: FlowUploadOptions): UseFlowUploadReturn {
|
|
198
|
-
const { getManager, releaseManager } = useFlowManagerContext();
|
|
199
|
-
const [state, setState] = useState<FlowUploadState>(initialState);
|
|
200
|
-
const managerRef = useRef<FlowManager<unknown> | null>(null);
|
|
201
|
-
|
|
202
|
-
// Store callbacks in refs so they can be updated without recreating the manager
|
|
203
|
-
const callbacksRef = useRef(options);
|
|
204
|
-
|
|
205
|
-
// Update refs on every render to capture latest callbacks
|
|
206
|
-
useEffect(() => {
|
|
207
|
-
callbacksRef.current = options;
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
// Get or create manager from context when component mounts
|
|
211
|
-
// Manager lifecycle is now handled by FlowManagerProvider
|
|
212
|
-
useEffect(() => {
|
|
213
|
-
const flowId = options.flowConfig.flowId;
|
|
214
|
-
|
|
215
|
-
// Create stable callback wrappers that call the latest callbacks via refs
|
|
216
|
-
const stableCallbacks = {
|
|
217
|
-
onStateChange: setState,
|
|
218
|
-
onProgress: (
|
|
219
|
-
uploadId: string,
|
|
220
|
-
bytesUploaded: number,
|
|
221
|
-
totalBytes: number | null,
|
|
222
|
-
) => {
|
|
223
|
-
callbacksRef.current.onProgress?.(uploadId, bytesUploaded, totalBytes);
|
|
224
|
-
},
|
|
225
|
-
onChunkComplete: (
|
|
226
|
-
chunkSize: number,
|
|
227
|
-
bytesAccepted: number,
|
|
228
|
-
bytesTotal: number | null,
|
|
229
|
-
) => {
|
|
230
|
-
callbacksRef.current.onChunkComplete?.(
|
|
231
|
-
chunkSize,
|
|
232
|
-
bytesAccepted,
|
|
233
|
-
bytesTotal,
|
|
234
|
-
);
|
|
235
|
-
},
|
|
236
|
-
onFlowComplete: (outputs: TypedOutput[]) => {
|
|
237
|
-
callbacksRef.current.onFlowComplete?.(outputs);
|
|
238
|
-
},
|
|
239
|
-
onSuccess: (outputs: TypedOutput[]) => {
|
|
240
|
-
callbacksRef.current.onSuccess?.(outputs);
|
|
241
|
-
},
|
|
242
|
-
onError: (error: Error) => {
|
|
243
|
-
callbacksRef.current.onError?.(error);
|
|
244
|
-
},
|
|
245
|
-
onAbort: () => {
|
|
246
|
-
callbacksRef.current.onAbort?.();
|
|
247
|
-
},
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
// Get manager from context (creates if doesn't exist, increments ref count)
|
|
251
|
-
managerRef.current = getManager(flowId, stableCallbacks, options);
|
|
252
|
-
|
|
253
|
-
// Release manager when component unmounts or flowId changes
|
|
254
|
-
return () => {
|
|
255
|
-
releaseManager(flowId);
|
|
256
|
-
managerRef.current = null;
|
|
257
|
-
};
|
|
258
|
-
}, [
|
|
259
|
-
options.flowConfig.flowId,
|
|
260
|
-
options.flowConfig.storageId,
|
|
261
|
-
options.flowConfig.outputNodeId,
|
|
262
|
-
getManager,
|
|
263
|
-
releaseManager,
|
|
264
|
-
]);
|
|
265
|
-
|
|
266
|
-
// Wrap manager methods with useCallback
|
|
267
|
-
const upload = useCallback(async (file: File | Blob) => {
|
|
268
|
-
await managerRef.current?.upload(file);
|
|
269
|
-
}, []);
|
|
270
|
-
|
|
271
|
-
const abort = useCallback(() => {
|
|
272
|
-
managerRef.current?.abort();
|
|
273
|
-
}, []);
|
|
274
|
-
|
|
275
|
-
const pause = useCallback(() => {
|
|
276
|
-
managerRef.current?.pause();
|
|
277
|
-
}, []);
|
|
278
|
-
|
|
279
|
-
const reset = useCallback(() => {
|
|
280
|
-
managerRef.current?.reset();
|
|
281
|
-
}, []);
|
|
282
|
-
|
|
283
|
-
// Derive computed values from state (reactive to state changes)
|
|
284
|
-
const isUploading =
|
|
285
|
-
state.status === "uploading" || state.status === "processing";
|
|
286
|
-
const isUploadingFile = state.status === "uploading";
|
|
287
|
-
const isProcessing = state.status === "processing";
|
|
288
|
-
|
|
289
|
-
return {
|
|
290
|
-
state,
|
|
291
|
-
upload,
|
|
292
|
-
abort,
|
|
293
|
-
pause,
|
|
294
|
-
reset,
|
|
295
|
-
isUploading,
|
|
296
|
-
isUploadingFile,
|
|
297
|
-
isProcessing,
|
|
298
|
-
};
|
|
299
|
-
}
|