@uploadista/react 0.1.2 → 0.1.3-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 +2 -2
- package/dist/components/index.mjs +1 -1
- package/dist/hooks/index.d.mts +2 -2
- package/dist/hooks/index.mjs +1 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{upload-zone-CH8B2-hl.mjs → upload-zone-Dz6GwCwO.mjs} +2 -2
- package/dist/{upload-zone-CH8B2-hl.mjs.map → upload-zone-Dz6GwCwO.mjs.map} +1 -1
- package/dist/{uploadista-provider-DwKXudoT.d.mts → uploadista-provider-dSzfz9mG.d.mts} +36 -37
- package/dist/uploadista-provider-dSzfz9mG.d.mts.map +1 -0
- package/dist/{use-upload-BgaJmdwF.mjs → use-upload-Ccc_uzbr.mjs} +1 -1
- package/dist/use-upload-Ccc_uzbr.mjs.map +1 -0
- package/dist/{use-uploadista-client-CkzVVmFT.d.mts → use-uploadista-client-wN0jDK-k.d.mts} +1 -1
- package/dist/use-uploadista-client-wN0jDK-k.d.mts.map +1 -0
- package/dist/{use-uploadista-events-CtDXJYrR.d.mts → use-uploadista-events-BiqIYgQN.d.mts} +1 -1
- package/dist/use-uploadista-events-BiqIYgQN.d.mts.map +1 -0
- package/dist/{use-uploadista-events-KhJ4knam.mjs → use-uploadista-events-C5SlouR3.mjs} +2 -2
- package/dist/{use-uploadista-events-KhJ4knam.mjs.map → use-uploadista-events-C5SlouR3.mjs.map} +1 -1
- package/package.json +8 -8
- package/dist/uploadista-provider-DwKXudoT.d.mts.map +0 -1
- package/dist/use-upload-BgaJmdwF.mjs.map +0 -1
- package/dist/use-uploadista-client-CkzVVmFT.d.mts.map +0 -1
- package/dist/use-uploadista-events-CtDXJYrR.d.mts.map +0 -1
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { S as UseDragDropReturn, a as MultiUploadState, b as DragDropOptions, d as UseUploadOptions, f as UseUploadReturn, i as MultiUploadOptions, l as UploadState, m as FlowInputMetadata, n as UseUploadistaClientReturn, o as UploadItem$1, s as UseMultiUploadReturn, t as UseUploadistaClientOptions, x as DragDropState } from "./use-uploadista-client-
|
|
1
|
+
import { S as UseDragDropReturn, a as MultiUploadState, b as DragDropOptions, d as UseUploadOptions, f as UseUploadReturn, i as MultiUploadOptions, l as UploadState, m as FlowInputMetadata, n as UseUploadistaClientReturn, o as UploadItem$1, s as UseMultiUploadReturn, t as UseUploadistaClientOptions, x as DragDropState } from "./use-uploadista-client-wN0jDK-k.mjs";
|
|
2
2
|
import React$1, { ReactNode } from "react";
|
|
3
3
|
import { FlowUploadState, FlowUploadStatus, InputExecutionState } from "@uploadista/client-core";
|
|
4
4
|
import { TypedOutput } from "@uploadista/core/flow";
|
|
5
5
|
import { UploadFile } from "@uploadista/core/types";
|
|
6
|
-
import * as
|
|
6
|
+
import * as react_jsx_runtime12 from "react/jsx-runtime";
|
|
7
7
|
import { BrowserUploadInput, FlowUploadConfig, FlowUploadItem, MultiFlowUploadOptions, UploadistaEvent as UploadistaEvent$1 } from "@uploadista/client-browser";
|
|
8
8
|
|
|
9
9
|
//#region src/components/flow-primitives.d.ts
|
|
10
|
-
|
|
11
10
|
/**
|
|
12
11
|
* Context value provided by the Flow component root.
|
|
13
12
|
* Contains all flow state and actions.
|
|
@@ -121,7 +120,7 @@ declare function FlowRoot({
|
|
|
121
120
|
onFlowComplete,
|
|
122
121
|
onAbort,
|
|
123
122
|
children
|
|
124
|
-
}: FlowProps):
|
|
123
|
+
}: FlowProps): react_jsx_runtime12.JSX.Element;
|
|
125
124
|
/**
|
|
126
125
|
* Render props for Flow.DropZone component.
|
|
127
126
|
*/
|
|
@@ -174,7 +173,7 @@ declare function FlowDropZone({
|
|
|
174
173
|
accept,
|
|
175
174
|
maxFileSize,
|
|
176
175
|
children
|
|
177
|
-
}: FlowDropZoneProps):
|
|
176
|
+
}: FlowDropZoneProps): react_jsx_runtime12.JSX.Element;
|
|
178
177
|
/**
|
|
179
178
|
* Render props for Flow.Inputs component.
|
|
180
179
|
*/
|
|
@@ -211,7 +210,7 @@ interface FlowInputsProps {
|
|
|
211
210
|
*/
|
|
212
211
|
declare function FlowInputs({
|
|
213
212
|
children
|
|
214
|
-
}: FlowInputsProps):
|
|
213
|
+
}: FlowInputsProps): react_jsx_runtime12.JSX.Element;
|
|
215
214
|
/**
|
|
216
215
|
* Props for Flow.Input component.
|
|
217
216
|
*/
|
|
@@ -240,7 +239,7 @@ interface FlowInputProps {
|
|
|
240
239
|
declare function FlowInput({
|
|
241
240
|
nodeId,
|
|
242
241
|
children
|
|
243
|
-
}: FlowInputProps):
|
|
242
|
+
}: FlowInputProps): react_jsx_runtime12.JSX.Element | null;
|
|
244
243
|
/**
|
|
245
244
|
* Render props for Flow.Input.DropZone component.
|
|
246
245
|
*/
|
|
@@ -283,7 +282,7 @@ declare function FlowInputDropZone({
|
|
|
283
282
|
accept,
|
|
284
283
|
maxFileSize,
|
|
285
284
|
children
|
|
286
|
-
}: FlowInputDropZoneProps):
|
|
285
|
+
}: FlowInputDropZoneProps): react_jsx_runtime12.JSX.Element;
|
|
287
286
|
/**
|
|
288
287
|
* Props for Flow.Input.UrlField component.
|
|
289
288
|
*/
|
|
@@ -298,7 +297,7 @@ interface FlowInputUrlFieldProps extends Omit<React.InputHTMLAttributes<HTMLInpu
|
|
|
298
297
|
declare function FlowInputUrlField({
|
|
299
298
|
placeholder,
|
|
300
299
|
...props
|
|
301
|
-
}: FlowInputUrlFieldProps):
|
|
300
|
+
}: FlowInputUrlFieldProps): react_jsx_runtime12.JSX.Element;
|
|
302
301
|
/**
|
|
303
302
|
* Render props for Flow.Input.Preview component.
|
|
304
303
|
*/
|
|
@@ -328,7 +327,7 @@ interface FlowInputPreviewProps {
|
|
|
328
327
|
*/
|
|
329
328
|
declare function FlowInputPreview({
|
|
330
329
|
children
|
|
331
|
-
}: FlowInputPreviewProps):
|
|
330
|
+
}: FlowInputPreviewProps): react_jsx_runtime12.JSX.Element;
|
|
332
331
|
/**
|
|
333
332
|
* Render props for Flow.Progress component.
|
|
334
333
|
*/
|
|
@@ -354,7 +353,7 @@ interface FlowProgressProps {
|
|
|
354
353
|
*/
|
|
355
354
|
declare function FlowProgress({
|
|
356
355
|
children
|
|
357
|
-
}: FlowProgressProps):
|
|
356
|
+
}: FlowProgressProps): react_jsx_runtime12.JSX.Element;
|
|
358
357
|
/**
|
|
359
358
|
* Render props for Flow.Status component.
|
|
360
359
|
*/
|
|
@@ -386,7 +385,7 @@ interface FlowStatusProps {
|
|
|
386
385
|
*/
|
|
387
386
|
declare function FlowStatus({
|
|
388
387
|
children
|
|
389
|
-
}: FlowStatusProps):
|
|
388
|
+
}: FlowStatusProps): react_jsx_runtime12.JSX.Element;
|
|
390
389
|
/**
|
|
391
390
|
* Render props for Flow.Error component.
|
|
392
391
|
*/
|
|
@@ -412,7 +411,7 @@ interface FlowErrorProps {
|
|
|
412
411
|
*/
|
|
413
412
|
declare function FlowError({
|
|
414
413
|
children
|
|
415
|
-
}: FlowErrorProps):
|
|
414
|
+
}: FlowErrorProps): react_jsx_runtime12.JSX.Element;
|
|
416
415
|
/**
|
|
417
416
|
* Props for Flow.Submit component.
|
|
418
417
|
*/
|
|
@@ -428,7 +427,7 @@ declare function FlowSubmit({
|
|
|
428
427
|
children,
|
|
429
428
|
disabled,
|
|
430
429
|
...props
|
|
431
|
-
}: FlowSubmitProps):
|
|
430
|
+
}: FlowSubmitProps): react_jsx_runtime12.JSX.Element;
|
|
432
431
|
/**
|
|
433
432
|
* Props for Flow.Cancel component.
|
|
434
433
|
*/
|
|
@@ -442,7 +441,7 @@ interface FlowCancelProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElem
|
|
|
442
441
|
declare function FlowCancel({
|
|
443
442
|
children,
|
|
444
443
|
...props
|
|
445
|
-
}: FlowCancelProps):
|
|
444
|
+
}: FlowCancelProps): react_jsx_runtime12.JSX.Element;
|
|
446
445
|
/**
|
|
447
446
|
* Props for Flow.Reset component.
|
|
448
447
|
*/
|
|
@@ -456,7 +455,7 @@ interface FlowResetProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonEleme
|
|
|
456
455
|
declare function FlowReset({
|
|
457
456
|
children,
|
|
458
457
|
...props
|
|
459
|
-
}: FlowResetProps):
|
|
458
|
+
}: FlowResetProps): react_jsx_runtime12.JSX.Element;
|
|
460
459
|
/**
|
|
461
460
|
* Flow compound component for flow-based file uploads.
|
|
462
461
|
*
|
|
@@ -723,7 +722,7 @@ declare function FlowUploadList({
|
|
|
723
722
|
flowConfig,
|
|
724
723
|
options,
|
|
725
724
|
children
|
|
726
|
-
}: FlowUploadListProps):
|
|
725
|
+
}: FlowUploadListProps): react_jsx_runtime12.JSX.Element;
|
|
727
726
|
/**
|
|
728
727
|
* Props for the SimpleFlowUploadListItem component.
|
|
729
728
|
*
|
|
@@ -778,7 +777,7 @@ declare function SimpleFlowUploadListItem({
|
|
|
778
777
|
onAbort,
|
|
779
778
|
onRetry,
|
|
780
779
|
onRemove
|
|
781
|
-
}: SimpleFlowUploadListItemProps):
|
|
780
|
+
}: SimpleFlowUploadListItemProps): react_jsx_runtime12.JSX.Element;
|
|
782
781
|
/**
|
|
783
782
|
* Props for the SimpleFlowUploadList component.
|
|
784
783
|
*
|
|
@@ -866,7 +865,7 @@ declare function SimpleFlowUploadList({
|
|
|
866
865
|
className,
|
|
867
866
|
showFileInput,
|
|
868
867
|
accept
|
|
869
|
-
}: SimpleFlowUploadListProps):
|
|
868
|
+
}: SimpleFlowUploadListProps): react_jsx_runtime12.JSX.Element;
|
|
870
869
|
//#endregion
|
|
871
870
|
//#region src/components/upload-list.d.ts
|
|
872
871
|
/**
|
|
@@ -1053,7 +1052,7 @@ declare function UploadList({
|
|
|
1053
1052
|
filter,
|
|
1054
1053
|
sortBy,
|
|
1055
1054
|
children
|
|
1056
|
-
}: UploadListProps):
|
|
1055
|
+
}: UploadListProps): react_jsx_runtime12.JSX.Element;
|
|
1057
1056
|
/**
|
|
1058
1057
|
* Props for the SimpleUploadListItem component.
|
|
1059
1058
|
*
|
|
@@ -1133,7 +1132,7 @@ declare function SimpleUploadListItem({
|
|
|
1133
1132
|
className,
|
|
1134
1133
|
style,
|
|
1135
1134
|
showDetails
|
|
1136
|
-
}: SimpleUploadListItemProps):
|
|
1135
|
+
}: SimpleUploadListItemProps): react_jsx_runtime12.JSX.Element;
|
|
1137
1136
|
//#endregion
|
|
1138
1137
|
//#region src/components/upload-primitives.d.ts
|
|
1139
1138
|
/**
|
|
@@ -1278,7 +1277,7 @@ declare function UploadRoot({
|
|
|
1278
1277
|
onUploadStart,
|
|
1279
1278
|
onProgress,
|
|
1280
1279
|
children
|
|
1281
|
-
}: UploadProps):
|
|
1280
|
+
}: UploadProps): react_jsx_runtime12.JSX.Element;
|
|
1282
1281
|
/**
|
|
1283
1282
|
* Render props for Upload.DropZone component.
|
|
1284
1283
|
*/
|
|
@@ -1332,7 +1331,7 @@ declare function UploadDropZone({
|
|
|
1332
1331
|
maxFileSize,
|
|
1333
1332
|
maxFiles,
|
|
1334
1333
|
children
|
|
1335
|
-
}: UploadDropZoneProps):
|
|
1334
|
+
}: UploadDropZoneProps): react_jsx_runtime12.JSX.Element;
|
|
1336
1335
|
/**
|
|
1337
1336
|
* Render props for Upload.Items component.
|
|
1338
1337
|
*/
|
|
@@ -1371,7 +1370,7 @@ interface UploadItemsProps {
|
|
|
1371
1370
|
*/
|
|
1372
1371
|
declare function UploadItems({
|
|
1373
1372
|
children
|
|
1374
|
-
}: UploadItemsProps):
|
|
1373
|
+
}: UploadItemsProps): react_jsx_runtime12.JSX.Element;
|
|
1375
1374
|
/**
|
|
1376
1375
|
* Props for Upload.Item component.
|
|
1377
1376
|
*/
|
|
@@ -1402,7 +1401,7 @@ interface UploadItemProps {
|
|
|
1402
1401
|
declare function UploadItem({
|
|
1403
1402
|
id,
|
|
1404
1403
|
children
|
|
1405
|
-
}: UploadItemProps):
|
|
1404
|
+
}: UploadItemProps): react_jsx_runtime12.JSX.Element | null;
|
|
1406
1405
|
/**
|
|
1407
1406
|
* Render props for Upload.Progress component.
|
|
1408
1407
|
*/
|
|
@@ -1437,7 +1436,7 @@ interface UploadProgressProps {
|
|
|
1437
1436
|
*/
|
|
1438
1437
|
declare function UploadProgress({
|
|
1439
1438
|
children
|
|
1440
|
-
}: UploadProgressProps):
|
|
1439
|
+
}: UploadProgressProps): react_jsx_runtime12.JSX.Element;
|
|
1441
1440
|
/**
|
|
1442
1441
|
* Render props for Upload.Status component.
|
|
1443
1442
|
*/
|
|
@@ -1487,7 +1486,7 @@ interface UploadStatusProps {
|
|
|
1487
1486
|
*/
|
|
1488
1487
|
declare function UploadStatus({
|
|
1489
1488
|
children
|
|
1490
|
-
}: UploadStatusProps):
|
|
1489
|
+
}: UploadStatusProps): react_jsx_runtime12.JSX.Element;
|
|
1491
1490
|
/**
|
|
1492
1491
|
* Render props for Upload.Error component.
|
|
1493
1492
|
*/
|
|
@@ -1529,7 +1528,7 @@ interface UploadErrorProps {
|
|
|
1529
1528
|
*/
|
|
1530
1529
|
declare function UploadError({
|
|
1531
1530
|
children
|
|
1532
|
-
}: UploadErrorProps):
|
|
1531
|
+
}: UploadErrorProps): react_jsx_runtime12.JSX.Element;
|
|
1533
1532
|
/**
|
|
1534
1533
|
* Props for Upload.Cancel component.
|
|
1535
1534
|
*/
|
|
@@ -1545,7 +1544,7 @@ declare function UploadCancel({
|
|
|
1545
1544
|
children,
|
|
1546
1545
|
disabled,
|
|
1547
1546
|
...props
|
|
1548
|
-
}: UploadCancelProps):
|
|
1547
|
+
}: UploadCancelProps): react_jsx_runtime12.JSX.Element;
|
|
1549
1548
|
/**
|
|
1550
1549
|
* Props for Upload.Retry component.
|
|
1551
1550
|
*/
|
|
@@ -1561,7 +1560,7 @@ declare function UploadRetry({
|
|
|
1561
1560
|
children,
|
|
1562
1561
|
disabled,
|
|
1563
1562
|
...props
|
|
1564
|
-
}: UploadRetryProps):
|
|
1563
|
+
}: UploadRetryProps): react_jsx_runtime12.JSX.Element;
|
|
1565
1564
|
/**
|
|
1566
1565
|
* Props for Upload.Reset component.
|
|
1567
1566
|
*/
|
|
@@ -1575,7 +1574,7 @@ interface UploadResetProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonEle
|
|
|
1575
1574
|
declare function UploadReset({
|
|
1576
1575
|
children,
|
|
1577
1576
|
...props
|
|
1578
|
-
}: UploadResetProps):
|
|
1577
|
+
}: UploadResetProps): react_jsx_runtime12.JSX.Element;
|
|
1579
1578
|
/**
|
|
1580
1579
|
* Props for Upload.StartAll component.
|
|
1581
1580
|
*/
|
|
@@ -1592,7 +1591,7 @@ declare function UploadStartAll({
|
|
|
1592
1591
|
children,
|
|
1593
1592
|
disabled,
|
|
1594
1593
|
...props
|
|
1595
|
-
}: UploadStartAllProps):
|
|
1594
|
+
}: UploadStartAllProps): react_jsx_runtime12.JSX.Element;
|
|
1596
1595
|
/**
|
|
1597
1596
|
* Props for Upload.ClearCompleted component.
|
|
1598
1597
|
*/
|
|
@@ -1608,7 +1607,7 @@ declare function UploadClearCompleted({
|
|
|
1608
1607
|
children,
|
|
1609
1608
|
disabled,
|
|
1610
1609
|
...props
|
|
1611
|
-
}: UploadClearCompletedProps):
|
|
1610
|
+
}: UploadClearCompletedProps): react_jsx_runtime12.JSX.Element;
|
|
1612
1611
|
/**
|
|
1613
1612
|
* Upload compound component for file uploads.
|
|
1614
1613
|
*
|
|
@@ -1811,7 +1810,7 @@ declare function UploadZone({
|
|
|
1811
1810
|
onUploadStart,
|
|
1812
1811
|
onValidationError,
|
|
1813
1812
|
...dragDropOptions
|
|
1814
|
-
}: UploadZoneProps):
|
|
1813
|
+
}: UploadZoneProps): react_jsx_runtime12.JSX.Element;
|
|
1815
1814
|
/**
|
|
1816
1815
|
* Props for the SimpleUploadZone component with built-in styling.
|
|
1817
1816
|
*
|
|
@@ -1914,7 +1913,7 @@ declare function SimpleUploadZone({
|
|
|
1914
1913
|
errorStyle,
|
|
1915
1914
|
children,
|
|
1916
1915
|
...uploadZoneProps
|
|
1917
|
-
}: SimpleUploadZoneProps):
|
|
1916
|
+
}: SimpleUploadZoneProps): react_jsx_runtime12.JSX.Element;
|
|
1918
1917
|
//#endregion
|
|
1919
1918
|
//#region src/components/uploadista-provider.d.ts
|
|
1920
1919
|
/**
|
|
@@ -1985,7 +1984,7 @@ type UploadistaContextValue = UseUploadistaClientReturn & {
|
|
|
1985
1984
|
declare function UploadistaProvider({
|
|
1986
1985
|
children,
|
|
1987
1986
|
...options
|
|
1988
|
-
}: UploadistaProviderProps):
|
|
1987
|
+
}: UploadistaProviderProps): react_jsx_runtime12.JSX.Element;
|
|
1989
1988
|
/**
|
|
1990
1989
|
* Hook to access the uploadista client from the UploadistaProvider context.
|
|
1991
1990
|
* Must be used within an UploadistaProvider component.
|
|
@@ -2020,4 +2019,4 @@ declare function UploadistaProvider({
|
|
|
2020
2019
|
declare function useUploadistaContext(): UploadistaContextValue;
|
|
2021
2020
|
//#endregion
|
|
2022
2021
|
export { FlowInputPreviewRenderProps as $, SimpleUploadListItem as A, SimpleFlowUploadListItemProps as B, UploadResetProps as C, UploadStatusRenderProps as D, UploadStatusProps as E, FlowUploadList as F, FlowDropZoneProps as G, Flow as H, FlowUploadListProps as I, FlowErrorRenderProps as J, FlowDropZoneRenderProps as K, FlowUploadListRenderProps as L, UploadList as M, UploadListProps as N, useUploadContext as O, UploadListRenderProps as P, FlowInputPreviewProps as Q, SimpleFlowUploadList as R, UploadProps as S, UploadStartAllProps as T, FlowCancelProps as U, SimpleFlowUploadListProps as V, FlowContextValue as W, FlowInputDropZoneProps as X, FlowInputContextValue as Y, FlowInputDropZoneRenderProps as Z, UploadItemProps as _, UploadZone as a, FlowProgressRenderProps as at, UploadProgressProps as b, Upload as c, FlowStatusProps as ct, UploadContextValue as d, useFlowContext as dt, FlowInputProps as et, UploadDropZoneProps as f, useFlowInputContext as ft, UploadItemContextValue as g, UploadErrorRenderProps as h, SimpleUploadZoneProps as i, FlowProgressProps as it, SimpleUploadListItemProps as j, useUploadItemContext as k, UploadCancelProps as l, FlowStatusRenderProps as lt, UploadErrorProps as m, useUploadistaContext as n, FlowInputsProps as nt, UploadZoneProps as o, FlowProps as ot, UploadDropZoneRenderProps as p, FlowErrorProps as q, SimpleUploadZone as r, FlowInputsRenderProps as rt, UploadZoneRenderProps as s, FlowResetProps as st, UploadistaProvider as t, FlowInputUrlFieldProps as tt, UploadClearCompletedProps as u, FlowSubmitProps as ut, UploadItemsProps as v, UploadRetryProps as w, UploadProgressRenderProps as x, UploadItemsRenderProps as y, SimpleFlowUploadListItem as z };
|
|
2023
|
-
//# sourceMappingURL=uploadista-provider-
|
|
2022
|
+
//# sourceMappingURL=uploadista-provider-dSzfz9mG.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadista-provider-dSzfz9mG.d.mts","names":[],"sources":["../src/components/flow-primitives.tsx","../src/components/flow-upload-list.tsx","../src/components/upload-list.tsx","../src/components/upload-primitives.tsx","../src/components/upload-zone.tsx","../src/components/uploadista-provider.tsx"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{createContext as e,useCallback as t,useContext as n,useEffect as r,useMemo as i,useRef as a,useState as o}from"react";import{FlowManager as s,UploadManager as c}from"@uploadista/client-core";import{EventType as l}from"@uploadista/core/flow";import{UploadEventType as u}from"@uploadista/core/types";import{jsx as d}from"react/jsx-runtime";import{createUploadistaClient as f}from"@uploadista/client-browser";const p={isDragging:!1,isOver:!1,isValid:!0,errors:[]};function m(e={}){let{accept:n,maxFiles:r,maxFileSize:i,multiple:s=!0,validator:c,onFilesReceived:l,onValidationError:u,onDragStateChange:d}=e,[f,m]=o(p),h=a(null),g=a(0),_=t(e=>{m(t=>({...t,...e}))},[]),v=t(e=>{let t=[];r&&e.length>r&&t.push(`Maximum ${r} files allowed. You selected ${e.length} files.`);for(let r of e){if(i&&r.size>i){let e=(i/(1024*1024)).toFixed(1),n=(r.size/(1024*1024)).toFixed(1);t.push(`File "${r.name}" (${n}MB) exceeds maximum size of ${e}MB.`)}n&&n.length>0&&(n.some(e=>{if(e===`*`||e===`*/*`)return!0;if(e.startsWith(`.`))return r.name.toLowerCase().endsWith(e.toLowerCase());if(e.endsWith(`/*`)){let t=e.slice(0,-2);return r.type.startsWith(t)}else return r.type===e})||t.push(`File "${r.name}" type "${r.type}" is not accepted. Accepted types: ${n.join(`, `)}.`))}if(c){let n=c(e);n&&t.push(...n)}return t},[n,r,i,c]),y=t(e=>{let t=Array.from(e),n=v(t);n.length>0?(_({errors:n,isValid:!1}),u?.(n)):(_({errors:[],isValid:!0}),l?.(t))},[v,_,l,u]),b=t(e=>{let t=[];if(e.items)for(let n=0;n<e.items.length;n++){let r=e.items[n];if(r&&r.kind===`file`){let e=r.getAsFile();e&&t.push(e)}}else for(let n=0;n<e.files.length;n++){let r=e.files[n];r&&t.push(r)}return t},[]),x=t(e=>{e.preventDefault(),e.stopPropagation(),g.current++,g.current===1&&(_({isDragging:!0,isOver:!0}),d?.(!0))},[_,d]),S=t(e=>{e.preventDefault(),e.stopPropagation(),e.dataTransfer&&(e.dataTransfer.dropEffect=`copy`)},[]),C=t(e=>{e.preventDefault(),e.stopPropagation(),g.current--,g.current===0&&(_({isDragging:!1,isOver:!1,errors:[]}),d?.(!1))},[_,d]),w=t(e=>{if(e.preventDefault(),e.stopPropagation(),g.current=0,_({isDragging:!1,isOver:!1}),d?.(!1),e.dataTransfer){let t=b(e.dataTransfer);t.length>0&&y(t)}},[_,d,b,y]),T=t(()=>{h.current?.click()},[]),E=t(e=>{e.target.files&&e.target.files.length>0&&y(Array.from(e.target.files)),e.target.value=``},[y]),D=t(()=>{m(p),g.current=0},[]);return{state:f,dragHandlers:{onDragEnter:x,onDragOver:S,onDragLeave:C,onDrop:w},inputProps:{type:`file`,multiple:s,accept:n?.join(`, `),onChange:E,style:{display:`none`},ref:h},openFilePicker:T,processFiles:y,reset:D}}function h(e){let t=e;return t.eventType===l.FlowStart||t.eventType===l.FlowEnd||t.eventType===l.FlowError||t.eventType===l.NodeStart||t.eventType===l.NodeEnd||t.eventType===l.NodePause||t.eventType===l.NodeResume||t.eventType===l.NodeError}const g=e(void 0);function _({children:e}){let{client:n,subscribeToEvents:i}=S(),o=a(new Map);r(()=>i(e=>{if(h(e)){for(let t of o.current.values())t.manager.handleFlowEvent(e);return}if(`type`in e&&e.type===u.UPLOAD_PROGRESS&&`data`in e){let t=e;for(let e of o.current.values())e.manager.handleUploadProgress(t.data.id,t.data.progress,t.data.total)}}),[i]);let c=t((e,t,r)=>{let i=o.current.get(e);if(i)return i.refCount++,i.manager;let a=new s(n.uploadWithFlow,t,r,n.multiInputFlowUpload);return o.current.set(e,{manager:a,refCount:1,flowId:e}),a},[n]),l=t(e=>{let t=o.current.get(e);t&&(t.refCount--,t.refCount<=0&&(t.manager.cleanup(),o.current.delete(e)))},[]);return d(g.Provider,{value:{getManager:c,releaseManager:l},children:e})}function v(){let e=n(g);if(e===void 0)throw Error(`useFlowManagerContext must be used within a FlowManagerProvider. Make sure to wrap your component tree with <FlowManagerProvider>.`);return e}function y(e){let t=a(e);return t.current=e,{client:i(()=>f({baseUrl:e.baseUrl,storageId:e.storageId,uploadistaBasePath:e.uploadistaBasePath,chunkSize:e.chunkSize,storeFingerprintForResuming:e.storeFingerprintForResuming,retryDelays:e.retryDelays,parallelUploads:e.parallelUploads,parallelChunkSize:e.parallelChunkSize,uploadStrategy:e.uploadStrategy,smartChunking:e.smartChunking,networkMonitoring:e.networkMonitoring,uploadMetrics:e.uploadMetrics,connectionPooling:e.connectionPooling,auth:e.auth,onEvent:e.onEvent}),[e.baseUrl,e.storageId,e.uploadistaBasePath,e.chunkSize,e.storeFingerprintForResuming,e.retryDelays,e.parallelUploads,e.parallelChunkSize,e.uploadStrategy,e.smartChunking,e.networkMonitoring,e.uploadMetrics,e.connectionPooling,e.auth,e.onEvent]),config:e}}const b=e(null);function x({children:e,...n}){let r=a(new Set),o=t(e=>{r.current.forEach(t=>{try{t(e)}catch(e){console.error(`Error in event subscriber:`,e)}})},[]),s=y({...n,onEvent:o}),c=t(e=>(r.current.add(e),()=>{r.current.delete(e)}),[]),l=i(()=>({...s,subscribeToEvents:c}),[s,c]);return d(b.Provider,{value:l,children:d(_,{children:e})})}function S(){let e=n(b);if(e===null)throw Error(`useUploadistaContext must be used within an UploadistaProvider. Make sure to wrap your component tree with <UploadistaProvider>.`);return e}const C={status:`idle`,progress:0,bytesUploaded:0,totalBytes:null,error:null,jobId:null,flowStarted:!1,currentNodeName:null,currentNodeType:null,flowOutputs:null};function w(e){let{client:n}=S(),{getManager:i,releaseManager:s}=v(),[c,l]=o(C),[u,d]=o(null),[f,p]=o(!1),[m,h]=o({}),[g,_]=o(new Map),y=a(null),b=a(e);return r(()=>{b.current=e}),r(()=>{(async()=>{p(!0);try{let{flow:t}=await n.getFlow(e.flowConfig.flowId);d(t.nodes.filter(e=>e.type===`input`).map(e=>({nodeId:e.id,nodeName:e.name,nodeDescription:e.description,inputTypeId:e.inputTypeId,required:!0})))}catch(e){console.error(`Failed to discover flow inputs:`,e)}finally{p(!1)}})()},[n,e.flowConfig.flowId]),r(()=>{let t=e.flowConfig.flowId;y.current=i(t,{onStateChange:e=>{l(e)},onProgress:(e,t,n)=>{b.current.onProgress?.(e,t,n)},onChunkComplete:(e,t,n)=>{b.current.onChunkComplete?.(e,t,n)},onFlowComplete:e=>{b.current.onFlowComplete?.(e)},onSuccess:e=>{b.current.onSuccess?.(e)},onError:e=>{b.current.onError?.(e)},onAbort:()=>{b.current.onAbort?.()}},e);let n=setInterval(()=>{if(y.current){let e=y.current.getInputStates();e.size>0&&_(new Map(e))}},100);return()=>{clearInterval(n),s(t),y.current=null}},[e.flowConfig.flowId,e.flowConfig.storageId,e.flowConfig.outputNodeId,i,s]),{state:c,inputMetadata:u,inputStates:g,inputs:m,setInput:t((e,t)=>{h(n=>({...n,[e]:t}))},[]),execute:t(async()=>{if(!y.current)throw Error(`FlowManager not initialized`);if(Object.keys(m).length===0)throw Error(`No inputs provided. Use setInput() to provide inputs before calling execute()`);await y.current.executeFlow(m)},[m]),upload:t(async e=>{if(!y.current)throw Error(`FlowManager not initialized`);if(u&&u.length>0){let t=u[0];if(!t)throw Error(`No input nodes found`);h({[t.nodeId]:e}),await y.current.executeFlow({[t.nodeId]:e})}else await y.current.upload(e)},[u]),abort:t(()=>{y.current?.abort()},[]),pause:t(()=>{y.current?.pause()},[]),reset:t(()=>{y.current?.reset(),h({}),_(new Map)},[]),isUploading:c.status===`uploading`||c.status===`processing`,isUploadingFile:c.status===`uploading`,isProcessing:c.status===`processing`,isDiscoveringInputs:f}}function T(e){let n=S(),[r,i]=o([]),s=a(new Map),c=a([]),l=a(0),u=e.maxConcurrent??3,d=t(e=>{if(e.length===0)return 0;let t=e.reduce((e,t)=>e+t.progress,0);return Math.round(t/e.length)},[]),f=t(async()=>{if(l.current>=u||c.current.length===0)return;let t=c.current.shift();if(!t)return;let a=r.find(e=>e.id===t);if(!a||a.status!==`pending`){f();return}l.current++,i(e=>e.map(e=>e.id===t?{...e,status:`uploading`}:e));try{let{abort:r,jobId:o}=await n.client.uploadWithFlow(a.file,e.flowConfig,{onJobStart:e=>{i(n=>n.map(n=>n.id===t?{...n,jobId:e}:n))},onProgress:(n,r,a)=>{let o=a?Math.round(r/a*100):0;i(n=>{let i=n.map(e=>e.id===t?{...e,progress:o,bytesUploaded:r,totalBytes:a||0}:e),s=i.find(e=>e.id===t);return s&&e.onItemProgress?.(s),i})},onSuccess:n=>{i(r=>{let i=r.map(e=>e.id===t?{...e,status:`success`,result:n,progress:100}:e),a=i.find(e=>e.id===t);return a&&e.onItemSuccess?.(a),i.every(e=>e.status===`success`||e.status===`error`||e.status===`aborted`)&&e.onComplete?.(i),i}),s.current.delete(t),l.current--,f()},onError:n=>{i(r=>{let i=r.map(e=>e.id===t?{...e,status:`error`,error:n}:e),a=i.find(e=>e.id===t);return a&&e.onItemError?.(a,n),i.every(e=>e.status===`success`||e.status===`error`||e.status===`aborted`)&&e.onComplete?.(i),i}),s.current.delete(t),l.current--,f()},onShouldRetry:e.onShouldRetry});s.current.set(t,r),i(e=>e.map(e=>e.id===t?{...e,jobId:o}:e))}catch(e){i(n=>n.map(n=>n.id===t?{...n,status:`error`,error:e}:n)),l.current--,f()}},[n,r,u,e]),p=t(e=>{let t=Array.from(e).map(e=>({id:`${Date.now()}-${Math.random().toString(36).substr(2,9)}`,file:e,status:`pending`,progress:0,bytesUploaded:0,totalBytes:e.size,error:null,result:null,jobId:null}));i(e=>[...e,...t])},[]),m=t(e=>{let t=s.current.get(e);t&&(t(),s.current.delete(e)),i(t=>t.filter(t=>t.id!==e)),c.current=c.current.filter(t=>t!==e)},[]),h=t(()=>{let e=r.filter(e=>e.status===`pending`);c.current.push(...e.map(e=>e.id));for(let e=0;e<u;e++)f()},[r,u,f]),g=t(e=>{let t=s.current.get(e);t&&(t(),s.current.delete(e),i(t=>t.map(t=>t.id===e?{...t,status:`aborted`}:t)),l.current--,f())},[f]),_=t(()=>{for(let e of s.current.values())e();s.current.clear(),c.current=[],l.current=0,i(e=>e.map(e=>e.status===`uploading`?{...e,status:`aborted`}:e))},[]),v=t(()=>{_(),i([])},[_]),y=t(e=>{i(t=>t.map(t=>t.id===e?{...t,status:`pending`,progress:0,bytesUploaded:0,error:null}:t)),c.current.push(e),f()},[f]),b={items:r,totalProgress:d(r),activeUploads:r.filter(e=>e.status===`uploading`).length,completedUploads:r.filter(e=>e.status===`success`).length,failedUploads:r.filter(e=>e.status===`error`).length};return{state:b,addFiles:p,removeFile:m,startUpload:h,abortUpload:g,abortAll:_,clear:v,retryUpload:y,isUploading:b.activeUploads>0}}function E(e={}){let n=S(),{maxConcurrent:r=3}=e,[i,s]=o([]),c=a([]),l=a(0),u=a(new Set),d=a(new Map);c.current=i;let f=t(()=>`upload-${Date.now()}-${l.current++}`,[]),p=t((e,t)=>{s(n=>{let r=n.map(n=>n.id===e?{...n,state:{...n.state,...t}}:n);return c.current=r,r})},[]),m=t(()=>{let t=c.current;if(t.every(e=>[`success`,`error`,`aborted`].includes(e.state.status))&&t.length>0){let n=t.filter(e=>e.state.status===`success`),r=t.filter(e=>[`error`,`aborted`].includes(e.state.status));e.onComplete?.({successful:n,failed:r,total:t.length})}},[e]),h=t(()=>{if(u.current.size>=r)return;let t=c.current.find(e=>e.state.status===`idle`&&!u.current.has(e.id));t&&(async()=>{u.current.add(t.id),e.onUploadStart?.(t),p(t.id,{status:`uploading`});try{let r=await n.client.upload(t.file,{metadata:e.metadata,uploadLengthDeferred:e.uploadLengthDeferred,uploadSize:e.uploadSize,onProgress:(n,r,i)=>{let a=i?Math.round(r/i*100):0;p(t.id,{progress:a,bytesUploaded:r,totalBytes:i}),e.onUploadProgress?.(t,a,r,i)},onChunkComplete:()=>{},onSuccess:n=>{p(t.id,{status:`success`,result:n,progress:100});let r={...t,state:{...t.state,status:`success`,result:n}};e.onUploadSuccess?.(r,n),u.current.delete(t.id),d.current.delete(t.id),h(),m()},onError:n=>{p(t.id,{status:`error`,error:n});let r={...t,state:{...t.state,status:`error`,error:n}};e.onUploadError?.(r,n),u.current.delete(t.id),d.current.delete(t.id),h(),m()},onShouldRetry:e.onShouldRetry});d.current.set(t.id,r)}catch(n){p(t.id,{status:`error`,error:n});let r={...t,state:{...t.state,status:`error`,error:n}};e.onUploadError?.(r,n),u.current.delete(t.id),d.current.delete(t.id),h(),m()}})()},[r,n,e,p,m]),g={total:i.length,completed:i.filter(e=>[`success`,`error`,`aborted`].includes(e.state.status)).length,successful:i.filter(e=>e.state.status===`success`).length,failed:i.filter(e=>[`error`,`aborted`].includes(e.state.status)).length,uploading:i.filter(e=>e.state.status===`uploading`).length,progress:i.length>0?Math.round(i.reduce((e,t)=>e+t.state.progress,0)/i.length):0,totalBytesUploaded:i.reduce((e,t)=>e+t.state.bytesUploaded,0),totalBytes:i.reduce((e,t)=>e+(t.state.totalBytes||0),0),isUploading:i.some(e=>e.state.status===`uploading`),isComplete:i.length>0&&i.every(e=>[`success`,`error`,`aborted`].includes(e.state.status))},_=t(e=>{let t=e.map(e=>({id:f(),file:e,state:{status:`idle`,progress:0,bytesUploaded:0,totalBytes:e instanceof File?e.size:null,error:null,result:null}})),n=[...c.current,...t];c.current=n,s(n)},[f]),v=t(e=>{let t=c.current.find(t=>t.id===e);if(t&&t.state.status===`uploading`){let t=d.current.get(e);t&&(t.abort(),d.current.delete(e))}s(t=>{let n=t.filter(t=>t.id!==e);return c.current=n,n}),u.current.delete(e)},[]),y=t(e=>{let t=c.current.find(t=>t.id===e);if(t&&t.state.status===`uploading`){let t=d.current.get(e);t&&(t.abort(),d.current.delete(e)),u.current.delete(e),s(t=>{let n=t.map(t=>t.id===e?{...t,state:{...t.state,status:`aborted`}}:t);return c.current=n,n}),h()}},[h]),b=t(e=>{let t=c.current.find(t=>t.id===e);t&&[`error`,`aborted`].includes(t.state.status)&&(s(t=>{let n=t.map(t=>t.id===e?{...t,state:{...t.state,status:`idle`,error:null}}:t);return c.current=n,n}),setTimeout(()=>h(),0))},[h]),x=t(()=>{let e=c.current.filter(e=>e.state.status===`idle`),t=r-u.current.size,n=e.slice(0,t);for(let e of n)h()},[r,h]),C=t(()=>{c.current.filter(e=>e.state.status===`uploading`).forEach(e=>{let t=d.current.get(e.id);t&&(t.abort(),d.current.delete(e.id))}),u.current.clear(),s(e=>{let t=e.map(e=>e.state.status===`uploading`?{...e,state:{...e.state,status:`aborted`}}:e);return c.current=t,t})},[]);return{state:g,items:i,addFiles:_,removeItem:v,removeFile:v,startAll:x,abortUpload:y,abortAll:C,retryUpload:b,retryFailed:t(()=>{let e=c.current.filter(e=>[`error`,`aborted`].includes(e.state.status));e.length>0&&(s(t=>{let n=t.map(t=>e.some(e=>e.id===t.id)?{...t,state:{...t.state,status:`idle`,error:null}}:t);return c.current=n,n}),setTimeout(x,0))},[x]),clearCompleted:t(()=>{s(e=>{let t=e.filter(e=>![`success`,`error`,`aborted`].includes(e.state.status));return c.current=t,t})},[]),clearAll:t(()=>{C(),s([]),c.current=[],u.current.clear()},[C]),getItemsByStatus:t(e=>c.current.filter(t=>t.state.status===e),[]),metrics:{getInsights:()=>n.client.getChunkingInsights(),exportMetrics:()=>n.client.exportMetrics(),getNetworkMetrics:()=>n.client.getNetworkMetrics(),getNetworkCondition:()=>n.client.getNetworkCondition(),resetMetrics:()=>n.client.resetMetrics()}}}const D={status:`idle`,progress:0,bytesUploaded:0,totalBytes:null,error:null,result:null};function O(e={}){let n=S(),[i,s]=o(D),l=a(null);return r(()=>(l.current=new c((e,t)=>n.client.upload(e,t),{onStateChange:s,onProgress:e.onProgress,onChunkComplete:e.onChunkComplete,onSuccess:e.onSuccess,onError:e.onError,onAbort:e.onAbort},{metadata:e.metadata,uploadLengthDeferred:e.uploadLengthDeferred,uploadSize:e.uploadSize,onShouldRetry:e.onShouldRetry}),()=>{l.current?.cleanup()}),[n,e]),{state:i,upload:t(e=>{l.current?.upload(e)},[]),abort:t(()=>{l.current?.abort()},[]),reset:t(()=>{l.current?.reset()},[]),retry:t(()=>{l.current?.retry()},[]),isUploading:i.status===`uploading`,canRetry:l.current?.canRetry()??!1,metrics:{getInsights:()=>n.client.getChunkingInsights(),exportMetrics:()=>n.client.exportMetrics(),getNetworkMetrics:()=>n.client.getNetworkMetrics(),getNetworkCondition:()=>n.client.getNetworkCondition(),resetMetrics:()=>n.client.resetMetrics()}}}export{x as a,_ as c,w as i,v as l,E as n,S as o,T as r,y as s,O as t,m as u};
|
|
2
|
-
//# sourceMappingURL=use-upload-
|
|
2
|
+
//# sourceMappingURL=use-upload-Ccc_uzbr.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-upload-Ccc_uzbr.mjs","names":["initialState","initialState"],"sources":["../src/hooks/use-drag-drop.ts","../src/contexts/flow-manager-context.tsx","../src/hooks/use-uploadista-client.ts","../src/components/uploadista-provider.tsx","../src/hooks/use-flow.ts","../src/hooks/use-multi-flow-upload.ts","../src/hooks/use-multi-upload.ts","../src/hooks/use-upload.ts"],"sourcesContent":["import { useCallback, useRef, useState } from \"react\";\n\nexport interface DragDropOptions {\n /**\n * Accept specific file types (MIME types or file extensions)\n */\n accept?: string[];\n\n /**\n * Maximum number of files allowed\n */\n maxFiles?: number;\n\n /**\n * Maximum file size in bytes\n */\n maxFileSize?: number;\n\n /**\n * Whether to allow multiple files\n */\n multiple?: boolean;\n\n /**\n * Custom validation function for files\n */\n validator?: (files: File[]) => string[] | null;\n\n /**\n * Called when files are dropped or selected\n */\n onFilesReceived?: (files: File[]) => void;\n\n /**\n * Called when validation fails\n */\n onValidationError?: (errors: string[]) => void;\n\n /**\n * Called when drag state changes\n */\n onDragStateChange?: (isDragging: boolean) => void;\n}\n\nexport interface DragDropState {\n /**\n * Whether files are currently being dragged over the drop zone\n */\n isDragging: boolean;\n\n /**\n * Whether the drag is currently over the drop zone\n */\n isOver: boolean;\n\n /**\n * Whether the dragged items are valid files\n */\n isValid: boolean;\n\n /**\n * Current validation errors\n */\n errors: string[];\n}\n\nexport interface UseDragDropReturn {\n /**\n * Current drag and drop state\n */\n state: DragDropState;\n\n /**\n * Event handlers for the drop zone element\n */\n dragHandlers: {\n onDragEnter: (event: React.DragEvent) => void;\n onDragOver: (event: React.DragEvent) => void;\n onDragLeave: (event: React.DragEvent) => void;\n onDrop: (event: React.DragEvent) => void;\n };\n\n /**\n * Props for a file input element\n */\n inputProps: {\n type: \"file\";\n multiple: boolean;\n accept?: string;\n onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n style: { display: \"none\" };\n ref: React.RefObject<HTMLInputElement | null>;\n };\n\n /**\n * Open file picker dialog\n */\n openFilePicker: () => void;\n\n /**\n * Manually process files (useful for programmatic file handling)\n */\n processFiles: (files: File[]) => void;\n\n /**\n * Reset drag state\n */\n reset: () => void;\n}\n\nconst initialState: DragDropState = {\n isDragging: false,\n isOver: false,\n isValid: true,\n errors: [],\n};\n\n/**\n * React hook for handling drag and drop file uploads with validation.\n * Provides drag state management, file validation, and file picker integration.\n *\n * @param options - Configuration and event handlers\n * @returns Drag and drop state and handlers\n *\n * @example\n * ```tsx\n * const dragDrop = useDragDrop({\n * accept: ['image/*', '.pdf'],\n * maxFiles: 5,\n * maxFileSize: 10 * 1024 * 1024, // 10MB\n * multiple: true,\n * onFilesReceived: (files) => {\n * console.log('Received files:', files);\n * // Process files with upload hooks\n * },\n * onValidationError: (errors) => {\n * console.error('Validation errors:', errors);\n * },\n * });\n *\n * return (\n * <div>\n * <div\n * {...dragDrop.dragHandlers}\n * style={{\n * border: dragDrop.state.isDragging ? '2px dashed #007bff' : '2px dashed #ccc',\n * backgroundColor: dragDrop.state.isOver ? '#f8f9fa' : 'transparent',\n * padding: '2rem',\n * textAlign: 'center',\n * cursor: 'pointer',\n * }}\n * onClick={dragDrop.openFilePicker}\n * >\n * {dragDrop.state.isDragging ? (\n * <p>Drop files here...</p>\n * ) : (\n * <p>Drag files here or click to select</p>\n * )}\n *\n * {dragDrop.state.errors.length > 0 && (\n * <div style={{ color: 'red', marginTop: '1rem' }}>\n * {dragDrop.state.errors.map((error, index) => (\n * <p key={index}>{error}</p>\n * ))}\n * </div>\n * )}\n * </div>\n *\n * <input {...dragDrop.inputProps} />\n * </div>\n * );\n * ```\n */\nexport function useDragDrop(options: DragDropOptions = {}): UseDragDropReturn {\n const {\n accept,\n maxFiles,\n maxFileSize,\n multiple = true,\n validator,\n onFilesReceived,\n onValidationError,\n onDragStateChange,\n } = options;\n\n const [state, setState] = useState<DragDropState>(initialState);\n const inputRef = useRef<HTMLInputElement>(null);\n const dragCounterRef = useRef(0);\n\n const updateState = useCallback((update: Partial<DragDropState>) => {\n setState((prev) => ({ ...prev, ...update }));\n }, []);\n\n const validateFiles = useCallback(\n (files: File[]): string[] => {\n const errors: string[] = [];\n\n // Check file count\n if (maxFiles && files.length > maxFiles) {\n errors.push(\n `Maximum ${maxFiles} files allowed. You selected ${files.length} files.`,\n );\n }\n\n // Check individual files\n for (const file of files) {\n // Check file size\n if (maxFileSize && file.size > maxFileSize) {\n const maxSizeMB = (maxFileSize / (1024 * 1024)).toFixed(1);\n const fileSizeMB = (file.size / (1024 * 1024)).toFixed(1);\n errors.push(\n `File \"${file.name}\" (${fileSizeMB}MB) exceeds maximum size of ${maxSizeMB}MB.`,\n );\n }\n\n // Check file type\n if (accept && accept.length > 0) {\n const isAccepted = accept.some((acceptType) => {\n // Handle wildcard \"*\" to accept all files\n if (acceptType === \"*\" || acceptType === \"*/*\") {\n return true;\n }\n if (acceptType.startsWith(\".\")) {\n // File extension check\n return file.name.toLowerCase().endsWith(acceptType.toLowerCase());\n } else {\n // MIME type check (supports wildcards like image/*)\n if (acceptType.endsWith(\"/*\")) {\n const baseType = acceptType.slice(0, -2);\n return file.type.startsWith(baseType);\n } else {\n return file.type === acceptType;\n }\n }\n });\n\n if (!isAccepted) {\n errors.push(\n `File \"${file.name}\" type \"${file.type}\" is not accepted. Accepted types: ${accept.join(\", \")}.`,\n );\n }\n }\n }\n\n // Run custom validator\n if (validator) {\n const customErrors = validator(files);\n if (customErrors) {\n errors.push(...customErrors);\n }\n }\n\n return errors;\n },\n [accept, maxFiles, maxFileSize, validator],\n );\n\n const processFiles = useCallback(\n (files: File[]) => {\n const fileArray = Array.from(files);\n const errors = validateFiles(fileArray);\n\n if (errors.length > 0) {\n updateState({ errors, isValid: false });\n onValidationError?.(errors);\n } else {\n updateState({ errors: [], isValid: true });\n onFilesReceived?.(fileArray);\n }\n },\n [validateFiles, updateState, onFilesReceived, onValidationError],\n );\n\n const getFilesFromDataTransfer = useCallback(\n (dataTransfer: DataTransfer): File[] => {\n const files: File[] = [];\n\n if (dataTransfer.items) {\n // Use DataTransferItemList interface\n for (let i = 0; i < dataTransfer.items.length; i++) {\n const item = dataTransfer.items[i];\n if (item && item.kind === \"file\") {\n const file = item.getAsFile();\n if (file) {\n files.push(file);\n }\n }\n }\n } else {\n // Fallback to DataTransfer.files\n for (let i = 0; i < dataTransfer.files.length; i++) {\n const file = dataTransfer.files[i];\n if (file) {\n files.push(file);\n }\n }\n }\n\n return files;\n },\n [],\n );\n\n const onDragEnter = useCallback(\n (event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n dragCounterRef.current++;\n\n if (dragCounterRef.current === 1) {\n updateState({ isDragging: true, isOver: true });\n onDragStateChange?.(true);\n }\n },\n [updateState, onDragStateChange],\n );\n\n const onDragOver = useCallback((event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n // Set dropEffect to indicate what operation is allowed\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = \"copy\";\n }\n }, []);\n\n const onDragLeave = useCallback(\n (event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n dragCounterRef.current--;\n\n if (dragCounterRef.current === 0) {\n updateState({ isDragging: false, isOver: false, errors: [] });\n onDragStateChange?.(false);\n }\n },\n [updateState, onDragStateChange],\n );\n\n const onDrop = useCallback(\n (event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n dragCounterRef.current = 0;\n updateState({ isDragging: false, isOver: false });\n onDragStateChange?.(false);\n\n if (event.dataTransfer) {\n const files = getFilesFromDataTransfer(event.dataTransfer);\n if (files.length > 0) {\n processFiles(files);\n }\n }\n },\n [updateState, onDragStateChange, getFilesFromDataTransfer, processFiles],\n );\n\n const openFilePicker = useCallback(() => {\n inputRef.current?.click();\n }, []);\n\n const onInputChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n if (event.target.files && event.target.files.length > 0) {\n const files = Array.from(event.target.files);\n processFiles(files);\n }\n\n // Reset input value to allow selecting the same files again\n event.target.value = \"\";\n },\n [processFiles],\n );\n\n const reset = useCallback(() => {\n setState(initialState);\n dragCounterRef.current = 0;\n }, []);\n\n const dragHandlers = {\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n };\n\n const inputProps = {\n type: \"file\" as const,\n multiple,\n accept: accept?.join(\", \"),\n onChange: onInputChange,\n style: { display: \"none\" as const },\n ref: inputRef,\n };\n\n return {\n state,\n dragHandlers,\n inputProps,\n openFilePicker,\n processFiles,\n reset,\n };\n}\n","import type {\n BrowserUploadInput,\n FlowUploadOptions,\n UploadistaEvent,\n} from \"@uploadista/client-browser\";\nimport {\n FlowManager,\n type FlowManagerCallbacks,\n} from \"@uploadista/client-core\";\nimport { EventType, type FlowEvent } from \"@uploadista/core/flow\";\nimport { UploadEventType } from \"@uploadista/core/types\";\nimport type { ReactNode } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n} from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\n\n/**\n * Type guard to check if an event is a flow event\n */\nfunction isFlowEvent(event: UploadistaEvent): event is FlowEvent {\n const flowEvent = event as FlowEvent;\n return (\n flowEvent.eventType === EventType.FlowStart ||\n flowEvent.eventType === EventType.FlowEnd ||\n flowEvent.eventType === EventType.FlowError ||\n flowEvent.eventType === EventType.NodeStart ||\n flowEvent.eventType === EventType.NodeEnd ||\n flowEvent.eventType === EventType.NodePause ||\n flowEvent.eventType === EventType.NodeResume ||\n flowEvent.eventType === EventType.NodeError\n );\n}\n\n/**\n * Internal manager registry entry with ref counting\n */\ninterface ManagerEntry {\n manager: FlowManager<unknown>;\n refCount: number;\n flowId: string;\n}\n\n/**\n * Context value providing access to flow managers\n */\ninterface FlowManagerContextValue {\n /**\n * Get or create a flow manager for the given flow ID.\n * Increments ref count - must call releaseManager when done.\n *\n * @param flowId - Unique identifier for the flow\n * @param callbacks - Callbacks for state changes and lifecycle events\n * @param options - Flow configuration options\n * @returns FlowManager instance\n */\n getManager: (\n flowId: string,\n callbacks: FlowManagerCallbacks,\n options: FlowUploadOptions,\n ) => FlowManager<unknown>;\n\n /**\n * Release a flow manager reference.\n * Decrements ref count and cleans up when reaching zero.\n *\n * @param flowId - Unique identifier for the flow to release\n */\n releaseManager: (flowId: string) => void;\n}\n\nconst FlowManagerContext = createContext<FlowManagerContextValue | undefined>(\n undefined,\n);\n\n/**\n * Props for FlowManagerProvider\n */\ninterface FlowManagerProviderProps {\n children: ReactNode;\n}\n\n/**\n * Provider that manages FlowManager instances with ref counting and event routing.\n * Ensures managers persist across component re-renders and are only cleaned up\n * when all consuming components unmount.\n *\n * This provider should be nested inside UploadistaProvider to access the upload client\n * and event subscription system.\n *\n * @example\n * ```tsx\n * <UploadistaProvider baseUrl=\"https://api.example.com\" storageId=\"default\">\n * <FlowManagerProvider>\n * <App />\n * </FlowManagerProvider>\n * </UploadistaProvider>\n * ```\n */\nexport function FlowManagerProvider({ children }: FlowManagerProviderProps) {\n const { client, subscribeToEvents } = useUploadistaContext();\n const managersRef = useRef(new Map<string, ManagerEntry>());\n\n // Subscribe to all events and route to appropriate managers\n useEffect(() => {\n const unsubscribe = subscribeToEvents((event: UploadistaEvent) => {\n // Route flow events to all managers (they filter by jobId internally)\n if (isFlowEvent(event)) {\n for (const entry of managersRef.current.values()) {\n entry.manager.handleFlowEvent(event);\n }\n return;\n }\n\n // Route upload progress events to all managers\n if (\n \"type\" in event &&\n event.type === UploadEventType.UPLOAD_PROGRESS &&\n \"data\" in event\n ) {\n const uploadEvent = event;\n\n for (const entry of managersRef.current.values()) {\n entry.manager.handleUploadProgress(\n uploadEvent.data.id,\n uploadEvent.data.progress,\n uploadEvent.data.total,\n );\n }\n }\n });\n\n return unsubscribe;\n }, [subscribeToEvents]);\n\n const getManager = useCallback(\n (\n flowId: string,\n callbacks: FlowManagerCallbacks,\n options: FlowUploadOptions,\n ): FlowManager<unknown> => {\n const existing = managersRef.current.get(flowId);\n\n if (existing) {\n // Increment ref count for existing manager\n existing.refCount++;\n return existing.manager;\n }\n\n const manager = new FlowManager<BrowserUploadInput>(\n client.uploadWithFlow,\n callbacks,\n options,\n client.multiInputFlowUpload,\n );\n\n managersRef.current.set(flowId, {\n manager,\n refCount: 1,\n flowId,\n });\n\n return manager;\n },\n [client],\n );\n\n const releaseManager = useCallback((flowId: string) => {\n const existing = managersRef.current.get(flowId);\n if (!existing) return;\n\n existing.refCount--;\n\n // Clean up when no more refs\n if (existing.refCount <= 0) {\n existing.manager.cleanup();\n managersRef.current.delete(flowId);\n }\n }, []);\n\n return (\n <FlowManagerContext.Provider value={{ getManager, releaseManager }}>\n {children}\n </FlowManagerContext.Provider>\n );\n}\n\n/**\n * Hook to access the FlowManager context.\n * Must be used within a FlowManagerProvider.\n *\n * @returns FlowManager context value with getManager and releaseManager functions\n * @throws Error if used outside of FlowManagerProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { getManager, releaseManager } = useFlowManagerContext();\n * // Use to create managers...\n * }\n * ```\n */\nexport function useFlowManagerContext(): FlowManagerContextValue {\n const context = useContext(FlowManagerContext);\n\n if (context === undefined) {\n throw new Error(\n \"useFlowManagerContext must be used within a FlowManagerProvider. \" +\n \"Make sure to wrap your component tree with <FlowManagerProvider>.\",\n );\n }\n\n return context;\n}\n","import {\n createUploadistaClient,\n type UploadistaClientOptions,\n} from \"@uploadista/client-browser\";\nimport { useMemo, useRef } from \"react\";\n\n/**\n * Configuration options for the uploadista client hook.\n * Extends the base client options with React-specific behavior.\n *\n * @property onEvent - Global event handler for all upload and flow events\n * @property baseUrl - API base URL for uploads\n * @property storageId - Default storage identifier\n * @property chunkSize - Size of upload chunks in bytes\n * @property storeFingerprintForResuming - Enable resumable uploads\n * @property retryDelays - Array of retry delays in milliseconds\n * @property parallelUploads - Maximum number of parallel uploads\n * @property uploadStrategy - Upload strategy (sequential, parallel, adaptive)\n * @property smartChunking - Enable dynamic chunk size adjustment\n * @property networkMonitoring - Enable network condition monitoring\n */\nexport interface UseUploadistaClientOptions extends UploadistaClientOptions {\n /**\n * Global event handler for all upload and flow events from this client\n */\n onEvent?: UploadistaClientOptions[\"onEvent\"];\n}\n\n/**\n * Return value from the useUploadistaClient hook.\n *\n * @property client - Configured uploadista client instance (stable across re-renders)\n * @property config - Current client configuration options\n */\nexport interface UseUploadistaClientReturn {\n /**\n * The uploadista client instance\n */\n client: ReturnType<typeof createUploadistaClient>;\n\n /**\n * Current configuration of the client\n */\n config: UseUploadistaClientOptions;\n}\n\n/**\n * React hook for creating and managing an uploadista client instance.\n * The client instance is memoized and stable across re-renders, only being\n * recreated when configuration options change.\n *\n * This hook is typically used internally by UploadistaProvider, but can be\n * used directly for advanced use cases requiring multiple client instances.\n *\n * @param options - Upload client configuration options\n * @returns Object containing the stable client instance and current configuration\n *\n * @example\n * ```tsx\n * // Basic client setup\n * function MyUploadComponent() {\n * const { client, config } = useUploadistaClient({\n * baseUrl: 'https://api.example.com',\n * storageId: 'default-storage',\n * chunkSize: 1024 * 1024, // 1MB chunks\n * storeFingerprintForResuming: true,\n * onEvent: (event) => {\n * console.log('Upload event:', event);\n * }\n * });\n *\n * // Use client directly\n * const handleUpload = async (file: File) => {\n * await client.upload(file, {\n * onSuccess: (result) => console.log('Uploaded:', result),\n * onError: (error) => console.error('Failed:', error),\n * });\n * };\n *\n * return <FileUploader onUpload={handleUpload} />;\n * }\n *\n * // Advanced: Multiple clients with different configurations\n * function MultiClientComponent() {\n * // Client for image uploads\n * const imageClient = useUploadistaClient({\n * baseUrl: 'https://images.example.com',\n * storageId: 'images',\n * chunkSize: 2 * 1024 * 1024, // 2MB for images\n * });\n *\n * // Client for document uploads\n * const docClient = useUploadistaClient({\n * baseUrl: 'https://docs.example.com',\n * storageId: 'documents',\n * chunkSize: 512 * 1024, // 512KB for documents\n * });\n *\n * return (\n * <div>\n * <ImageUploader client={imageClient.client} />\n * <DocumentUploader client={docClient.client} />\n * </div>\n * );\n * }\n * ```\n *\n * @see {@link UploadistaProvider} for the recommended way to provide client context\n */\nexport function useUploadistaClient(\n options: UseUploadistaClientOptions,\n): UseUploadistaClientReturn {\n // Store the options in a ref to enable stable dependency checking\n const optionsRef = useRef<UseUploadistaClientOptions>(options);\n\n // Update ref on each render but only create new client when essential deps change\n optionsRef.current = options;\n\n // Create client instance with stable identity\n // IMPORTANT: We depend on individual config values, not the entire options object,\n // to prevent unnecessary client recreation when the options object reference changes\n const client = useMemo(() => {\n return createUploadistaClient({\n baseUrl: options.baseUrl,\n storageId: options.storageId,\n uploadistaBasePath: options.uploadistaBasePath,\n chunkSize: options.chunkSize,\n storeFingerprintForResuming: options.storeFingerprintForResuming,\n retryDelays: options.retryDelays,\n parallelUploads: options.parallelUploads,\n parallelChunkSize: options.parallelChunkSize,\n uploadStrategy: options.uploadStrategy,\n smartChunking: options.smartChunking,\n networkMonitoring: options.networkMonitoring,\n uploadMetrics: options.uploadMetrics,\n connectionPooling: options.connectionPooling,\n // logger: options.logger,\n auth: options.auth,\n onEvent: options.onEvent,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n options.baseUrl,\n options.storageId,\n options.uploadistaBasePath,\n options.chunkSize,\n options.storeFingerprintForResuming,\n options.retryDelays,\n options.parallelUploads,\n options.parallelChunkSize,\n options.uploadStrategy,\n options.smartChunking,\n options.networkMonitoring,\n options.uploadMetrics,\n options.connectionPooling,\n options.auth,\n options.onEvent,\n ]);\n\n return {\n client,\n config: options,\n };\n}\n","\"use client\";\nimport type { UploadistaEvent } from \"@uploadista/client-browser\";\nimport type React from \"react\";\nimport { createContext, useCallback, useContext, useMemo, useRef } from \"react\";\nimport { FlowManagerProvider } from \"../contexts/flow-manager-context\";\nimport {\n type UseUploadistaClientOptions,\n type UseUploadistaClientReturn,\n useUploadistaClient,\n} from \"../hooks/use-uploadista-client\";\n\n/**\n * Props for the UploadistaProvider component.\n * Combines client configuration options with React children.\n *\n * @property children - React components that will have access to the upload client context\n * @property baseUrl - API base URL for uploads\n * @property storageId - Default storage identifier\n * @property chunkSize - Upload chunk size in bytes\n * @property ... - All other UploadistaClientOptions\n */\nexport interface UploadistaProviderProps\n extends Omit<UseUploadistaClientOptions, \"onEvent\"> {\n /**\n * Children components that will have access to the upload client\n */\n children: React.ReactNode;\n}\n\ntype UploadistaContextValue = UseUploadistaClientReturn & {\n /**\n * Subscribe to events (used internally by hooks)\n * @internal\n */\n subscribeToEvents: (handler: (event: UploadistaEvent) => void) => () => void;\n};\n\nconst UploadistaContext = createContext<UploadistaContextValue | null>(null);\n\n/**\n * Context provider that provides uploadista client functionality to child components.\n * This eliminates the need to pass upload client configuration down through props\n * and ensures a single, shared upload client instance across your application.\n *\n * @param props - Upload client options and children\n * @returns Provider component with upload client context\n *\n * @example\n * ```tsx\n * // Wrap your app with the upload provider\n * function App() {\n * return (\n * <UploadistaProvider\n * baseUrl=\"https://api.example.com\"\n * storageId=\"my-storage\"\n * chunkSize={1024 * 1024} // 1MB chunks\n * >\n * <UploadInterface />\n * </UploadistaProvider>\n * );\n * }\n *\n * // Use the upload client in any child component\n * function UploadInterface() {\n * const uploadClient = useUploadistaContext();\n * const upload = useUpload(uploadClient);\n * const dragDrop = useDragDrop({\n * onFilesReceived: (files) => {\n * files.forEach(file => upload.upload(file));\n * }\n * });\n *\n * return (\n * <div {...dragDrop.dragHandlers}>\n * <p>Drop files here to upload</p>\n * {upload.isUploading && <p>Progress: {upload.state.progress}%</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function UploadistaProvider({\n children,\n ...options\n}: UploadistaProviderProps) {\n const eventSubscribersRef = useRef<Set<(event: UploadistaEvent) => void>>(\n new Set(),\n );\n\n // Event handler that broadcasts to all subscribers\n const handleEvent = useCallback((event: UploadistaEvent) => {\n // Broadcast to all subscribers\n eventSubscribersRef.current.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n console.error(\"Error in event subscriber:\", err);\n }\n });\n }, []);\n\n const uploadClient = useUploadistaClient({\n ...options,\n onEvent: handleEvent,\n });\n\n const subscribeToEvents = useCallback(\n (handler: (event: UploadistaEvent) => void) => {\n eventSubscribersRef.current.add(handler);\n return () => {\n eventSubscribersRef.current.delete(handler);\n };\n },\n [],\n );\n\n // Memoize the context value to prevent unnecessary re-renders\n const contextValue = useMemo(\n () => ({\n ...uploadClient,\n subscribeToEvents,\n }),\n [uploadClient, subscribeToEvents],\n );\n\n return (\n <UploadistaContext.Provider value={contextValue}>\n <FlowManagerProvider>{children}</FlowManagerProvider>\n </UploadistaContext.Provider>\n );\n}\n\n/**\n * Hook to access the uploadista client from the UploadistaProvider context.\n * Must be used within an UploadistaProvider component.\n *\n * @returns Upload client instance from context\n * @throws Error if used outside of UploadistaProvider\n *\n * @example\n * ```tsx\n * function FileUploader() {\n * const uploadClient = useUploadistaContext();\n * const upload = useUpload(uploadClient);\n *\n * return (\n * <button\n * onClick={() => {\n * const input = document.createElement('input');\n * input.type = 'file';\n * input.onchange = (e) => {\n * const file = (e.target as HTMLInputElement).files?.[0];\n * if (file) upload.upload(file);\n * };\n * input.click();\n * }}\n * >\n * Upload File\n * </button>\n * );\n * }\n * ```\n */\nexport function useUploadistaContext(): UploadistaContextValue {\n const context = useContext(UploadistaContext);\n\n if (context === null) {\n throw new Error(\n \"useUploadistaContext must be used within an UploadistaProvider. \" +\n \"Make sure to wrap your component tree with <UploadistaProvider>.\",\n );\n }\n\n return context;\n}\n","import type { FlowUploadOptions } from \"@uploadista/client-browser\";\nimport type {\n FlowManager,\n FlowUploadState,\n FlowUploadStatus,\n InputExecutionState,\n} from \"@uploadista/client-core\";\nimport type { TypedOutput } from \"@uploadista/core/flow\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\nimport { useFlowManagerContext } from \"../contexts/flow-manager-context\";\n\n// Re-export types from core for convenience\nexport type { FlowUploadState, FlowUploadStatus, InputExecutionState };\n\n/**\n * Input metadata discovered from the flow\n */\nexport interface FlowInputMetadata {\n /** Input node ID */\n nodeId: string;\n /** Human-readable node name */\n nodeName: string;\n /** Node description explaining what input is needed */\n nodeDescription: string;\n /** Input type ID from inputTypeRegistry - describes how clients interact with this node */\n inputTypeId?: string;\n /** Whether this input is required */\n required: boolean;\n}\n\n/**\n * Return value from the useFlow hook with upload control methods and state.\n *\n * @property state - Complete flow upload state with progress and outputs\n * @property inputMetadata - Metadata about discovered input nodes (null until discovered)\n * @property inputStates - Per-input execution state for multi-input flows\n * @property inputs - Current input values set via setInput()\n * @property setInput - Set an input value for a specific node (for progressive provision)\n * @property execute - Execute the flow with current inputs (auto-detects types)\n * @property upload - Convenience method for single-file upload (same as execute with one file input)\n * @property abort - Cancel the current upload and flow execution\n * @property pause - Pause the current upload\n * @property reset - Reset state to idle (clears all data)\n * @property isUploading - True when upload or processing is active\n * @property isUploadingFile - True only during file upload phase\n * @property isProcessing - True only during flow processing phase\n * @property isDiscoveringInputs - True while discovering flow inputs\n */\nexport interface UseFlowReturn {\n /**\n * Current upload state\n */\n state: FlowUploadState;\n\n /**\n * Discovered input nodes metadata (null until discovery completes)\n */\n inputMetadata: FlowInputMetadata[] | null;\n\n /**\n * Per-input execution state for multi-input flows\n */\n inputStates: ReadonlyMap<string, InputExecutionState>;\n\n /**\n * Current inputs set via setInput()\n */\n inputs: Record<string, unknown>;\n\n /**\n * Set an input value for a specific node.\n * For progressive input provision before calling execute().\n *\n * @param nodeId - The input node ID\n * @param value - The input value (File, URL string, or structured data)\n */\n setInput: (nodeId: string, value: unknown) => void;\n\n /**\n * Execute the flow with current inputs.\n * Automatically detects input types and routes appropriately.\n * For single input, uses standard upload path.\n * For multiple inputs, requires multiInputUploadFn.\n */\n execute: () => Promise<void>;\n\n /**\n * Upload a single file through the flow (convenience method).\n * Equivalent to setInput(firstNodeId, file) + execute().\n *\n * @param file - File or Blob to upload\n */\n upload: (file: File | Blob) => Promise<void>;\n\n /**\n * Abort the current upload\n */\n abort: () => void;\n\n /**\n * Pause the current upload\n */\n pause: () => void;\n\n /**\n * Reset the upload state and clear all inputs\n */\n reset: () => void;\n\n /**\n * Whether an upload or flow execution is in progress (uploading OR processing)\n */\n isUploading: boolean;\n\n /**\n * Whether the file is currently being uploaded (chunks being sent)\n */\n isUploadingFile: boolean;\n\n /**\n * Whether the flow is currently processing (after upload completes)\n */\n isProcessing: boolean;\n\n /**\n * Whether the hook is discovering flow inputs\n */\n isDiscoveringInputs: boolean;\n}\n\nconst initialState: FlowUploadState = {\n status: \"idle\",\n progress: 0,\n bytesUploaded: 0,\n totalBytes: null,\n error: null,\n jobId: null,\n flowStarted: false,\n currentNodeName: null,\n currentNodeType: null,\n flowOutputs: null,\n};\n\n/**\n * React hook for executing flows with single or multiple inputs.\n * Automatically discovers input nodes and detects input types (File, URL, structured data).\n * Supports progressive input provision via setInput() and execute().\n *\n * This is the unified flow hook that replaces useFlowUpload for advanced use cases.\n * It provides:\n * - Auto-discovery of flow input nodes\n * - Automatic input type detection (file → upload, string → URL, object → data)\n * - Progressive input provision via setInput()\n * - Multi-input support with parallel coordination\n * - Per-input state tracking\n *\n * Must be used within FlowManagerProvider (which must be within UploadistaProvider).\n * Flow events are automatically routed by the provider to the appropriate manager.\n *\n * @param options - Flow upload configuration including flow ID and event handlers\n * @returns Flow upload state and control methods\n *\n * @example\n * ```tsx\n * // Single file upload (simple case)\n * function SingleFileUploader() {\n * const flow = useFlow({\n * flowConfig: {\n * flowId: \"image-optimization\",\n * storageId: \"s3-images\",\n * },\n * onSuccess: (outputs) => {\n * console.log(\"Flow outputs:\", outputs);\n * },\n * });\n *\n * return (\n * <div>\n * <input\n * type=\"file\"\n * onChange={(e) => {\n * const file = e.target.files?.[0];\n * if (file) flow.upload(file);\n * }}\n * />\n * {flow.isUploading && <div>Progress: {flow.state.progress}%</div>}\n * </div>\n * );\n * }\n *\n * // Multi-input with progressive provision\n * function MultiInputFlow() {\n * const flow = useFlow({\n * flowConfig: {\n * flowId: \"multi-source-processing\",\n * storageId: \"default\",\n * },\n * });\n *\n * return (\n * <div>\n * {flow.inputMetadata?.map((input) => (\n * <div key={input.nodeId}>\n * <label>{input.nodeId}</label>\n * {input.nodeType === \"streaming-input-v1\" ? (\n * <input\n * type=\"file\"\n * onChange={(e) => {\n * const file = e.target.files?.[0];\n * if (file) flow.setInput(input.nodeId, file);\n * }}\n * />\n * ) : (\n * <input\n * type=\"url\"\n * onChange={(e) => flow.setInput(input.nodeId, e.target.value)}\n * />\n * )}\n * </div>\n * ))}\n * <button onClick={flow.execute} disabled={flow.isUploading}>\n * Execute Flow\n * </button>\n *\n * {flow.isUploading && (\n * <div>\n * {Array.from(flow.inputStates.values()).map((inputState) => (\n * <div key={inputState.nodeId}>\n * {inputState.nodeId}: {inputState.status} ({inputState.progress}%)\n * </div>\n * ))}\n * </div>\n * )}\n * </div>\n * );\n * }\n * ```\n *\n * @see {@link useFlowUpload} for a simpler file-only upload hook\n */\nexport function useFlow(options: FlowUploadOptions): UseFlowReturn {\n const { client } = useUploadistaContext();\n const { getManager, releaseManager } = useFlowManagerContext();\n const [state, setState] = useState<FlowUploadState>(initialState);\n const [inputMetadata, setInputMetadata] = useState<\n FlowInputMetadata[] | null\n >(null);\n const [isDiscoveringInputs, setIsDiscoveringInputs] = useState(false);\n const [inputs, setInputs] = useState<Record<string, unknown>>({});\n const [inputStates, setInputStates] = useState<\n ReadonlyMap<string, InputExecutionState>\n >(new Map());\n const managerRef = useRef<FlowManager<unknown> | null>(null);\n\n // Store callbacks in refs so they can be updated without recreating the manager\n const callbacksRef = useRef(options);\n\n // Update refs on every render to capture latest callbacks\n useEffect(() => {\n callbacksRef.current = options;\n });\n\n // Auto-discover flow inputs on mount\n useEffect(() => {\n const discoverInputs = async () => {\n setIsDiscoveringInputs(true);\n try {\n const { flow } = await client.getFlow(options.flowConfig.flowId);\n\n // Find all input nodes\n const inputNodes = flow.nodes.filter((node) => node.type === \"input\");\n\n const metadata: FlowInputMetadata[] = inputNodes.map((node) => ({\n nodeId: node.id,\n nodeName: node.name,\n nodeDescription: node.description,\n inputTypeId: node.inputTypeId,\n // TODO: Add required field to node schema to determine if input is required\n required: true,\n }));\n\n setInputMetadata(metadata);\n } catch (error) {\n console.error(\"Failed to discover flow inputs:\", error);\n } finally {\n setIsDiscoveringInputs(false);\n }\n };\n\n discoverInputs();\n }, [client, options.flowConfig.flowId]);\n\n // Get or create manager from context when component mounts\n useEffect(() => {\n const flowId = options.flowConfig.flowId;\n\n // Create stable callback wrappers that call the latest callbacks via refs\n const stableCallbacks = {\n onStateChange: (newState: FlowUploadState) => {\n setState(newState);\n },\n onProgress: (\n uploadId: string,\n bytesUploaded: number,\n totalBytes: number | null,\n ) => {\n callbacksRef.current.onProgress?.(uploadId, bytesUploaded, totalBytes);\n },\n onChunkComplete: (\n chunkSize: number,\n bytesAccepted: number,\n bytesTotal: number | null,\n ) => {\n callbacksRef.current.onChunkComplete?.(\n chunkSize,\n bytesAccepted,\n bytesTotal,\n );\n },\n onFlowComplete: (outputs: TypedOutput[]) => {\n callbacksRef.current.onFlowComplete?.(outputs);\n },\n onSuccess: (outputs: TypedOutput[]) => {\n callbacksRef.current.onSuccess?.(outputs);\n },\n onError: (error: Error) => {\n callbacksRef.current.onError?.(error);\n },\n onAbort: () => {\n callbacksRef.current.onAbort?.();\n },\n };\n\n // Get manager from context (creates if doesn't exist, increments ref count)\n managerRef.current = getManager(flowId, stableCallbacks, options);\n\n // Set up interval to poll input states for multi-input flows\n const pollInterval = setInterval(() => {\n if (managerRef.current) {\n const states = managerRef.current.getInputStates();\n if (states.size > 0) {\n setInputStates(new Map(states));\n }\n }\n }, 100); // Poll every 100ms\n\n // Release manager when component unmounts or flowId changes\n return () => {\n clearInterval(pollInterval);\n releaseManager(flowId);\n managerRef.current = null;\n };\n }, [\n options.flowConfig.flowId,\n options.flowConfig.storageId,\n options.flowConfig.outputNodeId,\n getManager,\n releaseManager,\n ]);\n\n // Set an input value\n const setInput = useCallback((nodeId: string, value: unknown) => {\n setInputs((prev) => ({ ...prev, [nodeId]: value }));\n }, []);\n\n // Execute flow with current inputs\n const execute = useCallback(async () => {\n if (!managerRef.current) {\n throw new Error(\"FlowManager not initialized\");\n }\n\n if (Object.keys(inputs).length === 0) {\n throw new Error(\n \"No inputs provided. Use setInput() to provide inputs before calling execute()\",\n );\n }\n\n await managerRef.current.executeFlow(inputs);\n }, [inputs]);\n\n // Convenience method for single file upload\n const upload = useCallback(\n async (file: File | Blob) => {\n if (!managerRef.current) {\n throw new Error(\"FlowManager not initialized\");\n }\n\n // If we have input metadata, use the first input node\n // Otherwise, let the manager discover it\n if (inputMetadata && inputMetadata.length > 0) {\n const firstInputNode = inputMetadata[0];\n if (!firstInputNode) {\n throw new Error(\"No input nodes found\");\n }\n setInputs({ [firstInputNode.nodeId]: file });\n await managerRef.current.executeFlow({ [firstInputNode.nodeId]: file });\n } else {\n // Fall back to direct upload (manager will handle discovery)\n await managerRef.current.upload(file);\n }\n },\n [inputMetadata],\n );\n\n const abort = useCallback(() => {\n managerRef.current?.abort();\n }, []);\n\n const pause = useCallback(() => {\n managerRef.current?.pause();\n }, []);\n\n const reset = useCallback(() => {\n managerRef.current?.reset();\n setInputs({});\n setInputStates(new Map());\n }, []);\n\n // Derive computed values from state (reactive to state changes)\n const isUploading =\n state.status === \"uploading\" || state.status === \"processing\";\n const isUploadingFile = state.status === \"uploading\";\n const isProcessing = state.status === \"processing\";\n\n return {\n state,\n inputMetadata,\n inputStates,\n inputs,\n setInput,\n execute,\n upload,\n abort,\n pause,\n reset,\n isUploading,\n isUploadingFile,\n isProcessing,\n isDiscoveringInputs,\n };\n}\n","import type {\n BrowserUploadInput,\n FlowUploadItem,\n MultiFlowUploadOptions,\n MultiFlowUploadState,\n} from \"@uploadista/client-browser\";\nimport { useCallback, useRef, useState } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\n\n/**\n * Return value from the useMultiFlowUpload hook with batch upload control methods.\n *\n * @property state - Aggregated state across all flow upload items\n * @property addFiles - Add new files to the upload queue\n * @property removeFile - Remove a file from the queue (aborts if uploading)\n * @property startUpload - Begin uploading all pending files\n * @property abortUpload - Cancel a specific upload by its ID\n * @property abortAll - Cancel all active uploads\n * @property clear - Remove all items and abort active uploads\n * @property retryUpload - Retry a specific failed upload\n * @property isUploading - True when any uploads are in progress\n */\nexport interface UseMultiFlowUploadReturn {\n /**\n * Current upload state\n */\n state: MultiFlowUploadState<BrowserUploadInput>;\n\n /**\n * Add files to upload queue\n */\n addFiles: (files: File[] | FileList) => void;\n\n /**\n * Remove a file from the queue\n */\n removeFile: (id: string) => void;\n\n /**\n * Start uploading all pending files\n */\n startUpload: () => void;\n\n /**\n * Abort a specific upload by ID\n */\n abortUpload: (id: string) => void;\n\n /**\n * Abort all active uploads\n */\n abortAll: () => void;\n\n /**\n * Clear all items (aborts any active uploads first)\n */\n clear: () => void;\n\n /**\n * Retry a specific failed upload by ID\n */\n retryUpload: (id: string) => void;\n\n /**\n * Whether uploads are in progress\n */\n isUploading: boolean;\n}\n\n/**\n * React hook for uploading multiple files through a flow with concurrent upload management.\n * Processes each file through the specified flow while respecting concurrency limits.\n *\n * Each file is uploaded and processed independently through the flow, with automatic\n * queue management. Failed uploads can be retried individually, and uploads can be\n * aborted at any time.\n *\n * Must be used within an UploadistaProvider. Flow events for each upload are automatically\n * tracked and synchronized.\n *\n * @param options - Multi-flow upload configuration including flow config and concurrency settings\n * @returns Multi-flow upload state and control methods\n *\n * @example\n * ```tsx\n * // Batch image upload with progress tracking\n * function BatchImageUploader() {\n * const multiFlowUpload = useMultiFlowUpload({\n * flowConfig: {\n * flowId: \"image-optimization-flow\",\n * storageId: \"s3-images\",\n * },\n * maxConcurrent: 3, // Process 3 files at a time\n * onItemSuccess: (item) => {\n * console.log(`${item.file.name} uploaded successfully`);\n * },\n * onItemError: (item, error) => {\n * console.error(`${item.file.name} failed:`, error);\n * },\n * onComplete: (items) => {\n * const successful = items.filter(i => i.status === 'success');\n * const failed = items.filter(i => i.status === 'error');\n * console.log(`Batch complete: ${successful.length} successful, ${failed.length} failed`);\n * },\n * });\n *\n * return (\n * <div>\n * <input\n * type=\"file\"\n * multiple\n * accept=\"image/*\"\n * onChange={(e) => {\n * if (e.target.files) {\n * multiFlowUpload.addFiles(e.target.files);\n * multiFlowUpload.startUpload();\n * }\n * }}\n * />\n *\n * <div>\n * <p>Overall Progress: {multiFlowUpload.state.totalProgress}%</p>\n * <p>\n * {multiFlowUpload.state.activeUploads} uploading,\n * {multiFlowUpload.state.completedUploads} completed,\n * {multiFlowUpload.state.failedUploads} failed\n * </p>\n * </div>\n *\n * <div>\n * <button onClick={multiFlowUpload.startUpload} disabled={multiFlowUpload.isUploading}>\n * Start All\n * </button>\n * <button onClick={multiFlowUpload.abortAll} disabled={!multiFlowUpload.isUploading}>\n * Cancel All\n * </button>\n * <button onClick={multiFlowUpload.clear}>\n * Clear List\n * </button>\n * </div>\n *\n * {multiFlowUpload.state.items.map((item) => (\n * <div key={item.id} style={{\n * border: '1px solid #ccc',\n * padding: '1rem',\n * marginBottom: '0.5rem'\n * }}>\n * <div>{item.file instanceof File ? item.file.name : 'File'}</div>\n * <div>Status: {item.status}</div>\n *\n * {item.status === \"uploading\" && (\n * <div>\n * <progress value={item.progress} max={100} />\n * <span>{item.progress}%</span>\n * <button onClick={() => multiFlowUpload.abortUpload(item.id)}>\n * Cancel\n * </button>\n * </div>\n * )}\n *\n * {item.status === \"error\" && (\n * <div>\n * <p style={{ color: 'red' }}>{item.error?.message}</p>\n * <button onClick={() => multiFlowUpload.retryUpload(item.id)}>\n * Retry\n * </button>\n * <button onClick={() => multiFlowUpload.removeFile(item.id)}>\n * Remove\n * </button>\n * </div>\n * )}\n *\n * {item.status === \"success\" && (\n * <div>\n * <p style={{ color: 'green' }}>✓ Upload complete</p>\n * <button onClick={() => multiFlowUpload.removeFile(item.id)}>\n * Remove\n * </button>\n * </div>\n * )}\n * </div>\n * ))}\n * </div>\n * );\n * }\n * ```\n *\n * @see {@link useFlowUpload} for single file flow uploads\n * @see {@link useMultiUpload} for multi-file uploads without flow processing\n */\nexport function useMultiFlowUpload(\n options: MultiFlowUploadOptions<BrowserUploadInput>,\n): UseMultiFlowUploadReturn {\n const client = useUploadistaContext();\n const [items, setItems] = useState<FlowUploadItem<BrowserUploadInput>[]>([]);\n const abortFnsRef = useRef<Map<string, () => void>>(new Map());\n const queueRef = useRef<string[]>([]);\n const activeCountRef = useRef(0);\n\n const maxConcurrent = options.maxConcurrent ?? 3;\n\n const calculateTotalProgress = useCallback(\n (items: FlowUploadItem<BrowserUploadInput>[]) => {\n if (items.length === 0) return 0;\n const totalProgress = items.reduce((sum, item) => sum + item.progress, 0);\n return Math.round(totalProgress / items.length);\n },\n [],\n );\n\n const processQueue = useCallback(async () => {\n if (\n activeCountRef.current >= maxConcurrent ||\n queueRef.current.length === 0\n ) {\n return;\n }\n\n const itemId = queueRef.current.shift();\n if (!itemId) return;\n\n const item = items.find((i) => i.id === itemId);\n if (!item || item.status !== \"pending\") {\n processQueue();\n return;\n }\n\n activeCountRef.current++;\n\n setItems((prev) =>\n prev.map((i) =>\n i.id === itemId ? { ...i, status: \"uploading\" as const } : i,\n ),\n );\n\n try {\n const { abort, jobId } = await client.client.uploadWithFlow(\n item.file,\n options.flowConfig,\n {\n onJobStart: (jobId: string) => {\n setItems((prev) =>\n prev.map((i) => (i.id === itemId ? { ...i, jobId } : i)),\n );\n },\n onProgress: (\n _uploadId: string,\n bytesUploaded: number,\n totalBytes: number | null,\n ) => {\n const progress = totalBytes\n ? Math.round((bytesUploaded / totalBytes) * 100)\n : 0;\n\n setItems((prev) => {\n const updated = prev.map((i) =>\n i.id === itemId\n ? {\n ...i,\n progress,\n bytesUploaded,\n totalBytes: totalBytes || 0,\n }\n : i,\n );\n const updatedItem = updated.find((i) => i.id === itemId);\n if (updatedItem) {\n options.onItemProgress?.(updatedItem);\n }\n return updated;\n });\n },\n onSuccess: (outputs) => {\n setItems((prev) => {\n const updated = prev.map((i) =>\n i.id === itemId\n ? {\n ...i,\n status: \"success\" as const,\n result: outputs,\n progress: 100,\n }\n : i,\n );\n const updatedItem = updated.find((i) => i.id === itemId);\n if (updatedItem) {\n options.onItemSuccess?.(updatedItem);\n }\n\n // Check if all uploads are complete\n const allComplete = updated.every(\n (i) =>\n i.status === \"success\" ||\n i.status === \"error\" ||\n i.status === \"aborted\",\n );\n if (allComplete) {\n options.onComplete?.(updated);\n }\n\n return updated;\n });\n\n abortFnsRef.current.delete(itemId);\n activeCountRef.current--;\n processQueue();\n },\n onError: (error: Error) => {\n setItems((prev) => {\n const updated = prev.map((i) =>\n i.id === itemId ? { ...i, status: \"error\" as const, error } : i,\n );\n const updatedItem = updated.find((i) => i.id === itemId);\n if (updatedItem) {\n options.onItemError?.(updatedItem, error);\n }\n\n // Check if all uploads are complete\n const allComplete = updated.every(\n (i) =>\n i.status === \"success\" ||\n i.status === \"error\" ||\n i.status === \"aborted\",\n );\n if (allComplete) {\n options.onComplete?.(updated);\n }\n\n return updated;\n });\n\n abortFnsRef.current.delete(itemId);\n activeCountRef.current--;\n processQueue();\n },\n onShouldRetry: options.onShouldRetry,\n },\n );\n\n abortFnsRef.current.set(itemId, abort);\n\n setItems((prev) =>\n prev.map((i) => (i.id === itemId ? { ...i, jobId } : i)),\n );\n } catch (error) {\n setItems((prev) =>\n prev.map((i) =>\n i.id === itemId\n ? { ...i, status: \"error\" as const, error: error as Error }\n : i,\n ),\n );\n\n activeCountRef.current--;\n processQueue();\n }\n }, [client, items, maxConcurrent, options]);\n\n const addFiles = useCallback((files: File[] | FileList) => {\n const fileArray = Array.from(files);\n const newItems: FlowUploadItem<BrowserUploadInput>[] = fileArray.map(\n (file) => ({\n id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n file,\n status: \"pending\",\n progress: 0,\n bytesUploaded: 0,\n totalBytes: file.size,\n error: null,\n result: null,\n jobId: null,\n }),\n );\n\n setItems((prev) => [...prev, ...newItems]);\n }, []);\n\n const removeFile = useCallback((id: string) => {\n const abortFn = abortFnsRef.current.get(id);\n if (abortFn) {\n abortFn();\n abortFnsRef.current.delete(id);\n }\n\n setItems((prev) => prev.filter((item) => item.id !== id));\n queueRef.current = queueRef.current.filter((queueId) => queueId !== id);\n }, []);\n\n const startUpload = useCallback(() => {\n const pendingItems = items.filter((item) => item.status === \"pending\");\n queueRef.current.push(...pendingItems.map((item) => item.id));\n\n for (let i = 0; i < maxConcurrent; i++) {\n processQueue();\n }\n }, [items, maxConcurrent, processQueue]);\n\n const abortUpload = useCallback(\n (id: string) => {\n const abortFn = abortFnsRef.current.get(id);\n if (abortFn) {\n abortFn();\n abortFnsRef.current.delete(id);\n\n setItems((prev) =>\n prev.map((item) =>\n item.id === id ? { ...item, status: \"aborted\" as const } : item,\n ),\n );\n\n activeCountRef.current--;\n processQueue();\n }\n },\n [processQueue],\n );\n\n const abortAll = useCallback(() => {\n for (const abortFn of abortFnsRef.current.values()) {\n abortFn();\n }\n abortFnsRef.current.clear();\n queueRef.current = [];\n activeCountRef.current = 0;\n\n setItems((prev) =>\n prev.map((item) =>\n item.status === \"uploading\"\n ? { ...item, status: \"aborted\" as const }\n : item,\n ),\n );\n }, []);\n\n const clear = useCallback(() => {\n abortAll();\n setItems([]);\n }, [abortAll]);\n\n const retryUpload = useCallback(\n (id: string) => {\n setItems((prev) =>\n prev.map((item) =>\n item.id === id\n ? {\n ...item,\n status: \"pending\" as const,\n progress: 0,\n bytesUploaded: 0,\n error: null,\n }\n : item,\n ),\n );\n\n queueRef.current.push(id);\n processQueue();\n },\n [processQueue],\n );\n\n const state: MultiFlowUploadState<BrowserUploadInput> = {\n items,\n totalProgress: calculateTotalProgress(items),\n activeUploads: items.filter((item) => item.status === \"uploading\").length,\n completedUploads: items.filter((item) => item.status === \"success\").length,\n failedUploads: items.filter((item) => item.status === \"error\").length,\n };\n\n return {\n state,\n addFiles,\n removeFile,\n startUpload,\n abortUpload,\n abortAll,\n clear,\n retryUpload,\n isUploading: state.activeUploads > 0,\n };\n}\n","import type { BrowserUploadInput } from \"@uploadista/client-browser\";\nimport type { UploadMetrics } from \"@uploadista/client-core\";\nimport type { UploadFile } from \"@uploadista/core/types\";\nimport { useCallback, useRef, useState } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\nimport type { UploadState, UploadStatus, UseUploadOptions } from \"./use-upload\";\n\nexport interface UploadItem {\n id: string;\n file: BrowserUploadInput;\n state: UploadState;\n}\n\nexport interface MultiUploadOptions\n extends Omit<UseUploadOptions, \"onSuccess\" | \"onError\" | \"onProgress\"> {\n /**\n * Maximum number of concurrent uploads\n */\n maxConcurrent?: number;\n\n /**\n * Called when an individual file upload starts\n */\n onUploadStart?: (item: UploadItem) => void;\n\n /**\n * Called when an individual file upload progresses\n */\n onUploadProgress?: (\n item: UploadItem,\n progress: number,\n bytesUploaded: number,\n totalBytes: number | null,\n ) => void;\n\n /**\n * Called when an individual file upload succeeds\n */\n onUploadSuccess?: (item: UploadItem, result: UploadFile) => void;\n\n /**\n * Called when an individual file upload fails\n */\n onUploadError?: (item: UploadItem, error: Error) => void;\n\n /**\n * Called when all uploads complete (successfully or with errors)\n */\n onComplete?: (results: {\n successful: UploadItem[];\n failed: UploadItem[];\n total: number;\n }) => void;\n}\n\nexport interface MultiUploadState {\n /**\n * Total number of uploads\n */\n total: number;\n\n /**\n * Number of completed uploads (successful + failed)\n */\n completed: number;\n\n /**\n * Number of successful uploads\n */\n successful: number;\n\n /**\n * Number of failed uploads\n */\n failed: number;\n\n /**\n * Number of currently uploading files\n */\n uploading: number;\n\n /**\n * Overall progress as a percentage (0-100)\n */\n progress: number;\n\n /**\n * Total bytes uploaded across all files\n */\n totalBytesUploaded: number;\n\n /**\n * Total bytes to upload across all files\n */\n totalBytes: number;\n\n /**\n * Whether any uploads are currently active\n */\n isUploading: boolean;\n\n /**\n * Whether all uploads have completed\n */\n isComplete: boolean;\n}\n\nexport interface UseMultiUploadReturn {\n /**\n * Current multi-upload state\n */\n state: MultiUploadState;\n\n /**\n * Array of all upload items\n */\n items: UploadItem[];\n\n /**\n * Add files to the upload queue\n */\n addFiles: (files: BrowserUploadInput[]) => void;\n\n /**\n * Remove an item from the queue (only if not currently uploading)\n */\n removeItem: (id: string) => void;\n\n /**\n * Remove a file from the queue (alias for removeItem)\n */\n removeFile: (id: string) => void;\n\n /**\n * Start all pending uploads\n */\n startAll: () => void;\n\n /**\n * Abort a specific upload by ID\n */\n abortUpload: (id: string) => void;\n\n /**\n * Abort all active uploads\n */\n abortAll: () => void;\n\n /**\n * Retry a specific failed upload by ID\n */\n retryUpload: (id: string) => void;\n\n /**\n * Retry all failed uploads\n */\n retryFailed: () => void;\n\n /**\n * Clear all completed uploads (successful and failed)\n */\n clearCompleted: () => void;\n\n /**\n * Clear all items\n */\n clearAll: () => void;\n\n /**\n * Get items by status\n */\n getItemsByStatus: (status: UploadStatus) => UploadItem[];\n\n /**\n * Aggregated upload metrics and performance insights from the client\n */\n metrics: UploadMetrics;\n}\n\n/**\n * React hook for managing multiple file uploads with queue management,\n * concurrent upload limits, and batch operations.\n *\n * Must be used within an UploadistaProvider.\n *\n * @param options - Multi-upload configuration and event handlers\n * @returns Multi-upload state and control methods\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const multiUpload = useMultiUpload({\n * maxConcurrent: 3,\n * onUploadSuccess: (item, result) => {\n * console.log(`${item.file.name} uploaded successfully`);\n * },\n * onComplete: (results) => {\n * console.log(`Upload batch complete: ${results.successful.length}/${results.total} successful`);\n * },\n * });\n *\n * return (\n * <div>\n * <input\n * type=\"file\"\n * multiple\n * onChange={(e) => {\n * if (e.target.files) {\n * multiUpload.addFiles(Array.from(e.target.files));\n * }\n * }}\n * />\n *\n * <div>Progress: {multiUpload.state.progress}%</div>\n * <div>\n * {multiUpload.state.uploading} uploading, {multiUpload.state.successful} successful,\n * {multiUpload.state.failed} failed\n * </div>\n *\n * <button onClick={multiUpload.startAll} disabled={multiUpload.state.isUploading}>\n * Start All\n * </button>\n * <button onClick={multiUpload.abortAll} disabled={!multiUpload.state.isUploading}>\n * Abort All\n * </button>\n * <button onClick={multiUpload.retryFailed} disabled={multiUpload.state.failed === 0}>\n * Retry Failed\n * </button>\n *\n * {multiUpload.items.map((item) => (\n * <div key={item.id}>\n * {item.file.name}: {item.state.status} ({item.state.progress}%)\n * </div>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\n\nexport function useMultiUpload(\n options: MultiUploadOptions = {},\n): UseMultiUploadReturn {\n const uploadClient = useUploadistaContext();\n const { maxConcurrent = 3 } = options;\n const [items, setItems] = useState<UploadItem[]>([]);\n const itemsRef = useRef<UploadItem[]>([]);\n const nextIdRef = useRef(0);\n const activeUploadsRef = useRef(new Set<string>());\n\n // Store abort controllers for each upload\n const abortControllersRef = useRef<Map<string, { abort: () => void }>>(\n new Map(),\n );\n\n // Keep ref in sync with state (also updated synchronously in setItems callbacks)\n itemsRef.current = items;\n\n // Generate a unique ID for each upload item\n const generateId = useCallback(() => {\n return `upload-${Date.now()}-${nextIdRef.current++}`;\n }, []);\n\n // State update callback for individual uploads\n const onStateUpdate = useCallback(\n (id: string, state: Partial<UploadState>) => {\n setItems((prev) => {\n const updated = prev.map((item) =>\n item.id === id\n ? { ...item, state: { ...item.state, ...state } }\n : item,\n );\n itemsRef.current = updated;\n return updated;\n });\n },\n [],\n );\n\n // Check if all uploads are complete and trigger completion callback\n const checkForCompletion = useCallback(() => {\n const currentItems = itemsRef.current;\n const allComplete = currentItems.every((item) =>\n [\"success\", \"error\", \"aborted\"].includes(item.state.status),\n );\n\n if (allComplete && currentItems.length > 0) {\n const successful = currentItems.filter(\n (item) => item.state.status === \"success\",\n );\n const failed = currentItems.filter((item) =>\n [\"error\", \"aborted\"].includes(item.state.status),\n );\n\n options.onComplete?.({\n successful,\n failed,\n total: currentItems.length,\n });\n }\n }, [options]);\n\n // Start the next available upload if we have capacity\n const startNextUpload = useCallback(() => {\n if (activeUploadsRef.current.size >= maxConcurrent) {\n return;\n }\n\n const currentItems = itemsRef.current;\n const nextItem = currentItems.find(\n (item) =>\n item.state.status === \"idle\" && !activeUploadsRef.current.has(item.id),\n );\n\n if (!nextItem) {\n return;\n }\n\n // Perform upload inline to avoid circular dependency\n const performUploadInline = async () => {\n activeUploadsRef.current.add(nextItem.id);\n options.onUploadStart?.(nextItem);\n\n // Update state to uploading\n onStateUpdate(nextItem.id, { status: \"uploading\" });\n\n try {\n const controller = await uploadClient.client.upload(nextItem.file, {\n metadata: options.metadata,\n uploadLengthDeferred: options.uploadLengthDeferred,\n uploadSize: options.uploadSize,\n\n onProgress: (\n _uploadId: string,\n bytesUploaded: number,\n totalBytes: number | null,\n ) => {\n const progress = totalBytes\n ? Math.round((bytesUploaded / totalBytes) * 100)\n : 0;\n\n onStateUpdate(nextItem.id, {\n progress,\n bytesUploaded,\n totalBytes,\n });\n\n options.onUploadProgress?.(\n nextItem,\n progress,\n bytesUploaded,\n totalBytes,\n );\n },\n\n onChunkComplete: () => {\n // Optional: could expose this as an option\n },\n\n onSuccess: (result: UploadFile) => {\n onStateUpdate(nextItem.id, {\n status: \"success\",\n result,\n progress: 100,\n });\n\n const updatedItem = {\n ...nextItem,\n state: { ...nextItem.state, status: \"success\" as const, result },\n };\n options.onUploadSuccess?.(updatedItem, result);\n\n // Mark complete and start next\n activeUploadsRef.current.delete(nextItem.id);\n abortControllersRef.current.delete(nextItem.id);\n startNextUpload();\n checkForCompletion();\n },\n\n onError: (error: Error) => {\n onStateUpdate(nextItem.id, {\n status: \"error\",\n error,\n });\n\n const updatedItem = {\n ...nextItem,\n state: { ...nextItem.state, status: \"error\" as const, error },\n };\n options.onUploadError?.(updatedItem, error);\n\n // Mark complete and start next\n activeUploadsRef.current.delete(nextItem.id);\n abortControllersRef.current.delete(nextItem.id);\n startNextUpload();\n checkForCompletion();\n },\n\n onShouldRetry: options.onShouldRetry,\n });\n\n // Store abort controller\n abortControllersRef.current.set(nextItem.id, controller);\n } catch (error) {\n onStateUpdate(nextItem.id, {\n status: \"error\",\n error: error as Error,\n });\n\n const updatedItem = {\n ...nextItem,\n state: {\n ...nextItem.state,\n status: \"error\" as const,\n error: error as Error,\n },\n };\n options.onUploadError?.(updatedItem, error as Error);\n\n // Mark complete and start next\n activeUploadsRef.current.delete(nextItem.id);\n abortControllersRef.current.delete(nextItem.id);\n startNextUpload();\n checkForCompletion();\n }\n };\n\n performUploadInline();\n }, [maxConcurrent, uploadClient, options, onStateUpdate, checkForCompletion]);\n\n // Calculate overall state\n const state: MultiUploadState = {\n total: items.length,\n completed: items.filter((item) =>\n [\"success\", \"error\", \"aborted\"].includes(item.state.status),\n ).length,\n successful: items.filter((item) => item.state.status === \"success\").length,\n failed: items.filter((item) =>\n [\"error\", \"aborted\"].includes(item.state.status),\n ).length,\n uploading: items.filter((item) => item.state.status === \"uploading\").length,\n progress:\n items.length > 0\n ? Math.round(\n items.reduce((sum, item) => sum + item.state.progress, 0) /\n items.length,\n )\n : 0,\n totalBytesUploaded: items.reduce(\n (sum, item) => sum + item.state.bytesUploaded,\n 0,\n ),\n totalBytes: items.reduce(\n (sum, item) => sum + (item.state.totalBytes || 0),\n 0,\n ),\n isUploading: items.some((item) => item.state.status === \"uploading\"),\n isComplete:\n items.length > 0 &&\n items.every((item) =>\n [\"success\", \"error\", \"aborted\"].includes(item.state.status),\n ),\n };\n\n const addFiles = useCallback(\n (files: BrowserUploadInput[]) => {\n const newItems: UploadItem[] = files.map((file) => {\n const id = generateId();\n return {\n id,\n file,\n state: {\n status: \"idle\",\n progress: 0,\n bytesUploaded: 0,\n totalBytes: file instanceof File ? file.size : null,\n error: null,\n result: null,\n },\n };\n });\n\n // Update ref synchronously BEFORE setItems\n const updated = [...itemsRef.current, ...newItems];\n itemsRef.current = updated;\n\n setItems(updated);\n },\n [generateId],\n );\n\n const removeItem = useCallback((id: string) => {\n const currentItems = itemsRef.current;\n const item = currentItems.find((i) => i.id === id);\n if (item && item.state.status === \"uploading\") {\n // Abort before removing\n const controller = abortControllersRef.current.get(id);\n if (controller) {\n controller.abort();\n abortControllersRef.current.delete(id);\n }\n }\n\n setItems((prev) => {\n const updated = prev.filter((item) => item.id !== id);\n itemsRef.current = updated;\n return updated;\n });\n activeUploadsRef.current.delete(id);\n }, []);\n\n const abortUpload = useCallback(\n (id: string) => {\n const currentItems = itemsRef.current;\n const item = currentItems.find((i) => i.id === id);\n if (item && item.state.status === \"uploading\") {\n const controller = abortControllersRef.current.get(id);\n if (controller) {\n controller.abort();\n abortControllersRef.current.delete(id);\n }\n\n activeUploadsRef.current.delete(id);\n\n setItems((prev) => {\n const updated = prev.map((i) =>\n i.id === id\n ? { ...i, state: { ...i.state, status: \"aborted\" as const } }\n : i,\n );\n itemsRef.current = updated;\n return updated;\n });\n\n // Try to start next upload in queue\n startNextUpload();\n }\n },\n [startNextUpload],\n );\n\n const retryUpload = useCallback(\n (id: string) => {\n const currentItems = itemsRef.current;\n const item = currentItems.find((i) => i.id === id);\n if (item && [\"error\", \"aborted\"].includes(item.state.status)) {\n setItems((prev) => {\n const updated = prev.map((i) =>\n i.id === id\n ? {\n ...i,\n state: { ...i.state, status: \"idle\" as const, error: null },\n }\n : i,\n );\n itemsRef.current = updated;\n return updated;\n });\n\n // Auto-start the upload\n setTimeout(() => startNextUpload(), 0);\n }\n },\n [startNextUpload],\n );\n\n const startAll = useCallback(() => {\n const currentItems = itemsRef.current;\n // Start as many uploads as we can up to the concurrent limit\n const idleItems = currentItems.filter(\n (item) => item.state.status === \"idle\",\n );\n const slotsAvailable = maxConcurrent - activeUploadsRef.current.size;\n const itemsToStart = idleItems.slice(0, slotsAvailable);\n\n for (const _item of itemsToStart) {\n startNextUpload();\n }\n }, [maxConcurrent, startNextUpload]);\n\n const abortAll = useCallback(() => {\n const currentItems = itemsRef.current;\n currentItems\n .filter((item) => item.state.status === \"uploading\")\n .forEach((item) => {\n const controller = abortControllersRef.current.get(item.id);\n if (controller) {\n controller.abort();\n abortControllersRef.current.delete(item.id);\n }\n });\n\n activeUploadsRef.current.clear();\n\n // Update all uploading items to aborted status\n setItems((prev) => {\n const updated = prev.map((item) =>\n item.state.status === \"uploading\"\n ? { ...item, state: { ...item.state, status: \"aborted\" as const } }\n : item,\n );\n itemsRef.current = updated;\n return updated;\n });\n }, []);\n\n const retryFailed = useCallback(() => {\n const currentItems = itemsRef.current;\n const failedItems = currentItems.filter((item) =>\n [\"error\", \"aborted\"].includes(item.state.status),\n );\n\n if (failedItems.length > 0) {\n setItems((prev) => {\n const updated = prev.map((item) =>\n failedItems.some((f) => f.id === item.id)\n ? {\n ...item,\n state: { ...item.state, status: \"idle\" as const, error: null },\n }\n : item,\n );\n itemsRef.current = updated;\n return updated;\n });\n\n // Auto-start uploads if we have capacity\n setTimeout(startAll, 0);\n }\n }, [startAll]);\n\n const clearCompleted = useCallback(() => {\n setItems((prev) => {\n const updated = prev.filter(\n (item) => ![\"success\", \"error\", \"aborted\"].includes(item.state.status),\n );\n itemsRef.current = updated;\n return updated;\n });\n }, []);\n\n const clearAll = useCallback(() => {\n abortAll();\n setItems([]);\n itemsRef.current = [];\n activeUploadsRef.current.clear();\n }, [abortAll]);\n\n const getItemsByStatus = useCallback((status: UploadStatus) => {\n return itemsRef.current.filter((item) => item.state.status === status);\n }, []);\n\n // Create aggregated metrics object that delegates to the upload client\n const metrics: UploadMetrics = {\n getInsights: () => uploadClient.client.getChunkingInsights(),\n exportMetrics: () => uploadClient.client.exportMetrics(),\n getNetworkMetrics: () => uploadClient.client.getNetworkMetrics(),\n getNetworkCondition: () => uploadClient.client.getNetworkCondition(),\n resetMetrics: () => uploadClient.client.resetMetrics(),\n };\n\n return {\n state,\n items,\n addFiles,\n removeItem,\n removeFile: removeItem, // Alias for consistency with MultiUploadExample\n startAll,\n abortUpload,\n abortAll,\n retryUpload,\n retryFailed,\n clearCompleted,\n clearAll,\n getItemsByStatus,\n metrics,\n };\n}\n","import type { BrowserUploadInput } from \"@uploadista/client-browser\";\nimport type { UploadMetrics, UploadOptions } from \"@uploadista/client-core\";\nimport {\n UploadManager,\n type UploadState,\n type UploadStatus,\n} from \"@uploadista/client-core\";\nimport type { UploadFile } from \"@uploadista/core/types\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\n\n// Re-export types from core for convenience\nexport type { UploadState, UploadStatus };\n\nexport interface UseUploadOptions {\n /**\n * Upload metadata to attach to the file\n */\n metadata?: Record<string, string>;\n\n /**\n * Whether to defer the upload size calculation\n */\n uploadLengthDeferred?: boolean;\n\n /**\n * Manual upload size override\n */\n uploadSize?: number;\n\n /**\n * Called when upload progress updates\n *\n * @param uploadId - The unique identifier for this upload\n * @param bytesUploaded - Number of bytes uploaded\n * @param totalBytes - Total bytes to upload, null if unknown\n */\n onProgress?: (\n uploadId: string,\n bytesUploaded: number,\n totalBytes: number | null,\n ) => void;\n\n /**\n * Called when a chunk completes\n *\n * @param chunkSize - Size of the completed chunk\n * @param bytesAccepted - Total bytes accepted so far\n * @param bytesTotal - Total bytes to upload, null if unknown\n */\n onChunkComplete?: (\n chunkSize: number,\n bytesAccepted: number,\n bytesTotal: number | null,\n ) => void;\n\n /**\n * Called when upload succeeds\n *\n * @param result - The uploaded file result\n */\n onSuccess?: (result: UploadFile) => void;\n\n /**\n * Called when upload fails\n *\n * @param error - The error that caused the failure\n */\n onError?: (error: Error) => void;\n\n /**\n * Called when upload is aborted\n */\n onAbort?: () => void;\n\n /**\n * Custom retry logic\n *\n * @param error - The error that triggered the retry check\n * @param retryAttempt - The current retry attempt number\n * @returns true to retry, false to fail\n */\n onShouldRetry?: (error: Error, retryAttempt: number) => boolean;\n}\n\nexport interface UseUploadReturn {\n /**\n * Current upload state\n */\n state: UploadState;\n\n /**\n * Start uploading a file\n */\n upload: (file: BrowserUploadInput) => void;\n\n /**\n * Abort the current upload\n */\n abort: () => void;\n\n /**\n * Reset the upload state to idle\n */\n reset: () => void;\n\n /**\n * Retry the last failed upload\n */\n retry: () => void;\n\n /**\n * Whether an upload is currently active\n */\n isUploading: boolean;\n\n /**\n * Whether the upload can be retried\n */\n canRetry: boolean;\n\n /**\n * Upload metrics and performance insights from the client\n */\n metrics: UploadMetrics;\n}\n\n/**\n * React hook for managing individual file uploads with full state management.\n * Provides upload progress tracking, error handling, abort functionality, and retry logic.\n *\n * Must be used within an UploadistaProvider.\n *\n * @param options - Upload configuration and event handlers\n * @returns Upload state and control methods\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const upload = useUpload({\n * onSuccess: (result) => console.log('Upload complete:', result),\n * onError: (error) => console.error('Upload failed:', error),\n * onProgress: (uploadId, bytesUploaded, totalBytes) => {\n * const progress = totalBytes ? Math.round((bytesUploaded / totalBytes) * 100) : 0;\n * console.log(`Upload ${uploadId}: ${progress}% (${bytesUploaded}/${totalBytes} bytes)`);\n * },\n * });\n *\n * return (\n * <div>\n * <input\n * type=\"file\"\n * onChange={(e) => {\n * const file = e.target.files?.[0];\n * if (file) upload.upload(file);\n * }}\n * />\n * {upload.isUploading && <div>Progress: {upload.state.progress}%</div>}\n * {upload.state.error && <div>Error: {upload.state.error.message}</div>}\n * {upload.canRetry && <button onClick={upload.retry}>Retry</button>}\n * <button onClick={upload.abort} disabled={!upload.isUploading}>Abort</button>\n * </div>\n * );\n * }\n * ```\n */\nconst initialState: UploadState = {\n status: \"idle\",\n progress: 0,\n bytesUploaded: 0,\n totalBytes: null,\n error: null,\n result: null,\n};\n\nexport function useUpload(options: UseUploadOptions = {}): UseUploadReturn {\n const uploadClient = useUploadistaContext();\n const [state, setState] = useState<UploadState>(initialState);\n const managerRef = useRef<UploadManager<\n BrowserUploadInput,\n UploadOptions\n > | null>(null);\n\n // Create UploadManager instance\n useEffect(() => {\n managerRef.current = new UploadManager(\n (file: BrowserUploadInput, opts: UploadOptions) =>\n uploadClient.client.upload(file, opts),\n {\n onStateChange: setState,\n onProgress: options.onProgress,\n onChunkComplete: options.onChunkComplete,\n onSuccess: options.onSuccess,\n onError: options.onError,\n onAbort: options.onAbort,\n },\n {\n metadata: options.metadata,\n uploadLengthDeferred: options.uploadLengthDeferred,\n uploadSize: options.uploadSize,\n onShouldRetry: options.onShouldRetry,\n },\n );\n\n return () => {\n managerRef.current?.cleanup();\n };\n }, [uploadClient, options]);\n\n // Wrap manager methods with useCallback\n const upload = useCallback((file: BrowserUploadInput) => {\n managerRef.current?.upload(file);\n }, []);\n\n const abort = useCallback(() => {\n managerRef.current?.abort();\n }, []);\n\n const reset = useCallback(() => {\n managerRef.current?.reset();\n }, []);\n\n const retry = useCallback(() => {\n managerRef.current?.retry();\n }, []);\n\n // Derive computed values from state\n const isUploading = state.status === \"uploading\";\n const canRetry = managerRef.current?.canRetry() ?? false;\n\n // Create metrics object that delegates to the upload client\n const metrics: UploadMetrics = {\n getInsights: () => uploadClient.client.getChunkingInsights(),\n exportMetrics: () => uploadClient.client.exportMetrics(),\n getNetworkMetrics: () => uploadClient.client.getNetworkMetrics(),\n getNetworkCondition: () => uploadClient.client.getNetworkCondition(),\n resetMetrics: () => uploadClient.client.resetMetrics(),\n };\n\n return {\n state,\n upload,\n abort,\n reset,\n retry,\n isUploading,\n canRetry,\n metrics,\n };\n}\n"],"mappings":"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"}
|