@uploadista/react 0.0.20-beta.2 → 0.0.20-beta.4
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-D6j8JSP8.mjs +2 -0
- package/dist/flow-upload-list-D6j8JSP8.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-D-N-eL2l.d.mts → uploadista-provider-Cb13AK7Z.d.mts} +515 -318
- package/dist/uploadista-provider-Cb13AK7Z.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-CkzVVmFT.d.mts} +121 -286
- package/dist/use-uploadista-client-CkzVVmFT.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 +843 -0
- package/src/components/index.tsx +31 -13
- package/src/hooks/index.ts +25 -37
- package/src/hooks/use-drag-drop.ts +1 -0
- 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-D-N-eL2l.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,502 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic React hook for flexible flow execution with arbitrary input types.
|
|
3
|
-
*
|
|
4
|
-
* This hook provides a flexible interface for executing flows with different input types:
|
|
5
|
-
* - File/Blob: Traditional chunked file upload
|
|
6
|
-
* - string (URL): Direct file fetch from external URL
|
|
7
|
-
* - object: Structured data for custom input nodes
|
|
8
|
-
*
|
|
9
|
-
* The hook uses an inputBuilder pattern to transform trigger data into flow inputs,
|
|
10
|
-
* enabling dynamic input preparation and validation before flow execution.
|
|
11
|
-
*
|
|
12
|
-
* @module hooks/use-flow-execution
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```tsx
|
|
16
|
-
* // URL-based flow execution
|
|
17
|
-
* function UrlImageProcessor() {
|
|
18
|
-
* const execution = useFlowExecution<string>({
|
|
19
|
-
* flowConfig: {
|
|
20
|
-
* flowId: "image-optimize",
|
|
21
|
-
* storageId: "s3"
|
|
22
|
-
* },
|
|
23
|
-
* inputBuilder: async (url) => {
|
|
24
|
-
* // Find the input node
|
|
25
|
-
* const { inputNodes, single } = await client.findInputNode("image-optimize");
|
|
26
|
-
* if (!single) throw new Error("Expected single input node");
|
|
27
|
-
*
|
|
28
|
-
* return {
|
|
29
|
-
* [inputNodes[0].id]: {
|
|
30
|
-
* operation: "url",
|
|
31
|
-
* url,
|
|
32
|
-
* metadata: { source: "external" }
|
|
33
|
-
* }
|
|
34
|
-
* };
|
|
35
|
-
* },
|
|
36
|
-
* onSuccess: (outputs) => console.log("Done:", outputs)
|
|
37
|
-
* });
|
|
38
|
-
*
|
|
39
|
-
* return (
|
|
40
|
-
* <button onClick={() => execution.execute("https://example.com/image.jpg")}>
|
|
41
|
-
* Process URL
|
|
42
|
-
* </button>
|
|
43
|
-
* );
|
|
44
|
-
* }
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
import type { FlowUploadOptions } from "@uploadista/client-browser";
|
|
49
|
-
import type {
|
|
50
|
-
FlowInputs,
|
|
51
|
-
FlowManager,
|
|
52
|
-
FlowUploadState,
|
|
53
|
-
FlowUploadStatus,
|
|
54
|
-
} from "@uploadista/client-core";
|
|
55
|
-
import type { TypedOutput } from "@uploadista/core/flow";
|
|
56
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
57
|
-
import { useUploadistaContext } from "../components/uploadista-provider";
|
|
58
|
-
import { useFlowManagerContext } from "../contexts/flow-manager-context";
|
|
59
|
-
|
|
60
|
-
// Re-export types for convenience
|
|
61
|
-
export type { FlowUploadState, FlowUploadStatus };
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Input builder function that transforms trigger data into flow inputs.
|
|
65
|
-
*
|
|
66
|
-
* The builder receives the trigger data passed to execute() and returns
|
|
67
|
-
* a FlowInputs object mapping node IDs to their input data.
|
|
68
|
-
*
|
|
69
|
-
* @template TTrigger - The type of data passed to execute()
|
|
70
|
-
* @param trigger - The trigger data (e.g., File, URL string, structured data)
|
|
71
|
-
* @returns Promise resolving to FlowInputs mapping or the mapping directly
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* ```typescript
|
|
75
|
-
* // File upload builder
|
|
76
|
-
* const fileBuilder: InputBuilder<File> = async (file) => ({
|
|
77
|
-
* "input-node": {
|
|
78
|
-
* operation: "init",
|
|
79
|
-
* storageId: "s3",
|
|
80
|
-
* metadata: { originalName: file.name, size: file.size }
|
|
81
|
-
* }
|
|
82
|
-
* });
|
|
83
|
-
*
|
|
84
|
-
* // URL fetch builder
|
|
85
|
-
* const urlBuilder: InputBuilder<string> = (url) => ({
|
|
86
|
-
* "input-node": {
|
|
87
|
-
* operation: "url",
|
|
88
|
-
* url,
|
|
89
|
-
* metadata: { source: "external" }
|
|
90
|
-
* }
|
|
91
|
-
* });
|
|
92
|
-
* ```
|
|
93
|
-
*/
|
|
94
|
-
export type InputBuilder<TTrigger = unknown> = (
|
|
95
|
-
trigger: TTrigger,
|
|
96
|
-
) => Promise<FlowInputs> | FlowInputs;
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Options for the useFlowExecution hook.
|
|
100
|
-
*
|
|
101
|
-
* @template TTrigger - The type of trigger data passed to execute()
|
|
102
|
-
* @template TOutput - The expected output type from the flow
|
|
103
|
-
*
|
|
104
|
-
* @property flowConfig - Flow configuration (flowId, storageId, etc.)
|
|
105
|
-
* @property inputBuilder - Function to build flow inputs from trigger data
|
|
106
|
-
* @property onJobStart - Called when flow job is created
|
|
107
|
-
* @property onProgress - Called during upload progress (if applicable)
|
|
108
|
-
* @property onChunkComplete - Called when upload chunk completes (if applicable)
|
|
109
|
-
* @property onSuccess - Called with typed outputs when flow succeeds
|
|
110
|
-
* @property onFlowComplete - Called with all outputs when flow completes
|
|
111
|
-
* @property onError - Called when execution fails
|
|
112
|
-
* @property onAbort - Called when execution is aborted
|
|
113
|
-
* @property onShouldRetry - Custom retry logic (if applicable)
|
|
114
|
-
*/
|
|
115
|
-
export interface UseFlowExecutionOptions<
|
|
116
|
-
TTrigger = unknown,
|
|
117
|
-
TOutput = TypedOutput[],
|
|
118
|
-
> {
|
|
119
|
-
/**
|
|
120
|
-
* Flow configuration
|
|
121
|
-
*/
|
|
122
|
-
flowConfig: FlowUploadOptions["flowConfig"];
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Function to build flow inputs from trigger data.
|
|
126
|
-
* Can be async to perform validation, API calls, etc.
|
|
127
|
-
*/
|
|
128
|
-
inputBuilder: InputBuilder<TTrigger>;
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Called when the flow job starts
|
|
132
|
-
*/
|
|
133
|
-
onJobStart?: (jobId: string) => void;
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Called during upload progress (for file uploads)
|
|
137
|
-
*/
|
|
138
|
-
onProgress?: (
|
|
139
|
-
uploadId: string,
|
|
140
|
-
bytesUploaded: number,
|
|
141
|
-
totalBytes: number | null,
|
|
142
|
-
) => void;
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Called when an upload chunk completes (for file uploads)
|
|
146
|
-
*/
|
|
147
|
-
onChunkComplete?: (
|
|
148
|
-
chunkSize: number,
|
|
149
|
-
bytesAccepted: number,
|
|
150
|
-
bytesTotal: number | null,
|
|
151
|
-
) => void;
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Called when flow execution succeeds with final outputs
|
|
155
|
-
*/
|
|
156
|
-
onSuccess?: (outputs: TOutput) => void;
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Called when flow completes (alternative to onSuccess)
|
|
160
|
-
*/
|
|
161
|
-
onFlowComplete?: (outputs: TypedOutput[]) => void;
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Called when execution fails
|
|
165
|
-
*/
|
|
166
|
-
onError?: (error: Error) => void;
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Called when execution is aborted
|
|
170
|
-
*/
|
|
171
|
-
onAbort?: () => void;
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Custom retry logic (for file uploads)
|
|
175
|
-
*/
|
|
176
|
-
onShouldRetry?: (error: Error, retryAttempt: number) => boolean;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Return value from useFlowExecution hook.
|
|
181
|
-
*
|
|
182
|
-
* @template TTrigger - The type of trigger data passed to execute()
|
|
183
|
-
*
|
|
184
|
-
* @property state - Current execution state with progress and outputs
|
|
185
|
-
* @property execute - Function to trigger flow execution
|
|
186
|
-
* @property abort - Cancel the current execution
|
|
187
|
-
* @property pause - Pause the current execution (for file uploads)
|
|
188
|
-
* @property reset - Reset state to idle
|
|
189
|
-
* @property isExecuting - True when execution is active
|
|
190
|
-
* @property isUploadingFile - True during file upload phase
|
|
191
|
-
* @property isProcessing - True during flow processing phase
|
|
192
|
-
*/
|
|
193
|
-
export interface UseFlowExecutionReturn<TTrigger = unknown> {
|
|
194
|
-
/**
|
|
195
|
-
* Current execution state
|
|
196
|
-
*/
|
|
197
|
-
state: FlowUploadState;
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Execute the flow with trigger data
|
|
201
|
-
*/
|
|
202
|
-
execute: (trigger: TTrigger) => Promise<void>;
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Abort the current execution
|
|
206
|
-
*/
|
|
207
|
-
abort: () => void;
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Pause the current execution (if supported by input type)
|
|
211
|
-
*/
|
|
212
|
-
pause: () => void;
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Reset the execution state
|
|
216
|
-
*/
|
|
217
|
-
reset: () => void;
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Whether execution is active (uploading OR processing)
|
|
221
|
-
*/
|
|
222
|
-
isExecuting: boolean;
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Whether file upload is in progress
|
|
226
|
-
*/
|
|
227
|
-
isUploadingFile: boolean;
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Whether flow processing is in progress
|
|
231
|
-
*/
|
|
232
|
-
isProcessing: boolean;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const initialState: FlowUploadState = {
|
|
236
|
-
status: "idle",
|
|
237
|
-
progress: 0,
|
|
238
|
-
bytesUploaded: 0,
|
|
239
|
-
totalBytes: null,
|
|
240
|
-
error: null,
|
|
241
|
-
jobId: null,
|
|
242
|
-
flowStarted: false,
|
|
243
|
-
currentNodeName: null,
|
|
244
|
-
currentNodeType: null,
|
|
245
|
-
flowOutputs: null,
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Generic React hook for flexible flow execution.
|
|
250
|
-
*
|
|
251
|
-
* Provides a flexible interface for executing flows with arbitrary input types
|
|
252
|
-
* through an inputBuilder pattern. The builder transforms trigger data into
|
|
253
|
-
* flow inputs, enabling support for files, URLs, structured data, and more.
|
|
254
|
-
*
|
|
255
|
-
* Must be used within FlowManagerProvider (which must be within UploadistaProvider).
|
|
256
|
-
*
|
|
257
|
-
* @template TTrigger - The type of trigger data passed to execute()
|
|
258
|
-
* @template TOutput - The expected output type from the flow
|
|
259
|
-
*
|
|
260
|
-
* @param options - Flow execution configuration with inputBuilder
|
|
261
|
-
* @returns Execution state and control methods
|
|
262
|
-
*
|
|
263
|
-
* @example
|
|
264
|
-
* ```tsx
|
|
265
|
-
* // URL-based image processing
|
|
266
|
-
* const urlExecution = useFlowExecution<string>({
|
|
267
|
-
* flowConfig: { flowId: "optimize", storageId: "s3" },
|
|
268
|
-
* inputBuilder: async (url) => {
|
|
269
|
-
* const { inputNodes } = await client.findInputNode("optimize");
|
|
270
|
-
* return {
|
|
271
|
-
* [inputNodes[0].id]: {
|
|
272
|
-
* operation: "url",
|
|
273
|
-
* url,
|
|
274
|
-
* metadata: { source: "external" }
|
|
275
|
-
* }
|
|
276
|
-
* };
|
|
277
|
-
* },
|
|
278
|
-
* onSuccess: (outputs) => console.log("Processed:", outputs)
|
|
279
|
-
* });
|
|
280
|
-
*
|
|
281
|
-
* // Execute with URL
|
|
282
|
-
* await urlExecution.execute("https://example.com/image.jpg");
|
|
283
|
-
*
|
|
284
|
-
* // File upload (traditional pattern)
|
|
285
|
-
* const fileExecution = useFlowExecution<File>({
|
|
286
|
-
* flowConfig: { flowId: "optimize", storageId: "s3" },
|
|
287
|
-
* inputBuilder: async (file) => {
|
|
288
|
-
* const { inputNodes } = await client.findInputNode("optimize");
|
|
289
|
-
* return {
|
|
290
|
-
* [inputNodes[0].id]: {
|
|
291
|
-
* operation: "init",
|
|
292
|
-
* storageId: "s3",
|
|
293
|
-
* metadata: {
|
|
294
|
-
* originalName: file.name,
|
|
295
|
-
* mimeType: file.type,
|
|
296
|
-
* size: file.size
|
|
297
|
-
* }
|
|
298
|
-
* }
|
|
299
|
-
* };
|
|
300
|
-
* }
|
|
301
|
-
* });
|
|
302
|
-
*
|
|
303
|
-
* // Execute with file
|
|
304
|
-
* await fileExecution.execute(myFile);
|
|
305
|
-
* ```
|
|
306
|
-
*/
|
|
307
|
-
export function useFlowExecution<TTrigger = unknown, TOutput = TypedOutput[]>(
|
|
308
|
-
options: UseFlowExecutionOptions<TTrigger, TOutput>,
|
|
309
|
-
): UseFlowExecutionReturn<TTrigger> {
|
|
310
|
-
const { client } = useUploadistaContext();
|
|
311
|
-
const { getManager, releaseManager } = useFlowManagerContext();
|
|
312
|
-
const [state, setState] = useState<FlowUploadState>(initialState);
|
|
313
|
-
const managerRef = useRef<FlowManager<unknown> | null>(null);
|
|
314
|
-
|
|
315
|
-
// Store callbacks and inputBuilder in refs for stable access
|
|
316
|
-
const callbacksRef = useRef(options);
|
|
317
|
-
const inputBuilderRef = useRef(options.inputBuilder);
|
|
318
|
-
|
|
319
|
-
// Update refs when options change
|
|
320
|
-
useEffect(() => {
|
|
321
|
-
callbacksRef.current = options;
|
|
322
|
-
inputBuilderRef.current = options.inputBuilder;
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
// Get or create manager from context
|
|
326
|
-
useEffect(() => {
|
|
327
|
-
const flowId = options.flowConfig.flowId;
|
|
328
|
-
|
|
329
|
-
// Create stable callback wrappers
|
|
330
|
-
const stableCallbacks = {
|
|
331
|
-
onStateChange: setState,
|
|
332
|
-
onProgress: (
|
|
333
|
-
uploadId: string,
|
|
334
|
-
bytesUploaded: number,
|
|
335
|
-
totalBytes: number | null,
|
|
336
|
-
) => {
|
|
337
|
-
callbacksRef.current.onProgress?.(uploadId, bytesUploaded, totalBytes);
|
|
338
|
-
},
|
|
339
|
-
onChunkComplete: (
|
|
340
|
-
chunkSize: number,
|
|
341
|
-
bytesAccepted: number,
|
|
342
|
-
bytesTotal: number | null,
|
|
343
|
-
) => {
|
|
344
|
-
callbacksRef.current.onChunkComplete?.(
|
|
345
|
-
chunkSize,
|
|
346
|
-
bytesAccepted,
|
|
347
|
-
bytesTotal,
|
|
348
|
-
);
|
|
349
|
-
},
|
|
350
|
-
onFlowComplete: (outputs: TypedOutput[]) => {
|
|
351
|
-
callbacksRef.current.onFlowComplete?.(outputs);
|
|
352
|
-
},
|
|
353
|
-
onSuccess: (outputs: TypedOutput[]) => {
|
|
354
|
-
callbacksRef.current.onSuccess?.(outputs as TOutput);
|
|
355
|
-
},
|
|
356
|
-
onError: (error: Error) => {
|
|
357
|
-
callbacksRef.current.onError?.(error);
|
|
358
|
-
},
|
|
359
|
-
onAbort: () => {
|
|
360
|
-
callbacksRef.current.onAbort?.();
|
|
361
|
-
},
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
// Get or create manager for this flow
|
|
365
|
-
const manager = getManager(flowId, stableCallbacks, {
|
|
366
|
-
flowConfig: options.flowConfig,
|
|
367
|
-
});
|
|
368
|
-
managerRef.current = manager;
|
|
369
|
-
|
|
370
|
-
return () => {
|
|
371
|
-
if (managerRef.current) {
|
|
372
|
-
releaseManager(flowId);
|
|
373
|
-
managerRef.current = null;
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
}, [options.flowConfig.flowId, getManager, releaseManager, options]);
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* Execute the flow with trigger data.
|
|
380
|
-
* Calls inputBuilder to transform trigger into flow inputs.
|
|
381
|
-
*/
|
|
382
|
-
const execute = useCallback(async (trigger: TTrigger) => {
|
|
383
|
-
try {
|
|
384
|
-
// Build flow inputs from trigger data
|
|
385
|
-
const flowInputs = await inputBuilderRef.current(trigger);
|
|
386
|
-
|
|
387
|
-
// For now, we need to determine if this is a file upload or URL operation
|
|
388
|
-
// by inspecting the flowInputs structure
|
|
389
|
-
const firstInputNodeId = Object.keys(flowInputs)[0];
|
|
390
|
-
if (!firstInputNodeId) {
|
|
391
|
-
throw new Error("flowInputs must contain at least one input node");
|
|
392
|
-
}
|
|
393
|
-
const firstInput = flowInputs[firstInputNodeId];
|
|
394
|
-
|
|
395
|
-
// Type guard: check if this is an init operation (file upload)
|
|
396
|
-
const isFileUpload =
|
|
397
|
-
typeof firstInput === "object" &&
|
|
398
|
-
firstInput !== null &&
|
|
399
|
-
"operation" in firstInput &&
|
|
400
|
-
firstInput.operation === "init";
|
|
401
|
-
|
|
402
|
-
if (isFileUpload) {
|
|
403
|
-
// File upload path: use the standard upload mechanism
|
|
404
|
-
// This requires the trigger to be a File/Blob
|
|
405
|
-
if (managerRef.current) {
|
|
406
|
-
await managerRef.current.upload(trigger as unknown);
|
|
407
|
-
}
|
|
408
|
-
} else {
|
|
409
|
-
// Non-file path (URL, structured data, etc.)
|
|
410
|
-
// Skip chunked upload and execute flow directly with provided inputs
|
|
411
|
-
setState((prev) => ({
|
|
412
|
-
...prev,
|
|
413
|
-
status: "processing",
|
|
414
|
-
flowStarted: true,
|
|
415
|
-
}));
|
|
416
|
-
|
|
417
|
-
// Execute flow with the built inputs
|
|
418
|
-
const result = await client.executeFlowWithInputs(
|
|
419
|
-
options.flowConfig.flowId,
|
|
420
|
-
flowInputs,
|
|
421
|
-
{
|
|
422
|
-
storageId: options.flowConfig.storageId,
|
|
423
|
-
onJobStart: (jobId: string) => {
|
|
424
|
-
setState((prev) => ({
|
|
425
|
-
...prev,
|
|
426
|
-
jobId,
|
|
427
|
-
}));
|
|
428
|
-
callbacksRef.current.onJobStart?.(jobId);
|
|
429
|
-
},
|
|
430
|
-
},
|
|
431
|
-
);
|
|
432
|
-
|
|
433
|
-
// If job was created successfully, the FlowManager will handle
|
|
434
|
-
// flow events via WebSocket and update state accordingly
|
|
435
|
-
if (result.job?.id) {
|
|
436
|
-
// State updates will come from flow events
|
|
437
|
-
// Manager will receive FlowEnd event and update state to "success"
|
|
438
|
-
} else {
|
|
439
|
-
// No job created - treat as immediate completion
|
|
440
|
-
setState((prev) => ({
|
|
441
|
-
...prev,
|
|
442
|
-
status: "success",
|
|
443
|
-
progress: 100,
|
|
444
|
-
flowStarted: true,
|
|
445
|
-
}));
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
} catch (error) {
|
|
449
|
-
// Handle inputBuilder errors
|
|
450
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
451
|
-
setState((prev) => ({
|
|
452
|
-
...prev,
|
|
453
|
-
status: "error",
|
|
454
|
-
error: err,
|
|
455
|
-
}));
|
|
456
|
-
callbacksRef.current.onError?.(err);
|
|
457
|
-
}
|
|
458
|
-
}, []);
|
|
459
|
-
|
|
460
|
-
/**
|
|
461
|
-
* Abort the current execution
|
|
462
|
-
*/
|
|
463
|
-
const abort = useCallback(() => {
|
|
464
|
-
if (managerRef.current) {
|
|
465
|
-
managerRef.current.abort();
|
|
466
|
-
}
|
|
467
|
-
}, []);
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Pause the current execution
|
|
471
|
-
*/
|
|
472
|
-
const pause = useCallback(() => {
|
|
473
|
-
if (managerRef.current) {
|
|
474
|
-
managerRef.current.pause();
|
|
475
|
-
}
|
|
476
|
-
}, []);
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* Reset the execution state
|
|
480
|
-
*/
|
|
481
|
-
const reset = useCallback(() => {
|
|
482
|
-
if (managerRef.current) {
|
|
483
|
-
const flowId = options.flowConfig.flowId;
|
|
484
|
-
managerRef.current.reset();
|
|
485
|
-
managerRef.current.cleanup();
|
|
486
|
-
releaseManager(flowId);
|
|
487
|
-
managerRef.current = null;
|
|
488
|
-
}
|
|
489
|
-
setState(initialState);
|
|
490
|
-
}, [options.flowConfig.flowId, releaseManager]);
|
|
491
|
-
|
|
492
|
-
return {
|
|
493
|
-
state,
|
|
494
|
-
execute,
|
|
495
|
-
abort,
|
|
496
|
-
pause,
|
|
497
|
-
reset,
|
|
498
|
-
isExecuting: state.status === "uploading" || state.status === "processing",
|
|
499
|
-
isUploadingFile: state.status === "uploading",
|
|
500
|
-
isProcessing: state.status === "processing",
|
|
501
|
-
};
|
|
502
|
-
}
|