@uploadista/react 0.0.17-beta.8 → 0.0.17

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.
@@ -1,3 +1,3 @@
1
1
  import "../use-uploadista-client-CQi9j8yN.mjs";
2
- import { C as SimpleFlowUploadListItemProps, E as FlowInputProps, S as SimpleFlowUploadListItem, T as FlowInput, _ as SimpleFlowUploadZoneProps, a as UploadZone, b as FlowUploadListRenderProps, c as SimpleUploadListItem, d as UploadListProps, f as UploadListRenderProps, g as SimpleFlowUploadZone, h as FlowUploadZoneRenderProps, i as SimpleUploadZoneProps, l as SimpleUploadListItemProps, m as FlowUploadZoneProps, n as useUploadistaContext, o as UploadZoneProps, p as FlowUploadZone, r as SimpleUploadZone, s as UploadZoneRenderProps, t as UploadistaProvider, u as UploadList, v as FlowUploadList, w as SimpleFlowUploadListProps, x as SimpleFlowUploadList, y as FlowUploadListProps } from "../uploadista-provider-Dn-IiRxx.mjs";
2
+ import { C as SimpleFlowUploadListItemProps, E as FlowInputProps, S as SimpleFlowUploadListItem, T as FlowInput, _ as SimpleFlowUploadZoneProps, a as UploadZone, b as FlowUploadListRenderProps, c as SimpleUploadListItem, d as UploadListProps, f as UploadListRenderProps, g as SimpleFlowUploadZone, h as FlowUploadZoneRenderProps, i as SimpleUploadZoneProps, l as SimpleUploadListItemProps, m as FlowUploadZoneProps, n as useUploadistaContext, o as UploadZoneProps, p as FlowUploadZone, r as SimpleUploadZone, s as UploadZoneRenderProps, t as UploadistaProvider, u as UploadList, v as FlowUploadList, w as SimpleFlowUploadListProps, x as SimpleFlowUploadList, y as FlowUploadListProps } from "../uploadista-provider-BeHP_vze.mjs";
3
3
  export { FlowInput, type FlowInputProps, FlowUploadList, type FlowUploadListProps, type FlowUploadListRenderProps, FlowUploadZone, type FlowUploadZoneProps, type FlowUploadZoneRenderProps, SimpleFlowUploadList, SimpleFlowUploadListItem, type SimpleFlowUploadListItemProps, type SimpleFlowUploadListProps, SimpleFlowUploadZone, type SimpleFlowUploadZoneProps, SimpleUploadListItem, type SimpleUploadListItemProps, SimpleUploadZone, type SimpleUploadZoneProps, UploadList, type UploadListProps, type UploadListRenderProps, UploadZone, type UploadZoneProps, type UploadZoneRenderProps, UploadistaProvider, useUploadistaContext };
@@ -1 +1 @@
1
- import{a as e,c as t,i as n,n as r,o as i,r as a,s as o,t as s}from"../use-upload-metrics-CFx5cvbR.mjs";import{a as c,c as l,i as u,n as d,r as f,t as p}from"../use-upload-BDHVhQsI.mjs";export{o as isFlowEvent,t as isUploadEvent,c as useDragDrop,a as useFlow,e as useFlowEvents,r as useFlowExecution,f as useFlowUpload,u as useMultiFlowUpload,d as useMultiUpload,p as useUpload,n as useUploadEvents,s as useUploadMetrics,l as useUploadistaClient,i as useUploadistaEvents};
1
+ import{a as e,c as t,i as n,n as r,o as i,r as a,s as o,t as s}from"../use-upload-metrics-OAofTcgA.mjs";import{a as c,c as l,i as u,n as d,r as f,t as p}from"../use-upload-BDHVhQsI.mjs";export{o as isFlowEvent,t as isUploadEvent,c as useDragDrop,a as useFlow,e as useFlowEvents,r as useFlowExecution,f as useFlowUpload,u as useMultiFlowUpload,d as useMultiUpload,p as useUpload,n as useUploadEvents,s as useUploadMetrics,l as useUploadistaClient,i as useUploadistaEvents};
package/dist/index.d.mts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { C as InputExecutionState, S as FlowInputMetadata, T as useFlow, _ as useFlowUpload, a as MultiUploadState, b as UseDragDropReturn, c as useMultiUpload, d as UseUploadOptions, f as UseUploadReturn, g as UseFlowUploadReturn, h as FlowUploadStatus, i as MultiUploadOptions, l as UploadState, m as FlowUploadState, n as UseUploadistaClientReturn, o as UploadItem, p as useUpload, r as useUploadistaClient, s as UseMultiUploadReturn, t as UseUploadistaClientOptions, u as UploadStatus, v as DragDropOptions, w as UseFlowReturn, x as useDragDrop, y as DragDropState } from "./use-uploadista-client-CQi9j8yN.mjs";
2
- import { C as SimpleFlowUploadListItemProps, E as FlowInputProps, S as SimpleFlowUploadListItem, T as FlowInput, _ as SimpleFlowUploadZoneProps, a as UploadZone, b as FlowUploadListRenderProps, c as SimpleUploadListItem, d as UploadListProps, f as UploadListRenderProps, g as SimpleFlowUploadZone, h as FlowUploadZoneRenderProps, i as SimpleUploadZoneProps, l as SimpleUploadListItemProps, m as FlowUploadZoneProps, n as useUploadistaContext, o as UploadZoneProps, p as FlowUploadZone, r as SimpleUploadZone, s as UploadZoneRenderProps, t as UploadistaProvider, u as UploadList, v as FlowUploadList, w as SimpleFlowUploadListProps, x as SimpleFlowUploadList, y as FlowUploadListProps } from "./uploadista-provider-Dn-IiRxx.mjs";
2
+ import { C as SimpleFlowUploadListItemProps, E as FlowInputProps, S as SimpleFlowUploadListItem, T as FlowInput, _ as SimpleFlowUploadZoneProps, a as UploadZone, b as FlowUploadListRenderProps, c as SimpleUploadListItem, d as UploadListProps, f as UploadListRenderProps, g as SimpleFlowUploadZone, h as FlowUploadZoneRenderProps, i as SimpleUploadZoneProps, l as SimpleUploadListItemProps, m as FlowUploadZoneProps, n as useUploadistaContext, o as UploadZoneProps, p as FlowUploadZone, r as SimpleUploadZone, s as UploadZoneRenderProps, t as UploadistaProvider, u as UploadList, v as FlowUploadList, w as SimpleFlowUploadListProps, x as SimpleFlowUploadList, y as FlowUploadListProps } from "./uploadista-provider-BeHP_vze.mjs";
3
3
  import { C as isFlowEvent, S as useUploadistaEvents, _ as UploadValidationWarningEventData, a as useUploadMetrics, b as UseFlowEventsOptions, c as InputBuilder, d as useFlowExecution, f as UploadFailedEventData, g as UploadValidationSuccessEventData, h as UploadValidationFailedEventData, i as UseUploadMetricsReturn, l as UseFlowExecutionOptions, m as UploadProgressEventData, n as UploadMetrics, o as UseMultiFlowUploadReturn, p as UploadFileEventData, r as UseUploadMetricsOptions, s as useMultiFlowUpload, t as FileUploadMetrics, u as UseFlowExecutionReturn, v as UseUploadEventsOptions, w as isUploadEvent, x as useFlowEvents, y as useUploadEvents } from "./use-upload-metrics-DhzS4lhG.mjs";
4
4
  import { ReactNode } from "react";
5
5
  import { FlowManager, FlowManagerCallbacks } from "@uploadista/client-core";
6
- import * as react_jsx_runtime9 from "react/jsx-runtime";
6
+ import * as react_jsx_runtime10 from "react/jsx-runtime";
7
7
  import { FlowUploadOptions } from "@uploadista/client-browser";
8
8
 
9
9
  //#region src/contexts/flow-manager-context.d.ts
@@ -54,7 +54,7 @@ interface FlowManagerProviderProps {
54
54
  */
55
55
  declare function FlowManagerProvider({
56
56
  children
57
- }: FlowManagerProviderProps): react_jsx_runtime9.JSX.Element;
57
+ }: FlowManagerProviderProps): react_jsx_runtime10.JSX.Element;
58
58
  /**
59
59
  * Hook to access the FlowManager context.
60
60
  * Must be used within a FlowManagerProvider.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/contexts/flow-manager-context.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;;;;UAkDU,uBAAA;;;AAvC6B;;;;;AAqDrB;AAuClB;EAAsC,UAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,SAAA,EAzCvB,oBAyCuB,EAAA,OAAA,EAxCzB,iBAwCyB,EAAA,GAvC/B,WAuC+B,CAAA,OAAA,CAAA;EAAY;;;AAuGlD;;;;;;;;UA5HU,wBAAA;YACE;;;;;;;;;;;;;;;;;;;iBAoBI,mBAAA;;GAAkC,2BAAwB,kBAAA,CAAA,GAAA,CAAA;;;;;;;;;;;;;;;;iBAuG1D,qBAAA,CAAA,GAAyB"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/contexts/flow-manager-context.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;;;;UAkDU,uBAAA;;;AAvC6B;;;;;AAqDrB;AAuClB;EAAsC,UAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,SAAA,EAzCvB,oBAyCuB,EAAA,OAAA,EAxCzB,iBAwCyB,EAAA,GAvC/B,WAuC+B,CAAA,OAAA,CAAA;EAAY;;;AAuGlD;;;;;;;;UA5HU,wBAAA;YACE;;;;;;;;;;;;;;;;;;;iBAoBI,mBAAA;;GAAkC,2BAAwB,mBAAA,CAAA,GAAA,CAAA;;;;;;;;;;;;;;;;iBAuG1D,qBAAA,CAAA,GAAyB"}
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{a as e,c as t,i as n,n as r,o as i,r as a,s as o,t as s}from"./use-upload-metrics-CFx5cvbR.mjs";import{a as c,c as l,i as u,l as d,n as f,o as p,r as m,s as h,t as g,u as _}from"./use-upload-BDHVhQsI.mjs";import{a as v,c as y,i as b,l as x,n as S,o as C,r as w,s as T,t as E,u as D}from"./upload-zone-Bbqr8oWe.mjs";export{D as FlowInput,d as FlowManagerProvider,T as FlowUploadList,v as FlowUploadZone,y as SimpleFlowUploadList,x as SimpleFlowUploadListItem,C as SimpleFlowUploadZone,w as SimpleUploadListItem,E as SimpleUploadZone,b as UploadList,S as UploadZone,p as UploadistaProvider,o as isFlowEvent,t as isUploadEvent,c as useDragDrop,a as useFlow,e as useFlowEvents,r as useFlowExecution,_ as useFlowManagerContext,m as useFlowUpload,u as useMultiFlowUpload,f as useMultiUpload,g as useUpload,n as useUploadEvents,s as useUploadMetrics,l as useUploadistaClient,h as useUploadistaContext,i as useUploadistaEvents};
1
+ import{a as e,c as t,i as n,n as r,o as i,r as a,s as o,t as s}from"./use-upload-metrics-OAofTcgA.mjs";import{a as c,c as l,i as u,l as d,n as f,o as p,r as m,s as h,t as g,u as _}from"./use-upload-BDHVhQsI.mjs";import{a as v,c as y,i as b,l as x,n as S,o as C,r as w,s as T,t as E,u as D}from"./upload-zone-Bbqr8oWe.mjs";export{D as FlowInput,d as FlowManagerProvider,T as FlowUploadList,v as FlowUploadZone,y as SimpleFlowUploadList,x as SimpleFlowUploadListItem,C as SimpleFlowUploadZone,w as SimpleUploadListItem,E as SimpleUploadZone,b as UploadList,S as UploadZone,p as UploadistaProvider,o as isFlowEvent,t as isUploadEvent,c as useDragDrop,a as useFlow,e as useFlowEvents,r as useFlowExecution,_ as useFlowManagerContext,m as useFlowUpload,u as useMultiFlowUpload,f as useMultiUpload,g as useUpload,n as useUploadEvents,s as useUploadMetrics,l as useUploadistaClient,h as useUploadistaContext,i as useUploadistaEvents};
@@ -1,6 +1,6 @@
1
1
  import { S as FlowInputMetadata, b as UseDragDropReturn, d as UseUploadOptions, f as UseUploadReturn, g as UseFlowUploadReturn, i as MultiUploadOptions, n as UseUploadistaClientReturn, o as UploadItem, s as UseMultiUploadReturn, t as UseUploadistaClientOptions, v as DragDropOptions } from "./use-uploadista-client-CQi9j8yN.mjs";
2
2
  import React$1, { ReactNode } from "react";
3
- import * as react_jsx_runtime2 from "react/jsx-runtime";
3
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
4
4
  import { BrowserUploadInput, FlowUploadConfig, FlowUploadItem, FlowUploadOptions, MultiFlowUploadOptions, UploadistaEvent } from "@uploadista/client-browser";
5
5
 
6
6
  //#region src/components/flow-input.d.ts
@@ -49,7 +49,7 @@ declare function FlowInput({
49
49
  onChange,
50
50
  disabled,
51
51
  className
52
- }: FlowInputProps): react_jsx_runtime2.JSX.Element;
52
+ }: FlowInputProps): react_jsx_runtime0.JSX.Element;
53
53
  //#endregion
54
54
  //#region src/components/flow-upload-list.d.ts
55
55
  /**
@@ -255,7 +255,7 @@ declare function FlowUploadList({
255
255
  flowConfig,
256
256
  options,
257
257
  children
258
- }: FlowUploadListProps): react_jsx_runtime2.JSX.Element;
258
+ }: FlowUploadListProps): react_jsx_runtime0.JSX.Element;
259
259
  /**
260
260
  * Props for the SimpleFlowUploadListItem component.
261
261
  *
@@ -310,7 +310,7 @@ declare function SimpleFlowUploadListItem({
310
310
  onAbort,
311
311
  onRetry,
312
312
  onRemove
313
- }: SimpleFlowUploadListItemProps): react_jsx_runtime2.JSX.Element;
313
+ }: SimpleFlowUploadListItemProps): react_jsx_runtime0.JSX.Element;
314
314
  /**
315
315
  * Props for the SimpleFlowUploadList component.
316
316
  *
@@ -398,7 +398,7 @@ declare function SimpleFlowUploadList({
398
398
  className,
399
399
  showFileInput,
400
400
  accept
401
- }: SimpleFlowUploadListProps): react_jsx_runtime2.JSX.Element;
401
+ }: SimpleFlowUploadListProps): react_jsx_runtime0.JSX.Element;
402
402
  //#endregion
403
403
  //#region src/components/flow-upload-zone.d.ts
404
404
  /**
@@ -574,7 +574,7 @@ declare function FlowUploadZone({
574
574
  accept,
575
575
  multiple,
576
576
  children
577
- }: FlowUploadZoneProps): react_jsx_runtime2.JSX.Element;
577
+ }: FlowUploadZoneProps): react_jsx_runtime0.JSX.Element;
578
578
  /**
579
579
  * Props for the SimpleFlowUploadZone component.
580
580
  *
@@ -668,7 +668,7 @@ declare function SimpleFlowUploadZone({
668
668
  className,
669
669
  dragText,
670
670
  idleText
671
- }: SimpleFlowUploadZoneProps): react_jsx_runtime2.JSX.Element;
671
+ }: SimpleFlowUploadZoneProps): react_jsx_runtime0.JSX.Element;
672
672
  //#endregion
673
673
  //#region src/components/upload-list.d.ts
674
674
  /**
@@ -855,7 +855,7 @@ declare function UploadList({
855
855
  filter,
856
856
  sortBy,
857
857
  children
858
- }: UploadListProps): react_jsx_runtime2.JSX.Element;
858
+ }: UploadListProps): react_jsx_runtime0.JSX.Element;
859
859
  /**
860
860
  * Props for the SimpleUploadListItem component.
861
861
  *
@@ -935,7 +935,7 @@ declare function SimpleUploadListItem({
935
935
  className,
936
936
  style,
937
937
  showDetails
938
- }: SimpleUploadListItemProps): react_jsx_runtime2.JSX.Element;
938
+ }: SimpleUploadListItemProps): react_jsx_runtime0.JSX.Element;
939
939
  //#endregion
940
940
  //#region src/components/upload-zone.d.ts
941
941
  /**
@@ -1071,7 +1071,7 @@ declare function UploadZone({
1071
1071
  onUploadStart,
1072
1072
  onValidationError,
1073
1073
  ...dragDropOptions
1074
- }: UploadZoneProps): react_jsx_runtime2.JSX.Element;
1074
+ }: UploadZoneProps): react_jsx_runtime0.JSX.Element;
1075
1075
  /**
1076
1076
  * Props for the SimpleUploadZone component with built-in styling.
1077
1077
  *
@@ -1174,7 +1174,7 @@ declare function SimpleUploadZone({
1174
1174
  errorStyle,
1175
1175
  children,
1176
1176
  ...uploadZoneProps
1177
- }: SimpleUploadZoneProps): react_jsx_runtime2.JSX.Element;
1177
+ }: SimpleUploadZoneProps): react_jsx_runtime0.JSX.Element;
1178
1178
  //#endregion
1179
1179
  //#region src/components/uploadista-provider.d.ts
1180
1180
  /**
@@ -1245,7 +1245,7 @@ type UploadistaContextValue = UseUploadistaClientReturn & {
1245
1245
  declare function UploadistaProvider({
1246
1246
  children,
1247
1247
  ...options
1248
- }: UploadistaProviderProps): react_jsx_runtime2.JSX.Element;
1248
+ }: UploadistaProviderProps): react_jsx_runtime0.JSX.Element;
1249
1249
  /**
1250
1250
  * Hook to access the uploadista client from the UploadistaProvider context.
1251
1251
  * Must be used within an UploadistaProvider component.
@@ -1280,4 +1280,4 @@ declare function UploadistaProvider({
1280
1280
  declare function useUploadistaContext(): UploadistaContextValue;
1281
1281
  //#endregion
1282
1282
  export { SimpleFlowUploadListItemProps as C, FlowInputProps as E, SimpleFlowUploadListItem as S, FlowInput as T, SimpleFlowUploadZoneProps as _, UploadZone as a, FlowUploadListRenderProps as b, SimpleUploadListItem as c, UploadListProps as d, UploadListRenderProps as f, SimpleFlowUploadZone as g, FlowUploadZoneRenderProps as h, SimpleUploadZoneProps as i, SimpleUploadListItemProps as l, FlowUploadZoneProps as m, useUploadistaContext as n, UploadZoneProps as o, FlowUploadZone as p, SimpleUploadZone as r, UploadZoneRenderProps as s, UploadistaProvider as t, UploadList as u, FlowUploadList as v, SimpleFlowUploadListProps as w, SimpleFlowUploadList as x, FlowUploadListProps as y };
1283
- //# sourceMappingURL=uploadista-provider-Dn-IiRxx.d.mts.map
1283
+ //# sourceMappingURL=uploadista-provider-BeHP_vze.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uploadista-provider-Dn-IiRxx.d.mts","names":[],"sources":["../src/components/flow-input.tsx","../src/components/flow-upload-list.tsx","../src/components/flow-upload-zone.tsx","../src/components/upload-list.tsx","../src/components/upload-zone.tsx","../src/components/uploadista-provider.tsx"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"uploadista-provider-BeHP_vze.d.mts","names":[],"sources":["../src/components/flow-input.tsx","../src/components/flow-upload-list.tsx","../src/components/flow-upload-zone.tsx","../src/components/upload-list.tsx","../src/components/upload-zone.tsx","../src/components/uploadista-provider.tsx"],"sourcesContent":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-upload-metrics-DhzS4lhG.d.mts","names":[],"sources":["../src/hooks/event-utils.ts","../src/hooks/use-uploadista-events.ts","../src/hooks/use-flow-events.ts","../src/hooks/use-upload-events.ts","../src/hooks/use-flow-execution.ts","../src/hooks/use-multi-flow-upload.ts","../src/hooks/use-upload-metrics.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"use-upload-metrics-DhzS4lhG.d.mts","names":[],"sources":["../src/hooks/event-utils.ts","../src/hooks/use-uploadista-events.ts","../src/hooks/use-flow-events.ts","../src/hooks/use-upload-events.ts","../src/hooks/use-flow-execution.ts","../src/hooks/use-multi-flow-upload.ts","../src/hooks/use-upload-metrics.ts"],"sourcesContent":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{s as e,u as t}from"./use-upload-BDHVhQsI.mjs";import{EventType as n}from"@uploadista/core/flow";import{UploadEventType as r}from"@uploadista/core/types";import i,{useCallback as a,useEffect as o,useRef as s,useState as c}from"react";function l(e){if(!(`eventType`in e))return!1;let t=e;return t.eventType===n.JobStart||t.eventType===n.JobEnd||t.eventType===n.FlowStart||t.eventType===n.FlowEnd||t.eventType===n.FlowError||t.eventType===n.FlowPause||t.eventType===n.FlowCancel||t.eventType===n.NodeStart||t.eventType===n.NodeEnd||t.eventType===n.NodePause||t.eventType===n.NodeResume||t.eventType===n.NodeError||t.eventType===n.NodeStream||t.eventType===n.NodeResponse}function u(e){if(!(`type`in e))return!1;let t=e;return t.type===r.UPLOAD_STARTED||t.type===r.UPLOAD_PROGRESS||t.type===r.UPLOAD_COMPLETE||t.type===r.UPLOAD_FAILED||t.type===r.UPLOAD_VALIDATION_SUCCESS||t.type===r.UPLOAD_VALIDATION_FAILED||t.type===r.UPLOAD_VALIDATION_WARNING}function d(t){let{subscribeToEvents:n}=e();o(()=>n(t),[n,t])}function f(t){let{subscribeToEvents:r}=e();o(()=>r(e=>{if(l(e))switch(e.eventType){case n.JobStart:t.onJobStart?.(e);break;case n.JobEnd:t.onJobEnd?.(e);break;case n.FlowStart:t.onFlowStart?.(e);break;case n.FlowEnd:t.onFlowEnd?.(e);break;case n.FlowError:t.onFlowError?.(e);break;case n.FlowPause:t.onFlowPause?.(e);break;case n.FlowCancel:t.onFlowCancel?.(e);break;case n.NodeStart:t.onNodeStart?.(e);break;case n.NodeEnd:t.onNodeEnd?.(e);break;case n.NodePause:t.onNodePause?.(e);break;case n.NodeResume:t.onNodeResume?.(e);break;case n.NodeError:t.onNodeError?.(e);break}}),[r,t])}function p(t){let{subscribeToEvents:n}=e();o(()=>n(e=>{if(!u(e))return;let n=`flow`in e?e.flow:void 0;switch(e.type){case r.UPLOAD_STARTED:t.onUploadStarted?.({...e.data,flow:n});break;case r.UPLOAD_PROGRESS:t.onUploadProgress?.({...e.data,flow:n});break;case r.UPLOAD_COMPLETE:t.onUploadComplete?.({...e.data,flow:n});break;case r.UPLOAD_FAILED:t.onUploadFailed?.({...e.data,flow:n});break;case r.UPLOAD_VALIDATION_SUCCESS:t.onUploadValidationSuccess?.({...e.data,flow:n});break;case r.UPLOAD_VALIDATION_FAILED:t.onUploadValidationFailed?.({...e.data,flow:n});break;case r.UPLOAD_VALIDATION_WARNING:t.onUploadValidationWarning?.({...e.data,flow:n});break}}),[n,t])}const m={status:`idle`,progress:0,bytesUploaded:0,totalBytes:null,error:null,jobId:null,flowStarted:!1,currentNodeName:null,currentNodeType:null,flowOutputs:null};function h(n){let{client:r}=e(),{getManager:i,releaseManager:l}=t(),[u,d]=c(m),[f,p]=c(null),[h,g]=c(!1),[_,v]=c({}),[y,b]=c(new Map),x=s(null),S=s(n);return o(()=>{S.current=n}),o(()=>{(async()=>{g(!0);try{let{flow:e}=await r.getFlow(n.flowConfig.flowId),t=e.nodes.filter(e=>e.type===`input`);console.log(`inputNodes`,t),p(t.map(e=>({nodeId:e.id,nodeName:e.name,nodeDescription:e.description,nodeTypeId:e.nodeTypeId,required:!0})))}catch(e){console.error(`Failed to discover flow inputs:`,e)}finally{g(!1)}})()},[r,n.flowConfig.flowId]),o(()=>{let e=n.flowConfig.flowId;x.current=i(e,{onStateChange:e=>{d(e)},onProgress:(e,t,n)=>{S.current.onProgress?.(e,t,n)},onChunkComplete:(e,t,n)=>{S.current.onChunkComplete?.(e,t,n)},onFlowComplete:e=>{S.current.onFlowComplete?.(e)},onSuccess:e=>{S.current.onSuccess?.(e)},onError:e=>{S.current.onError?.(e)},onAbort:()=>{S.current.onAbort?.()}},n);let t=setInterval(()=>{if(x.current){let e=x.current.getInputStates();e.size>0&&b(new Map(e))}},100);return()=>{clearInterval(t),l(e),x.current=null}},[n.flowConfig.flowId,n.flowConfig.storageId,n.flowConfig.outputNodeId,i,l]),{state:u,inputMetadata:f,inputStates:y,inputs:_,setInput:a((e,t)=>{v(n=>({...n,[e]:t}))},[]),execute:a(async()=>{if(!x.current)throw Error(`FlowManager not initialized`);if(Object.keys(_).length===0)throw Error(`No inputs provided. Use setInput() to provide inputs before calling execute()`);await x.current.executeFlow(_)},[_]),upload:a(async e=>{if(!x.current)throw Error(`FlowManager not initialized`);if(f&&f.length>0){let t=f[0];if(!t)throw Error(`No input nodes found`);v({[t.nodeId]:e}),await x.current.executeFlow({[t.nodeId]:e})}else await x.current.upload(e)},[f]),abort:a(()=>{x.current?.abort()},[]),pause:a(()=>{x.current?.pause()},[]),reset:a(()=>{x.current?.reset(),v({}),b(new Map)},[]),isUploading:u.status===`uploading`||u.status===`processing`,isUploadingFile:u.status===`uploading`,isProcessing:u.status===`processing`,isDiscoveringInputs:h}}const g={status:`idle`,progress:0,bytesUploaded:0,totalBytes:null,error:null,jobId:null,flowStarted:!1,currentNodeName:null,currentNodeType:null,flowOutputs:null};function _(n){let{client:r}=e(),{getManager:i,releaseManager:l}=t(),[u,d]=c(g),f=s(null),p=s(n),m=s(n.inputBuilder);return o(()=>{p.current=n,m.current=n.inputBuilder}),o(()=>{let e=n.flowConfig.flowId;return f.current=i(e,{onStateChange:d,onProgress:(e,t,n)=>{p.current.onProgress?.(e,t,n)},onChunkComplete:(e,t,n)=>{p.current.onChunkComplete?.(e,t,n)},onFlowComplete:e=>{p.current.onFlowComplete?.(e)},onSuccess:e=>{p.current.onSuccess?.(e)},onError:e=>{p.current.onError?.(e)},onAbort:()=>{p.current.onAbort?.()}},{flowConfig:n.flowConfig}),()=>{f.current&&=(l(e),null)}},[n.flowConfig.flowId,i,l,n]),{state:u,execute:a(async e=>{try{let t=await m.current(e),i=Object.keys(t)[0];if(!i)throw Error(`flowInputs must contain at least one input node`);let a=t[i];typeof a==`object`&&a&&`operation`in a&&a.operation===`init`?f.current&&await f.current.upload(e):(d(e=>({...e,status:`processing`,flowStarted:!0})),(await r.executeFlowWithInputs(n.flowConfig.flowId,t,{storageId:n.flowConfig.storageId,onJobStart:e=>{d(t=>({...t,jobId:e})),p.current.onJobStart?.(e)}})).job?.id||d(e=>({...e,status:`success`,progress:100,flowStarted:!0})))}catch(e){let t=e instanceof Error?e:Error(String(e));d(e=>({...e,status:`error`,error:t})),p.current.onError?.(t)}},[]),abort:a(()=>{f.current&&f.current.abort()},[]),pause:a(()=>{f.current&&f.current.pause()},[]),reset:a(()=>{if(f.current){let e=n.flowConfig.flowId;f.current.reset(),f.current.cleanup(),l(e),f.current=null}d(g)},[n.flowConfig.flowId,l]),isExecuting:u.status===`uploading`||u.status===`processing`,isUploadingFile:u.status===`uploading`,isProcessing:u.status===`processing`}}const v={totalBytesUploaded:0,totalBytes:0,averageSpeed:0,currentSpeed:0,estimatedTimeRemaining:null,totalFiles:0,completedFiles:0,activeUploads:0,progress:0,peakSpeed:0,startTime:null,endTime:null,totalDuration:null,insights:{overallEfficiency:0,chunkingEffectiveness:0,networkStability:0,recommendations:[],optimalChunkSizeRange:{min:256*1024,max:2*1024*1024}},sessionMetrics:[],chunkMetrics:[]};function y(t={}){let{speedCalculationInterval:n=1e3,speedSampleSize:r=10,onMetricsUpdate:o,onFileStart:l,onFileProgress:u,onFileComplete:d}=t,f=e(),[p,m]=c(v),[h,g]=c([]),_=s([]),y=s(0),b=s(null),x=a((e,t)=>{let n={time:e,bytes:t};_.current.push(n),_.current.length>r&&(_.current=_.current.slice(-r));let i=0;if(_.current.length>=2){let e=_.current[_.current.length-1],t=_.current[_.current.length-2];if(e&&t){let n=(e.time-t.time)/1e3,r=e.bytes-t.bytes;i=n>0?r/n:0}}let a=0;if(_.current.length>=2){let e=_.current[0],t=_.current[_.current.length-1];if(e&&t){let n=(t.time-e.time)/1e3,r=t.bytes-e.bytes;a=n>0?r/n:0}}return{currentSpeed:i,averageSpeed:a}},[r]),S=a(()=>{let e=Date.now(),t=h.reduce((e,t)=>e+t.size,0),n=h.reduce((e,t)=>e+t.bytesUploaded,0),r=h.filter(e=>e.isComplete).length,i=h.filter(e=>!e.isComplete&&e.bytesUploaded>0).length,{currentSpeed:a,averageSpeed:s}=x(e,n),c=t>0?Math.round(n/t*100):0,l=null;a>0&&(l=(t-n)/a*1e3);let u=h.filter(e=>e.startTime>0),d=u.length>0?Math.min(...u.map(e=>e.startTime)):null,g=h.filter(e=>e.endTime!==null),_=g.length>0&&r===h.length?Math.max(...g.map(e=>e.endTime).filter(e=>e!==null)):null,v=d&&_?_-d:null,y={totalBytesUploaded:n,totalBytes:t,averageSpeed:s,currentSpeed:a,estimatedTimeRemaining:l,totalFiles:h.length,completedFiles:r,activeUploads:i,progress:c,peakSpeed:Math.max(p.peakSpeed,a),startTime:d,endTime:_,totalDuration:v,insights:f.client.getChunkingInsights(),sessionMetrics:[f.client.exportMetrics().session],chunkMetrics:f.client.exportMetrics().chunks};m(y),o?.(y)},[h,p.peakSpeed,x,o,f.client]),C=a(()=>(b.current&&clearInterval(b.current),b.current=setInterval(()=>{h.some(e=>!e.isComplete&&e.bytesUploaded>0)&&S()},n),()=>{b.current&&=(clearInterval(b.current),null)}),[n,S,h]),w=a((e,t,n)=>{let r={id:e,filename:t,size:n,bytesUploaded:0,progress:0,speed:0,startTime:Date.now(),endTime:null,duration:null,isComplete:!1};g(t=>t.find(t=>t.id===e)?t.map(t=>t.id===e?r:t):[...t,r]),l?.(r),h.filter(e=>!e.isComplete).length===0&&C()},[h,l,C]),T=a((e,t)=>{let n=Date.now();g(r=>r.map(r=>{if(r.id!==e)return r;let i=(n-r.startTime)/1e3,a=i>0?t/i:0,o=r.size>0?Math.round(t/r.size*100):0,s={...r,bytesUploaded:t,progress:o,speed:a};return u?.(s),s})),setTimeout(S,0)},[u,S]),E=a(e=>{let t=Date.now();g(n=>n.map(n=>{if(n.id!==e)return n;let r=t-n.startTime,i=r>0?n.size/r*1e3:0,a={...n,bytesUploaded:n.size,progress:100,speed:i,endTime:t,duration:r,isComplete:!0};return d?.(a),a})),setTimeout(S,0)},[d,S]),D=a(e=>{g(t=>t.filter(t=>t.id!==e)),setTimeout(S,0)},[S]),O=a(()=>{b.current&&=(clearInterval(b.current),null),m(v),g([]),_.current=[],y.current=0},[]),k=a(e=>h.find(t=>t.id===e),[h]),A=a(()=>({overall:p,files:h,exportTime:Date.now()}),[p,h]);return i.useEffect(()=>()=>{b.current&&clearInterval(b.current)},[]),{metrics:p,fileMetrics:h,startFileUpload:w,updateFileProgress:T,completeFileUpload:E,removeFile:D,reset:O,getFileMetrics:k,exportMetrics:A}}export{f as a,u as c,p as i,_ as n,d as o,h as r,l as s,y as t};
2
+ //# sourceMappingURL=use-upload-metrics-OAofTcgA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-upload-metrics-OAofTcgA.mjs","names":["initialState: FlowUploadState","initialState","initialState: FlowUploadState","initialMetrics: UploadMetrics","estimatedTimeRemaining: number | null","newMetrics: UploadMetrics","fileMetric: FileUploadMetrics"],"sources":["../src/hooks/event-utils.ts","../src/hooks/use-uploadista-events.ts","../src/hooks/use-flow-events.ts","../src/hooks/use-upload-events.ts","../src/hooks/use-flow.ts","../src/hooks/use-flow-execution.ts","../src/hooks/use-upload-metrics.ts"],"sourcesContent":["import type { UploadistaEvent } from \"@uploadista/client-browser\";\nimport { EventType, type FlowEvent } from \"@uploadista/core/flow\";\nimport { UploadEventType, type UploadEvent } from \"@uploadista/core/types\";\n\n/**\n * Type guard to check if an event is a flow event\n */\nexport function isFlowEvent(event: UploadistaEvent): event is FlowEvent {\n if (!(\"eventType\" in event)) return false;\n const e = event as { eventType: unknown };\n return (\n e.eventType === EventType.JobStart ||\n e.eventType === EventType.JobEnd ||\n e.eventType === EventType.FlowStart ||\n e.eventType === EventType.FlowEnd ||\n e.eventType === EventType.FlowError ||\n e.eventType === EventType.FlowPause ||\n e.eventType === EventType.FlowCancel ||\n e.eventType === EventType.NodeStart ||\n e.eventType === EventType.NodeEnd ||\n e.eventType === EventType.NodePause ||\n e.eventType === EventType.NodeResume ||\n e.eventType === EventType.NodeError ||\n e.eventType === EventType.NodeStream ||\n e.eventType === EventType.NodeResponse\n );\n}\n\n/**\n * Type guard to check if an event is an upload event\n */\nexport function isUploadEvent(event: UploadistaEvent): event is UploadEvent {\n if (!(\"type\" in event)) return false;\n const e = event as { type: unknown };\n return (\n e.type === UploadEventType.UPLOAD_STARTED ||\n e.type === UploadEventType.UPLOAD_PROGRESS ||\n e.type === UploadEventType.UPLOAD_COMPLETE ||\n e.type === UploadEventType.UPLOAD_FAILED ||\n e.type === UploadEventType.UPLOAD_VALIDATION_SUCCESS ||\n e.type === UploadEventType.UPLOAD_VALIDATION_FAILED ||\n e.type === UploadEventType.UPLOAD_VALIDATION_WARNING\n );\n}\n","import type { UploadistaEvent } from \"@uploadista/client-core\";\nimport { useEffect } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\n\n/**\n * Simple hook that subscribes to all Uploadista events (both flow and upload events).\n *\n * This is a low-level hook that provides access to all events. For more structured\n * event handling, consider using `useFlowEvents` or `useUploadEvents` instead.\n *\n * Must be used within UploadistaProvider.\n *\n * @param callback - Function called for every event emitted by the Uploadista client\n *\n * @example\n * ```tsx\n * import { useUploadistaEvents, isFlowEvent, isUploadEvent } from '@uploadista/react';\n *\n * function MyComponent() {\n * useUploadistaEvents((event) => {\n * if (isFlowEvent(event)) {\n * console.log('Flow event:', event.eventType);\n * } else if (isUploadEvent(event)) {\n * console.log('Upload event:', event.type);\n * }\n * });\n *\n * return <div>Listening to all events...</div>;\n * }\n * ```\n */\nexport function useUploadistaEvents(\n callback: (event: UploadistaEvent) => void,\n): void {\n const { subscribeToEvents } = useUploadistaContext();\n\n useEffect(() => {\n const unsubscribe = subscribeToEvents(callback);\n return unsubscribe;\n }, [subscribeToEvents, callback]);\n}\n","import type {\n FlowEventFlowCancel,\n FlowEventFlowEnd,\n FlowEventFlowError,\n FlowEventFlowPause,\n FlowEventFlowStart,\n FlowEventJobEnd,\n FlowEventJobStart,\n FlowEventNodeEnd,\n FlowEventNodeError,\n FlowEventNodePause,\n FlowEventNodeResume,\n FlowEventNodeStart,\n} from \"@uploadista/core/flow\";\nimport { EventType } from \"@uploadista/core/flow\";\nimport { useEffect } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\nimport { isFlowEvent } from \"./event-utils\";\n\n/**\n * Options for handling flow execution events.\n *\n * All callbacks are optional - only provide handlers for events you care about.\n */\nexport interface UseFlowEventsOptions {\n /** Called when a job starts execution */\n onJobStart?: (event: FlowEventJobStart) => void;\n /** Called when a job completes (success or failure) */\n onJobEnd?: (event: FlowEventJobEnd) => void;\n /** Called when a flow begins execution */\n onFlowStart?: (event: FlowEventFlowStart) => void;\n /** Called when a flow completes successfully */\n onFlowEnd?: (event: FlowEventFlowEnd) => void;\n /** Called when a flow encounters an error */\n onFlowError?: (event: FlowEventFlowError) => void;\n /** Called when a flow is paused by user request */\n onFlowPause?: (event: FlowEventFlowPause) => void;\n /** Called when a flow is cancelled by user request */\n onFlowCancel?: (event: FlowEventFlowCancel) => void;\n /** Called when a node starts processing */\n onNodeStart?: (event: FlowEventNodeStart) => void;\n /** Called when a node completes successfully */\n onNodeEnd?: (event: FlowEventNodeEnd) => void;\n /** Called when a node pauses (waiting for additional data) */\n onNodePause?: (event: FlowEventNodePause) => void;\n /** Called when a paused node resumes execution */\n onNodeResume?: (event: FlowEventNodeResume) => void;\n /** Called when a node encounters an error */\n onNodeError?: (event: FlowEventNodeError) => void;\n}\n\n/**\n * Structured hook for handling flow execution events with type-safe callbacks.\n *\n * This hook provides a clean API for listening to specific flow events without\n * needing to manually filter events or use type guards.\n *\n * Must be used within UploadistaProvider.\n *\n * @param options - Object with optional callbacks for each flow event type\n *\n * @example\n * ```tsx\n * import { useFlowEvents } from '@uploadista/react';\n *\n * function FlowMonitor() {\n * useFlowEvents({\n * onFlowStart: (event) => {\n * console.log('Flow started:', event.flowId);\n * },\n * onNodeStart: (event) => {\n * console.log('Node started:', event.nodeName);\n * },\n * onNodeEnd: (event) => {\n * console.log('Node completed:', event.nodeName, event.result);\n * },\n * onFlowEnd: (event) => {\n * console.log('Flow completed with outputs:', event.outputs);\n * },\n * onFlowError: (event) => {\n * console.error('Flow failed:', event.error);\n * },\n * });\n *\n * return <div>Monitoring flow execution...</div>;\n * }\n * ```\n */\nexport function useFlowEvents(options: UseFlowEventsOptions): void {\n const { subscribeToEvents } = useUploadistaContext();\n\n useEffect(() => {\n const unsubscribe = subscribeToEvents((event) => {\n // Only handle flow events\n if (!isFlowEvent(event)) return;\n\n // Route to appropriate callback based on event type\n switch (event.eventType) {\n case EventType.JobStart:\n options.onJobStart?.(event);\n break;\n case EventType.JobEnd:\n options.onJobEnd?.(event);\n break;\n case EventType.FlowStart:\n options.onFlowStart?.(event);\n break;\n case EventType.FlowEnd:\n options.onFlowEnd?.(event);\n break;\n case EventType.FlowError:\n options.onFlowError?.(event);\n break;\n case EventType.FlowPause:\n options.onFlowPause?.(event);\n break;\n case EventType.FlowCancel:\n options.onFlowCancel?.(event);\n break;\n case EventType.NodeStart:\n options.onNodeStart?.(event);\n break;\n case EventType.NodeEnd:\n options.onNodeEnd?.(event);\n break;\n case EventType.NodePause:\n options.onNodePause?.(event);\n break;\n case EventType.NodeResume:\n options.onNodeResume?.(event);\n break;\n case EventType.NodeError:\n options.onNodeError?.(event);\n break;\n }\n });\n\n return unsubscribe;\n }, [subscribeToEvents, options]);\n}\n","import { UploadEventType, type UploadEvent } from \"@uploadista/core/types\";\nimport { useEffect } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\nimport { isUploadEvent } from \"./event-utils\";\n\n/**\n * Upload progress event data\n */\nexport interface UploadProgressEventData {\n id: string;\n progress: number;\n total: number;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Upload started/complete event data (contains full UploadFile)\n */\nexport interface UploadFileEventData {\n // This will contain the full UploadFile schema\n [key: string]: unknown;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Upload failed event data\n */\nexport interface UploadFailedEventData {\n id: string;\n error: string;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Upload validation success event data\n */\nexport interface UploadValidationSuccessEventData {\n id: string;\n validationType: \"checksum\" | \"mimetype\";\n algorithm?: string;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Upload validation failed event data\n */\nexport interface UploadValidationFailedEventData {\n id: string;\n reason: string;\n expected: string;\n actual: string;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Upload validation warning event data\n */\nexport interface UploadValidationWarningEventData {\n id: string;\n message: string;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Options for handling upload events.\n *\n * All callbacks are optional - only provide handlers for events you care about.\n */\nexport interface UseUploadEventsOptions {\n /** Called when an upload starts */\n onUploadStarted?: (data: UploadFileEventData) => void;\n /** Called with upload progress updates */\n onUploadProgress?: (data: UploadProgressEventData) => void;\n /** Called when an upload completes successfully */\n onUploadComplete?: (data: UploadFileEventData) => void;\n /** Called when an upload fails */\n onUploadFailed?: (data: UploadFailedEventData) => void;\n /** Called when upload validation succeeds */\n onUploadValidationSuccess?: (data: UploadValidationSuccessEventData) => void;\n /** Called when upload validation fails */\n onUploadValidationFailed?: (data: UploadValidationFailedEventData) => void;\n /** Called when upload validation produces a warning */\n onUploadValidationWarning?: (data: UploadValidationWarningEventData) => void;\n}\n\n/**\n * Structured hook for handling upload events with type-safe callbacks.\n *\n * This hook provides a clean API for listening to specific upload events without\n * needing to manually filter events or use type guards.\n *\n * Must be used within UploadistaProvider.\n *\n * @param options - Object with optional callbacks for each upload event type\n *\n * @example\n * ```tsx\n * import { useUploadEvents } from '@uploadista/react';\n *\n * function UploadMonitor() {\n * useUploadEvents({\n * onUploadStarted: (data) => {\n * console.log('Upload started:', data.id);\n * },\n * onUploadProgress: (data) => {\n * const percent = (data.progress / data.total) * 100;\n * console.log(`Upload progress: ${percent}%`);\n * },\n * onUploadComplete: (data) => {\n * console.log('Upload completed:', data);\n * },\n * onUploadFailed: (data) => {\n * console.error('Upload failed:', data.error);\n * },\n * });\n *\n * return <div>Monitoring uploads...</div>;\n * }\n * ```\n */\nexport function useUploadEvents(options: UseUploadEventsOptions): void {\n const { subscribeToEvents } = useUploadistaContext();\n\n useEffect(() => {\n const unsubscribe = subscribeToEvents((event) => {\n // Only handle upload events\n if (!isUploadEvent(event)) return;\n\n // Route to appropriate callback based on event type\n // Note: flow context is at the top level of the event, not inside data\n const flowContext = \"flow\" in event ? event.flow : undefined;\n\n switch (event.type) {\n case UploadEventType.UPLOAD_STARTED:\n options.onUploadStarted?.({\n ...(event.data as unknown as Omit<UploadFileEventData, \"flow\">),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_PROGRESS:\n options.onUploadProgress?.({\n ...(event.data as unknown as Omit<\n UploadProgressEventData,\n \"flow\"\n >),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_COMPLETE:\n options.onUploadComplete?.({\n ...(event.data as unknown as Omit<UploadFileEventData, \"flow\">),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_FAILED:\n options.onUploadFailed?.({\n ...(event.data as unknown as Omit<UploadFailedEventData, \"flow\">),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_VALIDATION_SUCCESS:\n options.onUploadValidationSuccess?.({\n ...(event.data as unknown as Omit<\n UploadValidationSuccessEventData,\n \"flow\"\n >),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_VALIDATION_FAILED:\n options.onUploadValidationFailed?.({\n ...(event.data as unknown as Omit<\n UploadValidationFailedEventData,\n \"flow\"\n >),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_VALIDATION_WARNING:\n options.onUploadValidationWarning?.({\n ...(event.data as unknown as Omit<\n UploadValidationWarningEventData,\n \"flow\"\n >),\n flow: flowContext,\n });\n break;\n }\n });\n\n return unsubscribe;\n }, [subscribeToEvents, options]);\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 node type */\n nodeTypeId: 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 console.log(\"inputNodes\", inputNodes);\n\n const metadata: FlowInputMetadata[] = inputNodes.map((node) => ({\n nodeId: node.id,\n nodeName: node.name,\n nodeDescription: node.description,\n nodeTypeId: node.nodeTypeId,\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","/**\n * Generic React hook for flexible flow execution with arbitrary input types.\n *\n * This hook provides a flexible interface for executing flows with different input types:\n * - File/Blob: Traditional chunked file upload\n * - string (URL): Direct file fetch from external URL\n * - object: Structured data for custom input nodes\n *\n * The hook uses an inputBuilder pattern to transform trigger data into flow inputs,\n * enabling dynamic input preparation and validation before flow execution.\n *\n * @module hooks/use-flow-execution\n *\n * @example\n * ```tsx\n * // URL-based flow execution\n * function UrlImageProcessor() {\n * const execution = useFlowExecution<string>({\n * flowConfig: {\n * flowId: \"image-optimize\",\n * storageId: \"s3\"\n * },\n * inputBuilder: async (url) => {\n * // Find the input node\n * const { inputNodes, single } = await client.findInputNode(\"image-optimize\");\n * if (!single) throw new Error(\"Expected single input node\");\n *\n * return {\n * [inputNodes[0].id]: {\n * operation: \"url\",\n * url,\n * metadata: { source: \"external\" }\n * }\n * };\n * },\n * onSuccess: (outputs) => console.log(\"Done:\", outputs)\n * });\n *\n * return (\n * <button onClick={() => execution.execute(\"https://example.com/image.jpg\")}>\n * Process URL\n * </button>\n * );\n * }\n * ```\n */\n\nimport type { FlowUploadOptions } from \"@uploadista/client-browser\";\nimport type {\n FlowInputs,\n FlowManager,\n FlowUploadState,\n FlowUploadStatus,\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 for convenience\nexport type { FlowUploadState, FlowUploadStatus };\n\n/**\n * Input builder function that transforms trigger data into flow inputs.\n *\n * The builder receives the trigger data passed to execute() and returns\n * a FlowInputs object mapping node IDs to their input data.\n *\n * @template TTrigger - The type of data passed to execute()\n * @param trigger - The trigger data (e.g., File, URL string, structured data)\n * @returns Promise resolving to FlowInputs mapping or the mapping directly\n *\n * @example\n * ```typescript\n * // File upload builder\n * const fileBuilder: InputBuilder<File> = async (file) => ({\n * \"input-node\": {\n * operation: \"init\",\n * storageId: \"s3\",\n * metadata: { originalName: file.name, size: file.size }\n * }\n * });\n *\n * // URL fetch builder\n * const urlBuilder: InputBuilder<string> = (url) => ({\n * \"input-node\": {\n * operation: \"url\",\n * url,\n * metadata: { source: \"external\" }\n * }\n * });\n * ```\n */\nexport type InputBuilder<TTrigger = unknown> = (\n trigger: TTrigger,\n) => Promise<FlowInputs> | FlowInputs;\n\n/**\n * Options for the useFlowExecution hook.\n *\n * @template TTrigger - The type of trigger data passed to execute()\n * @template TOutput - The expected output type from the flow\n *\n * @property flowConfig - Flow configuration (flowId, storageId, etc.)\n * @property inputBuilder - Function to build flow inputs from trigger data\n * @property onJobStart - Called when flow job is created\n * @property onProgress - Called during upload progress (if applicable)\n * @property onChunkComplete - Called when upload chunk completes (if applicable)\n * @property onSuccess - Called with typed outputs when flow succeeds\n * @property onFlowComplete - Called with all outputs when flow completes\n * @property onError - Called when execution fails\n * @property onAbort - Called when execution is aborted\n * @property onShouldRetry - Custom retry logic (if applicable)\n */\nexport interface UseFlowExecutionOptions<\n TTrigger = unknown,\n TOutput = TypedOutput[],\n> {\n /**\n * Flow configuration\n */\n flowConfig: FlowUploadOptions[\"flowConfig\"];\n\n /**\n * Function to build flow inputs from trigger data.\n * Can be async to perform validation, API calls, etc.\n */\n inputBuilder: InputBuilder<TTrigger>;\n\n /**\n * Called when the flow job starts\n */\n onJobStart?: (jobId: string) => void;\n\n /**\n * Called during upload progress (for file uploads)\n */\n onProgress?: (\n uploadId: string,\n bytesUploaded: number,\n totalBytes: number | null,\n ) => void;\n\n /**\n * Called when an upload chunk completes (for file uploads)\n */\n onChunkComplete?: (\n chunkSize: number,\n bytesAccepted: number,\n bytesTotal: number | null,\n ) => void;\n\n /**\n * Called when flow execution succeeds with final outputs\n */\n onSuccess?: (outputs: TOutput) => void;\n\n /**\n * Called when flow completes (alternative to onSuccess)\n */\n onFlowComplete?: (outputs: TypedOutput[]) => void;\n\n /**\n * Called when execution fails\n */\n onError?: (error: Error) => void;\n\n /**\n * Called when execution is aborted\n */\n onAbort?: () => void;\n\n /**\n * Custom retry logic (for file uploads)\n */\n onShouldRetry?: (error: Error, retryAttempt: number) => boolean;\n}\n\n/**\n * Return value from useFlowExecution hook.\n *\n * @template TTrigger - The type of trigger data passed to execute()\n *\n * @property state - Current execution state with progress and outputs\n * @property execute - Function to trigger flow execution\n * @property abort - Cancel the current execution\n * @property pause - Pause the current execution (for file uploads)\n * @property reset - Reset state to idle\n * @property isExecuting - True when execution is active\n * @property isUploadingFile - True during file upload phase\n * @property isProcessing - True during flow processing phase\n */\nexport interface UseFlowExecutionReturn<TTrigger = unknown> {\n /**\n * Current execution state\n */\n state: FlowUploadState;\n\n /**\n * Execute the flow with trigger data\n */\n execute: (trigger: TTrigger) => Promise<void>;\n\n /**\n * Abort the current execution\n */\n abort: () => void;\n\n /**\n * Pause the current execution (if supported by input type)\n */\n pause: () => void;\n\n /**\n * Reset the execution state\n */\n reset: () => void;\n\n /**\n * Whether execution is active (uploading OR processing)\n */\n isExecuting: boolean;\n\n /**\n * Whether file upload is in progress\n */\n isUploadingFile: boolean;\n\n /**\n * Whether flow processing is in progress\n */\n isProcessing: 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 * Generic React hook for flexible flow execution.\n *\n * Provides a flexible interface for executing flows with arbitrary input types\n * through an inputBuilder pattern. The builder transforms trigger data into\n * flow inputs, enabling support for files, URLs, structured data, and more.\n *\n * Must be used within FlowManagerProvider (which must be within UploadistaProvider).\n *\n * @template TTrigger - The type of trigger data passed to execute()\n * @template TOutput - The expected output type from the flow\n *\n * @param options - Flow execution configuration with inputBuilder\n * @returns Execution state and control methods\n *\n * @example\n * ```tsx\n * // URL-based image processing\n * const urlExecution = useFlowExecution<string>({\n * flowConfig: { flowId: \"optimize\", storageId: \"s3\" },\n * inputBuilder: async (url) => {\n * const { inputNodes } = await client.findInputNode(\"optimize\");\n * return {\n * [inputNodes[0].id]: {\n * operation: \"url\",\n * url,\n * metadata: { source: \"external\" }\n * }\n * };\n * },\n * onSuccess: (outputs) => console.log(\"Processed:\", outputs)\n * });\n *\n * // Execute with URL\n * await urlExecution.execute(\"https://example.com/image.jpg\");\n *\n * // File upload (traditional pattern)\n * const fileExecution = useFlowExecution<File>({\n * flowConfig: { flowId: \"optimize\", storageId: \"s3\" },\n * inputBuilder: async (file) => {\n * const { inputNodes } = await client.findInputNode(\"optimize\");\n * return {\n * [inputNodes[0].id]: {\n * operation: \"init\",\n * storageId: \"s3\",\n * metadata: {\n * originalName: file.name,\n * mimeType: file.type,\n * size: file.size\n * }\n * }\n * };\n * }\n * });\n *\n * // Execute with file\n * await fileExecution.execute(myFile);\n * ```\n */\nexport function useFlowExecution<TTrigger = unknown, TOutput = TypedOutput[]>(\n options: UseFlowExecutionOptions<TTrigger, TOutput>,\n): UseFlowExecutionReturn<TTrigger> {\n const { client } = useUploadistaContext();\n const { getManager, releaseManager } = useFlowManagerContext();\n const [state, setState] = useState<FlowUploadState>(initialState);\n const managerRef = useRef<FlowManager<unknown> | null>(null);\n\n // Store callbacks and inputBuilder in refs for stable access\n const callbacksRef = useRef(options);\n const inputBuilderRef = useRef(options.inputBuilder);\n\n // Update refs when options change\n useEffect(() => {\n callbacksRef.current = options;\n inputBuilderRef.current = options.inputBuilder;\n });\n\n // Get or create manager from context\n useEffect(() => {\n const flowId = options.flowConfig.flowId;\n\n // Create stable callback wrappers\n const stableCallbacks = {\n onStateChange: setState,\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 as TOutput);\n },\n onError: (error: Error) => {\n callbacksRef.current.onError?.(error);\n },\n onAbort: () => {\n callbacksRef.current.onAbort?.();\n },\n };\n\n // Get or create manager for this flow\n const manager = getManager(flowId, stableCallbacks, {\n flowConfig: options.flowConfig,\n });\n managerRef.current = manager;\n\n return () => {\n if (managerRef.current) {\n releaseManager(flowId);\n managerRef.current = null;\n }\n };\n }, [options.flowConfig.flowId, getManager, releaseManager, options]);\n\n /**\n * Execute the flow with trigger data.\n * Calls inputBuilder to transform trigger into flow inputs.\n */\n const execute = useCallback(async (trigger: TTrigger) => {\n try {\n // Build flow inputs from trigger data\n const flowInputs = await inputBuilderRef.current(trigger);\n\n // For now, we need to determine if this is a file upload or URL operation\n // by inspecting the flowInputs structure\n const firstInputNodeId = Object.keys(flowInputs)[0];\n if (!firstInputNodeId) {\n throw new Error(\"flowInputs must contain at least one input node\");\n }\n const firstInput = flowInputs[firstInputNodeId];\n\n // Type guard: check if this is an init operation (file upload)\n const isFileUpload =\n typeof firstInput === \"object\" &&\n firstInput !== null &&\n \"operation\" in firstInput &&\n firstInput.operation === \"init\";\n\n if (isFileUpload) {\n // File upload path: use the standard upload mechanism\n // This requires the trigger to be a File/Blob\n if (managerRef.current) {\n await managerRef.current.upload(trigger as unknown);\n }\n } else {\n // Non-file path (URL, structured data, etc.)\n // Skip chunked upload and execute flow directly with provided inputs\n setState((prev) => ({\n ...prev,\n status: \"processing\",\n flowStarted: true,\n }));\n\n // Execute flow with the built inputs\n const result = await client.executeFlowWithInputs(\n options.flowConfig.flowId,\n flowInputs,\n {\n storageId: options.flowConfig.storageId,\n onJobStart: (jobId: string) => {\n setState((prev) => ({\n ...prev,\n jobId,\n }));\n callbacksRef.current.onJobStart?.(jobId);\n },\n },\n );\n\n // If job was created successfully, the FlowManager will handle\n // flow events via WebSocket and update state accordingly\n if (result.job?.id) {\n // State updates will come from flow events\n // Manager will receive FlowEnd event and update state to \"success\"\n } else {\n // No job created - treat as immediate completion\n setState((prev) => ({\n ...prev,\n status: \"success\",\n progress: 100,\n flowStarted: true,\n }));\n }\n }\n } catch (error) {\n // Handle inputBuilder errors\n const err = error instanceof Error ? error : new Error(String(error));\n setState((prev) => ({\n ...prev,\n status: \"error\",\n error: err,\n }));\n callbacksRef.current.onError?.(err);\n }\n }, []);\n\n /**\n * Abort the current execution\n */\n const abort = useCallback(() => {\n if (managerRef.current) {\n managerRef.current.abort();\n }\n }, []);\n\n /**\n * Pause the current execution\n */\n const pause = useCallback(() => {\n if (managerRef.current) {\n managerRef.current.pause();\n }\n }, []);\n\n /**\n * Reset the execution state\n */\n const reset = useCallback(() => {\n if (managerRef.current) {\n const flowId = options.flowConfig.flowId;\n managerRef.current.reset();\n managerRef.current.cleanup();\n releaseManager(flowId);\n managerRef.current = null;\n }\n setState(initialState);\n }, [options.flowConfig.flowId, releaseManager]);\n\n return {\n state,\n execute,\n abort,\n pause,\n reset,\n isExecuting: state.status === \"uploading\" || state.status === \"processing\",\n isUploadingFile: state.status === \"uploading\",\n isProcessing: state.status === \"processing\",\n };\n}\n","import type {\n ChunkMetrics,\n PerformanceInsights,\n UploadSessionMetrics,\n} from \"@uploadista/client-core\";\nimport React, { useCallback, useRef, useState } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\n\nexport type Timeout = ReturnType<typeof setInterval>;\n\nexport interface UploadMetrics {\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 * Overall upload speed in bytes per second\n */\n averageSpeed: number;\n\n /**\n * Current upload speed in bytes per second\n */\n currentSpeed: number;\n\n /**\n * Estimated time remaining in milliseconds\n */\n estimatedTimeRemaining: number | null;\n\n /**\n * Total number of files being tracked\n */\n totalFiles: number;\n\n /**\n * Number of files completed\n */\n completedFiles: number;\n\n /**\n * Number of files currently uploading\n */\n activeUploads: number;\n\n /**\n * Overall progress as percentage (0-100)\n */\n progress: number;\n\n /**\n * Peak upload speed achieved\n */\n peakSpeed: number;\n\n /**\n * Start time of the first upload\n */\n startTime: number | null;\n\n /**\n * End time of the last completed upload\n */\n endTime: number | null;\n\n /**\n * Total duration of all uploads\n */\n totalDuration: number | null;\n\n /**\n * Detailed performance insights from the upload client\n */\n insights: PerformanceInsights;\n\n /**\n * Session metrics for completed uploads\n */\n sessionMetrics: Partial<UploadSessionMetrics>[];\n\n /**\n * Detailed chunk metrics from recent uploads\n */\n chunkMetrics: ChunkMetrics[];\n}\n\nexport interface FileUploadMetrics {\n id: string;\n filename: string;\n size: number;\n bytesUploaded: number;\n progress: number;\n speed: number;\n startTime: number;\n endTime: number | null;\n duration: number | null;\n isComplete: boolean;\n}\n\nexport interface UseUploadMetricsOptions {\n /**\n * Interval for calculating current speed (in milliseconds)\n */\n speedCalculationInterval?: number;\n\n /**\n * Number of speed samples to keep for average calculation\n */\n speedSampleSize?: number;\n\n /**\n * Called when metrics are updated\n */\n onMetricsUpdate?: (metrics: UploadMetrics) => void;\n\n /**\n * Called when a file upload starts\n */\n onFileStart?: (fileMetrics: FileUploadMetrics) => void;\n\n /**\n * Called when a file upload progresses\n */\n onFileProgress?: (fileMetrics: FileUploadMetrics) => void;\n\n /**\n * Called when a file upload completes\n */\n onFileComplete?: (fileMetrics: FileUploadMetrics) => void;\n}\n\nexport interface UseUploadMetricsReturn {\n /**\n * Current overall metrics\n */\n metrics: UploadMetrics;\n\n /**\n * Individual file metrics\n */\n fileMetrics: FileUploadMetrics[];\n\n /**\n * Start tracking a new file upload\n */\n startFileUpload: (id: string, filename: string, size: number) => void;\n\n /**\n * Update progress for a file upload\n */\n updateFileProgress: (id: string, bytesUploaded: number) => void;\n\n /**\n * Mark a file upload as complete\n */\n completeFileUpload: (id: string) => void;\n\n /**\n * Remove a file from tracking\n */\n removeFile: (id: string) => void;\n\n /**\n * Reset all metrics\n */\n reset: () => void;\n\n /**\n * Get metrics for a specific file\n */\n getFileMetrics: (id: string) => FileUploadMetrics | undefined;\n\n /**\n * Export metrics as JSON\n */\n exportMetrics: () => {\n overall: UploadMetrics;\n files: FileUploadMetrics[];\n exportTime: number;\n };\n}\n\nconst initialMetrics: UploadMetrics = {\n totalBytesUploaded: 0,\n totalBytes: 0,\n averageSpeed: 0,\n currentSpeed: 0,\n estimatedTimeRemaining: null,\n totalFiles: 0,\n completedFiles: 0,\n activeUploads: 0,\n progress: 0,\n peakSpeed: 0,\n startTime: null,\n endTime: null,\n totalDuration: null,\n insights: {\n overallEfficiency: 0,\n chunkingEffectiveness: 0,\n networkStability: 0,\n recommendations: [],\n optimalChunkSizeRange: { min: 256 * 1024, max: 2 * 1024 * 1024 },\n },\n sessionMetrics: [],\n chunkMetrics: [],\n};\n\n/**\n * React hook for tracking detailed upload metrics and performance statistics.\n * Provides comprehensive monitoring of upload progress, speed, and timing data.\n *\n * @param options - Configuration and event handlers\n * @returns Upload metrics state and control methods\n *\n * @example\n * ```tsx\n * const uploadMetrics = useUploadMetrics({\n * speedCalculationInterval: 1000, // Update speed every second\n * speedSampleSize: 10, // Keep last 10 speed samples for average\n * onMetricsUpdate: (metrics) => {\n * console.log(`Overall progress: ${metrics.progress}%`);\n * console.log(`Speed: ${(metrics.currentSpeed / 1024).toFixed(1)} KB/s`);\n * console.log(`ETA: ${metrics.estimatedTimeRemaining}ms`);\n * },\n * onFileComplete: (fileMetrics) => {\n * console.log(`${fileMetrics.filename} completed in ${fileMetrics.duration}ms`);\n * },\n * });\n *\n * // Start tracking a file\n * const handleFileStart = (file: File) => {\n * uploadMetrics.startFileUpload(file.name, file.name, file.size);\n * };\n *\n * // Update progress during upload\n * const handleProgress = (fileId: string, bytesUploaded: number) => {\n * uploadMetrics.updateFileProgress(fileId, bytesUploaded);\n * };\n *\n * // Display metrics\n * return (\n * <div>\n * <div>Overall Progress: {uploadMetrics.metrics.progress}%</div>\n * <div>Speed: {(uploadMetrics.metrics.currentSpeed / 1024).toFixed(1)} KB/s</div>\n * <div>Files: {uploadMetrics.metrics.completedFiles}/{uploadMetrics.metrics.totalFiles}</div>\n *\n * {uploadMetrics.metrics.estimatedTimeRemaining && (\n * <div>ETA: {Math.round(uploadMetrics.metrics.estimatedTimeRemaining / 1000)}s</div>\n * )}\n *\n * {uploadMetrics.fileMetrics.map((file) => (\n * <div key={file.id}>\n * {file.filename}: {file.progress}% ({(file.speed / 1024).toFixed(1)} KB/s)\n * </div>\n * ))}\n * </div>\n * );\n * ```\n */\nexport function useUploadMetrics(\n options: UseUploadMetricsOptions = {},\n): UseUploadMetricsReturn {\n const {\n speedCalculationInterval = 1000,\n speedSampleSize = 10,\n onMetricsUpdate,\n onFileStart,\n onFileProgress,\n onFileComplete,\n } = options;\n\n const uploadClient = useUploadistaContext();\n\n const [metrics, setMetrics] = useState<UploadMetrics>(initialMetrics);\n const [fileMetrics, setFileMetrics] = useState<FileUploadMetrics[]>([]);\n\n const speedSamplesRef = useRef<Array<{ time: number; bytes: number }>>([]);\n const lastUpdateRef = useRef<number>(0);\n const intervalRef = useRef<Timeout | null>(null);\n\n const calculateSpeed = useCallback(\n (currentTime: number, totalBytesUploaded: number) => {\n const sample = { time: currentTime, bytes: totalBytesUploaded };\n speedSamplesRef.current.push(sample);\n\n // Keep only recent samples\n if (speedSamplesRef.current.length > speedSampleSize) {\n speedSamplesRef.current = speedSamplesRef.current.slice(\n -speedSampleSize,\n );\n }\n\n // Calculate current speed (bytes per second)\n let currentSpeed = 0;\n if (speedSamplesRef.current.length >= 2) {\n const recent =\n speedSamplesRef.current[speedSamplesRef.current.length - 1];\n const previous =\n speedSamplesRef.current[speedSamplesRef.current.length - 2];\n if (recent && previous) {\n const timeDiff = (recent.time - previous.time) / 1000; // Convert to seconds\n const bytesDiff = recent.bytes - previous.bytes;\n currentSpeed = timeDiff > 0 ? bytesDiff / timeDiff : 0;\n }\n }\n\n // Calculate average speed\n let averageSpeed = 0;\n if (speedSamplesRef.current.length >= 2) {\n const first = speedSamplesRef.current[0];\n const last =\n speedSamplesRef.current[speedSamplesRef.current.length - 1];\n if (first && last) {\n const totalTime = (last.time - first.time) / 1000; // Convert to seconds\n const totalBytes = last.bytes - first.bytes;\n averageSpeed = totalTime > 0 ? totalBytes / totalTime : 0;\n }\n }\n\n return { currentSpeed, averageSpeed };\n },\n [speedSampleSize],\n );\n\n const updateMetrics = useCallback(() => {\n const now = Date.now();\n\n // Calculate totals from file metrics\n const totalBytes = fileMetrics.reduce((sum, file) => sum + file.size, 0);\n const totalBytesUploaded = fileMetrics.reduce(\n (sum, file) => sum + file.bytesUploaded,\n 0,\n );\n const completedFiles = fileMetrics.filter((file) => file.isComplete).length;\n const activeUploads = fileMetrics.filter(\n (file) => !file.isComplete && file.bytesUploaded > 0,\n ).length;\n\n // Calculate speeds\n const { currentSpeed, averageSpeed } = calculateSpeed(\n now,\n totalBytesUploaded,\n );\n\n // Calculate progress\n const progress =\n totalBytes > 0 ? Math.round((totalBytesUploaded / totalBytes) * 100) : 0;\n\n // Calculate estimated time remaining\n let estimatedTimeRemaining: number | null = null;\n if (currentSpeed > 0) {\n const remainingBytes = totalBytes - totalBytesUploaded;\n estimatedTimeRemaining = (remainingBytes / currentSpeed) * 1000; // Convert to milliseconds\n }\n\n // Find start and end times\n const activeTimes = fileMetrics.filter((file) => file.startTime > 0);\n const startTime =\n activeTimes.length > 0\n ? Math.min(...activeTimes.map((file) => file.startTime))\n : null;\n\n const completedTimes = fileMetrics.filter((file) => file.endTime !== null);\n const endTime =\n completedTimes.length > 0 && completedFiles === fileMetrics.length\n ? Math.max(\n ...completedTimes\n .map((file) => file.endTime)\n .filter((time) => time !== null),\n )\n : null;\n\n const totalDuration = startTime && endTime ? endTime - startTime : null;\n\n const newMetrics: UploadMetrics = {\n totalBytesUploaded,\n totalBytes,\n averageSpeed,\n currentSpeed,\n estimatedTimeRemaining,\n totalFiles: fileMetrics.length,\n completedFiles,\n activeUploads,\n progress,\n peakSpeed: Math.max(metrics.peakSpeed, currentSpeed),\n startTime,\n endTime,\n totalDuration,\n insights: uploadClient.client.getChunkingInsights(),\n sessionMetrics: [uploadClient.client.exportMetrics().session],\n chunkMetrics: uploadClient.client.exportMetrics().chunks,\n };\n\n setMetrics(newMetrics);\n onMetricsUpdate?.(newMetrics);\n }, [\n fileMetrics,\n metrics.peakSpeed,\n calculateSpeed,\n onMetricsUpdate,\n uploadClient.client,\n ]);\n\n // Set up periodic speed calculations\n const setupSpeedCalculation = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n }\n\n intervalRef.current = setInterval(() => {\n if (\n fileMetrics.some((file) => !file.isComplete && file.bytesUploaded > 0)\n ) {\n updateMetrics();\n }\n }, speedCalculationInterval);\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [speedCalculationInterval, updateMetrics, fileMetrics]);\n\n const startFileUpload = useCallback(\n (id: string, filename: string, size: number) => {\n const now = Date.now();\n\n const fileMetric: FileUploadMetrics = {\n id,\n filename,\n size,\n bytesUploaded: 0,\n progress: 0,\n speed: 0,\n startTime: now,\n endTime: null,\n duration: null,\n isComplete: false,\n };\n\n setFileMetrics((prev) => {\n const existing = prev.find((file) => file.id === id);\n if (existing) {\n return prev.map((file) => (file.id === id ? fileMetric : file));\n }\n return [...prev, fileMetric];\n });\n\n onFileStart?.(fileMetric);\n\n // Start speed calculation if this is the first active upload\n if (fileMetrics.filter((file) => !file.isComplete).length === 0) {\n setupSpeedCalculation();\n }\n },\n [fileMetrics, onFileStart, setupSpeedCalculation],\n );\n\n const updateFileProgress = useCallback(\n (id: string, bytesUploaded: number) => {\n const now = Date.now();\n\n setFileMetrics((prev) =>\n prev.map((file) => {\n if (file.id !== id) return file;\n\n const timeDiff = (now - file.startTime) / 1000; // seconds\n const speed = timeDiff > 0 ? bytesUploaded / timeDiff : 0;\n const progress =\n file.size > 0 ? Math.round((bytesUploaded / file.size) * 100) : 0;\n\n const updatedFile = {\n ...file,\n bytesUploaded,\n progress,\n speed,\n };\n\n onFileProgress?.(updatedFile);\n return updatedFile;\n }),\n );\n\n // Trigger metrics update\n setTimeout(updateMetrics, 0);\n },\n [onFileProgress, updateMetrics],\n );\n\n const completeFileUpload = useCallback(\n (id: string) => {\n const now = Date.now();\n\n setFileMetrics((prev) =>\n prev.map((file) => {\n if (file.id !== id) return file;\n\n const duration = now - file.startTime;\n const speed = duration > 0 ? (file.size / duration) * 1000 : 0; // bytes per second\n\n const completedFile = {\n ...file,\n bytesUploaded: file.size,\n progress: 100,\n speed,\n endTime: now,\n duration,\n isComplete: true,\n };\n\n onFileComplete?.(completedFile);\n return completedFile;\n }),\n );\n\n // Trigger metrics update\n setTimeout(updateMetrics, 0);\n },\n [onFileComplete, updateMetrics],\n );\n\n const removeFile = useCallback(\n (id: string) => {\n setFileMetrics((prev) => prev.filter((file) => file.id !== id));\n setTimeout(updateMetrics, 0);\n },\n [updateMetrics],\n );\n\n const reset = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n\n setMetrics(initialMetrics);\n setFileMetrics([]);\n speedSamplesRef.current = [];\n lastUpdateRef.current = 0;\n }, []);\n\n const getFileMetrics = useCallback(\n (id: string) => {\n return fileMetrics.find((file) => file.id === id);\n },\n [fileMetrics],\n );\n\n const exportMetrics = useCallback(() => {\n return {\n overall: metrics,\n files: fileMetrics,\n exportTime: Date.now(),\n };\n }, [metrics, fileMetrics]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n }\n };\n }, []);\n\n return {\n metrics,\n fileMetrics,\n startFileUpload,\n updateFileProgress,\n completeFileUpload,\n removeFile,\n reset,\n getFileMetrics,\n exportMetrics,\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uploadista/react",
3
3
  "type": "module",
4
- "version": "0.0.17-beta.8",
4
+ "version": "0.0.17",
5
5
  "description": "React client for Uploadista",
6
6
  "license": "MIT",
7
7
  "author": "Uploadista",
@@ -22,16 +22,16 @@
22
22
  "dependencies": {
23
23
  "react": "19.2.0",
24
24
  "react-dom": "19.2.0",
25
- "@uploadista/core": "0.0.17-beta.8",
26
- "@uploadista/client-core": "0.0.17-beta.8",
27
- "@uploadista/client-browser": "0.0.17-beta.8"
25
+ "@uploadista/core": "0.0.17",
26
+ "@uploadista/client-core": "0.0.17",
27
+ "@uploadista/client-browser": "0.0.17"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/react": "19.2.7",
31
31
  "@types/react-dom": "19.2.3",
32
32
  "tsdown": "0.16.6",
33
33
  "vitest": "4.0.13",
34
- "@uploadista/typescript-config": "0.0.17-beta.8"
34
+ "@uploadista/typescript-config": "0.0.17"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsdown",
@@ -271,6 +271,8 @@ export function useFlow(options: FlowUploadOptions): UseFlowReturn {
271
271
  // Find all input nodes
272
272
  const inputNodes = flow.nodes.filter((node) => node.type === "input");
273
273
 
274
+ console.log("inputNodes", inputNodes);
275
+
274
276
  const metadata: FlowInputMetadata[] = inputNodes.map((node) => ({
275
277
  nodeId: node.id,
276
278
  nodeName: node.name,
@@ -1,2 +0,0 @@
1
- import{s as e,u as t}from"./use-upload-BDHVhQsI.mjs";import{EventType as n}from"@uploadista/core/flow";import{UploadEventType as r}from"@uploadista/core/types";import i,{useCallback as a,useEffect as o,useRef as s,useState as c}from"react";function l(e){if(!(`eventType`in e))return!1;let t=e;return t.eventType===n.JobStart||t.eventType===n.JobEnd||t.eventType===n.FlowStart||t.eventType===n.FlowEnd||t.eventType===n.FlowError||t.eventType===n.FlowPause||t.eventType===n.FlowCancel||t.eventType===n.NodeStart||t.eventType===n.NodeEnd||t.eventType===n.NodePause||t.eventType===n.NodeResume||t.eventType===n.NodeError||t.eventType===n.NodeStream||t.eventType===n.NodeResponse}function u(e){if(!(`type`in e))return!1;let t=e;return t.type===r.UPLOAD_STARTED||t.type===r.UPLOAD_PROGRESS||t.type===r.UPLOAD_COMPLETE||t.type===r.UPLOAD_FAILED||t.type===r.UPLOAD_VALIDATION_SUCCESS||t.type===r.UPLOAD_VALIDATION_FAILED||t.type===r.UPLOAD_VALIDATION_WARNING}function d(t){let{subscribeToEvents:n}=e();o(()=>n(t),[n,t])}function f(t){let{subscribeToEvents:r}=e();o(()=>r(e=>{if(l(e))switch(e.eventType){case n.JobStart:t.onJobStart?.(e);break;case n.JobEnd:t.onJobEnd?.(e);break;case n.FlowStart:t.onFlowStart?.(e);break;case n.FlowEnd:t.onFlowEnd?.(e);break;case n.FlowError:t.onFlowError?.(e);break;case n.FlowPause:t.onFlowPause?.(e);break;case n.FlowCancel:t.onFlowCancel?.(e);break;case n.NodeStart:t.onNodeStart?.(e);break;case n.NodeEnd:t.onNodeEnd?.(e);break;case n.NodePause:t.onNodePause?.(e);break;case n.NodeResume:t.onNodeResume?.(e);break;case n.NodeError:t.onNodeError?.(e);break}}),[r,t])}function p(t){let{subscribeToEvents:n}=e();o(()=>n(e=>{if(!u(e))return;let n=`flow`in e?e.flow:void 0;switch(e.type){case r.UPLOAD_STARTED:t.onUploadStarted?.({...e.data,flow:n});break;case r.UPLOAD_PROGRESS:t.onUploadProgress?.({...e.data,flow:n});break;case r.UPLOAD_COMPLETE:t.onUploadComplete?.({...e.data,flow:n});break;case r.UPLOAD_FAILED:t.onUploadFailed?.({...e.data,flow:n});break;case r.UPLOAD_VALIDATION_SUCCESS:t.onUploadValidationSuccess?.({...e.data,flow:n});break;case r.UPLOAD_VALIDATION_FAILED:t.onUploadValidationFailed?.({...e.data,flow:n});break;case r.UPLOAD_VALIDATION_WARNING:t.onUploadValidationWarning?.({...e.data,flow:n});break}}),[n,t])}const m={status:`idle`,progress:0,bytesUploaded:0,totalBytes:null,error:null,jobId:null,flowStarted:!1,currentNodeName:null,currentNodeType:null,flowOutputs:null};function h(n){let{client:r}=e(),{getManager:i,releaseManager:l}=t(),[u,d]=c(m),[f,p]=c(null),[h,g]=c(!1),[_,v]=c({}),[y,b]=c(new Map),x=s(null),S=s(n);return o(()=>{S.current=n}),o(()=>{(async()=>{g(!0);try{let{flow:e}=await r.getFlow(n.flowConfig.flowId);p(e.nodes.filter(e=>e.type===`input`).map(e=>({nodeId:e.id,nodeName:e.name,nodeDescription:e.description,nodeTypeId:e.nodeTypeId,required:!0})))}catch(e){console.error(`Failed to discover flow inputs:`,e)}finally{g(!1)}})()},[r,n.flowConfig.flowId]),o(()=>{let e=n.flowConfig.flowId;x.current=i(e,{onStateChange:e=>{d(e)},onProgress:(e,t,n)=>{S.current.onProgress?.(e,t,n)},onChunkComplete:(e,t,n)=>{S.current.onChunkComplete?.(e,t,n)},onFlowComplete:e=>{S.current.onFlowComplete?.(e)},onSuccess:e=>{S.current.onSuccess?.(e)},onError:e=>{S.current.onError?.(e)},onAbort:()=>{S.current.onAbort?.()}},n);let t=setInterval(()=>{if(x.current){let e=x.current.getInputStates();e.size>0&&b(new Map(e))}},100);return()=>{clearInterval(t),l(e),x.current=null}},[n.flowConfig.flowId,n.flowConfig.storageId,n.flowConfig.outputNodeId,i,l]),{state:u,inputMetadata:f,inputStates:y,inputs:_,setInput:a((e,t)=>{v(n=>({...n,[e]:t}))},[]),execute:a(async()=>{if(!x.current)throw Error(`FlowManager not initialized`);if(Object.keys(_).length===0)throw Error(`No inputs provided. Use setInput() to provide inputs before calling execute()`);await x.current.executeFlow(_)},[_]),upload:a(async e=>{if(!x.current)throw Error(`FlowManager not initialized`);if(f&&f.length>0){let t=f[0];if(!t)throw Error(`No input nodes found`);v({[t.nodeId]:e}),await x.current.executeFlow({[t.nodeId]:e})}else await x.current.upload(e)},[f]),abort:a(()=>{x.current?.abort()},[]),pause:a(()=>{x.current?.pause()},[]),reset:a(()=>{x.current?.reset(),v({}),b(new Map)},[]),isUploading:u.status===`uploading`||u.status===`processing`,isUploadingFile:u.status===`uploading`,isProcessing:u.status===`processing`,isDiscoveringInputs:h}}const g={status:`idle`,progress:0,bytesUploaded:0,totalBytes:null,error:null,jobId:null,flowStarted:!1,currentNodeName:null,currentNodeType:null,flowOutputs:null};function _(n){let{client:r}=e(),{getManager:i,releaseManager:l}=t(),[u,d]=c(g),f=s(null),p=s(n),m=s(n.inputBuilder);return o(()=>{p.current=n,m.current=n.inputBuilder}),o(()=>{let e=n.flowConfig.flowId;return f.current=i(e,{onStateChange:d,onProgress:(e,t,n)=>{p.current.onProgress?.(e,t,n)},onChunkComplete:(e,t,n)=>{p.current.onChunkComplete?.(e,t,n)},onFlowComplete:e=>{p.current.onFlowComplete?.(e)},onSuccess:e=>{p.current.onSuccess?.(e)},onError:e=>{p.current.onError?.(e)},onAbort:()=>{p.current.onAbort?.()}},{flowConfig:n.flowConfig}),()=>{f.current&&=(l(e),null)}},[n.flowConfig.flowId,i,l,n]),{state:u,execute:a(async e=>{try{let t=await m.current(e),i=Object.keys(t)[0];if(!i)throw Error(`flowInputs must contain at least one input node`);let a=t[i];typeof a==`object`&&a&&`operation`in a&&a.operation===`init`?f.current&&await f.current.upload(e):(d(e=>({...e,status:`processing`,flowStarted:!0})),(await r.executeFlowWithInputs(n.flowConfig.flowId,t,{storageId:n.flowConfig.storageId,onJobStart:e=>{d(t=>({...t,jobId:e})),p.current.onJobStart?.(e)}})).job?.id||d(e=>({...e,status:`success`,progress:100,flowStarted:!0})))}catch(e){let t=e instanceof Error?e:Error(String(e));d(e=>({...e,status:`error`,error:t})),p.current.onError?.(t)}},[]),abort:a(()=>{f.current&&f.current.abort()},[]),pause:a(()=>{f.current&&f.current.pause()},[]),reset:a(()=>{if(f.current){let e=n.flowConfig.flowId;f.current.reset(),f.current.cleanup(),l(e),f.current=null}d(g)},[n.flowConfig.flowId,l]),isExecuting:u.status===`uploading`||u.status===`processing`,isUploadingFile:u.status===`uploading`,isProcessing:u.status===`processing`}}const v={totalBytesUploaded:0,totalBytes:0,averageSpeed:0,currentSpeed:0,estimatedTimeRemaining:null,totalFiles:0,completedFiles:0,activeUploads:0,progress:0,peakSpeed:0,startTime:null,endTime:null,totalDuration:null,insights:{overallEfficiency:0,chunkingEffectiveness:0,networkStability:0,recommendations:[],optimalChunkSizeRange:{min:256*1024,max:2*1024*1024}},sessionMetrics:[],chunkMetrics:[]};function y(t={}){let{speedCalculationInterval:n=1e3,speedSampleSize:r=10,onMetricsUpdate:o,onFileStart:l,onFileProgress:u,onFileComplete:d}=t,f=e(),[p,m]=c(v),[h,g]=c([]),_=s([]),y=s(0),b=s(null),x=a((e,t)=>{let n={time:e,bytes:t};_.current.push(n),_.current.length>r&&(_.current=_.current.slice(-r));let i=0;if(_.current.length>=2){let e=_.current[_.current.length-1],t=_.current[_.current.length-2];if(e&&t){let n=(e.time-t.time)/1e3,r=e.bytes-t.bytes;i=n>0?r/n:0}}let a=0;if(_.current.length>=2){let e=_.current[0],t=_.current[_.current.length-1];if(e&&t){let n=(t.time-e.time)/1e3,r=t.bytes-e.bytes;a=n>0?r/n:0}}return{currentSpeed:i,averageSpeed:a}},[r]),S=a(()=>{let e=Date.now(),t=h.reduce((e,t)=>e+t.size,0),n=h.reduce((e,t)=>e+t.bytesUploaded,0),r=h.filter(e=>e.isComplete).length,i=h.filter(e=>!e.isComplete&&e.bytesUploaded>0).length,{currentSpeed:a,averageSpeed:s}=x(e,n),c=t>0?Math.round(n/t*100):0,l=null;a>0&&(l=(t-n)/a*1e3);let u=h.filter(e=>e.startTime>0),d=u.length>0?Math.min(...u.map(e=>e.startTime)):null,g=h.filter(e=>e.endTime!==null),_=g.length>0&&r===h.length?Math.max(...g.map(e=>e.endTime).filter(e=>e!==null)):null,v=d&&_?_-d:null,y={totalBytesUploaded:n,totalBytes:t,averageSpeed:s,currentSpeed:a,estimatedTimeRemaining:l,totalFiles:h.length,completedFiles:r,activeUploads:i,progress:c,peakSpeed:Math.max(p.peakSpeed,a),startTime:d,endTime:_,totalDuration:v,insights:f.client.getChunkingInsights(),sessionMetrics:[f.client.exportMetrics().session],chunkMetrics:f.client.exportMetrics().chunks};m(y),o?.(y)},[h,p.peakSpeed,x,o,f.client]),C=a(()=>(b.current&&clearInterval(b.current),b.current=setInterval(()=>{h.some(e=>!e.isComplete&&e.bytesUploaded>0)&&S()},n),()=>{b.current&&=(clearInterval(b.current),null)}),[n,S,h]),w=a((e,t,n)=>{let r={id:e,filename:t,size:n,bytesUploaded:0,progress:0,speed:0,startTime:Date.now(),endTime:null,duration:null,isComplete:!1};g(t=>t.find(t=>t.id===e)?t.map(t=>t.id===e?r:t):[...t,r]),l?.(r),h.filter(e=>!e.isComplete).length===0&&C()},[h,l,C]),T=a((e,t)=>{let n=Date.now();g(r=>r.map(r=>{if(r.id!==e)return r;let i=(n-r.startTime)/1e3,a=i>0?t/i:0,o=r.size>0?Math.round(t/r.size*100):0,s={...r,bytesUploaded:t,progress:o,speed:a};return u?.(s),s})),setTimeout(S,0)},[u,S]),E=a(e=>{let t=Date.now();g(n=>n.map(n=>{if(n.id!==e)return n;let r=t-n.startTime,i=r>0?n.size/r*1e3:0,a={...n,bytesUploaded:n.size,progress:100,speed:i,endTime:t,duration:r,isComplete:!0};return d?.(a),a})),setTimeout(S,0)},[d,S]),D=a(e=>{g(t=>t.filter(t=>t.id!==e)),setTimeout(S,0)},[S]),O=a(()=>{b.current&&=(clearInterval(b.current),null),m(v),g([]),_.current=[],y.current=0},[]),k=a(e=>h.find(t=>t.id===e),[h]),A=a(()=>({overall:p,files:h,exportTime:Date.now()}),[p,h]);return i.useEffect(()=>()=>{b.current&&clearInterval(b.current)},[]),{metrics:p,fileMetrics:h,startFileUpload:w,updateFileProgress:T,completeFileUpload:E,removeFile:D,reset:O,getFileMetrics:k,exportMetrics:A}}export{f as a,u as c,p as i,_ as n,d as o,h as r,l as s,y as t};
2
- //# sourceMappingURL=use-upload-metrics-CFx5cvbR.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-upload-metrics-CFx5cvbR.mjs","names":["initialState: FlowUploadState","initialState","initialState: FlowUploadState","initialMetrics: UploadMetrics","estimatedTimeRemaining: number | null","newMetrics: UploadMetrics","fileMetric: FileUploadMetrics"],"sources":["../src/hooks/event-utils.ts","../src/hooks/use-uploadista-events.ts","../src/hooks/use-flow-events.ts","../src/hooks/use-upload-events.ts","../src/hooks/use-flow.ts","../src/hooks/use-flow-execution.ts","../src/hooks/use-upload-metrics.ts"],"sourcesContent":["import type { UploadistaEvent } from \"@uploadista/client-browser\";\nimport { EventType, type FlowEvent } from \"@uploadista/core/flow\";\nimport { UploadEventType, type UploadEvent } from \"@uploadista/core/types\";\n\n/**\n * Type guard to check if an event is a flow event\n */\nexport function isFlowEvent(event: UploadistaEvent): event is FlowEvent {\n if (!(\"eventType\" in event)) return false;\n const e = event as { eventType: unknown };\n return (\n e.eventType === EventType.JobStart ||\n e.eventType === EventType.JobEnd ||\n e.eventType === EventType.FlowStart ||\n e.eventType === EventType.FlowEnd ||\n e.eventType === EventType.FlowError ||\n e.eventType === EventType.FlowPause ||\n e.eventType === EventType.FlowCancel ||\n e.eventType === EventType.NodeStart ||\n e.eventType === EventType.NodeEnd ||\n e.eventType === EventType.NodePause ||\n e.eventType === EventType.NodeResume ||\n e.eventType === EventType.NodeError ||\n e.eventType === EventType.NodeStream ||\n e.eventType === EventType.NodeResponse\n );\n}\n\n/**\n * Type guard to check if an event is an upload event\n */\nexport function isUploadEvent(event: UploadistaEvent): event is UploadEvent {\n if (!(\"type\" in event)) return false;\n const e = event as { type: unknown };\n return (\n e.type === UploadEventType.UPLOAD_STARTED ||\n e.type === UploadEventType.UPLOAD_PROGRESS ||\n e.type === UploadEventType.UPLOAD_COMPLETE ||\n e.type === UploadEventType.UPLOAD_FAILED ||\n e.type === UploadEventType.UPLOAD_VALIDATION_SUCCESS ||\n e.type === UploadEventType.UPLOAD_VALIDATION_FAILED ||\n e.type === UploadEventType.UPLOAD_VALIDATION_WARNING\n );\n}\n","import type { UploadistaEvent } from \"@uploadista/client-core\";\nimport { useEffect } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\n\n/**\n * Simple hook that subscribes to all Uploadista events (both flow and upload events).\n *\n * This is a low-level hook that provides access to all events. For more structured\n * event handling, consider using `useFlowEvents` or `useUploadEvents` instead.\n *\n * Must be used within UploadistaProvider.\n *\n * @param callback - Function called for every event emitted by the Uploadista client\n *\n * @example\n * ```tsx\n * import { useUploadistaEvents, isFlowEvent, isUploadEvent } from '@uploadista/react';\n *\n * function MyComponent() {\n * useUploadistaEvents((event) => {\n * if (isFlowEvent(event)) {\n * console.log('Flow event:', event.eventType);\n * } else if (isUploadEvent(event)) {\n * console.log('Upload event:', event.type);\n * }\n * });\n *\n * return <div>Listening to all events...</div>;\n * }\n * ```\n */\nexport function useUploadistaEvents(\n callback: (event: UploadistaEvent) => void,\n): void {\n const { subscribeToEvents } = useUploadistaContext();\n\n useEffect(() => {\n const unsubscribe = subscribeToEvents(callback);\n return unsubscribe;\n }, [subscribeToEvents, callback]);\n}\n","import type {\n FlowEventFlowCancel,\n FlowEventFlowEnd,\n FlowEventFlowError,\n FlowEventFlowPause,\n FlowEventFlowStart,\n FlowEventJobEnd,\n FlowEventJobStart,\n FlowEventNodeEnd,\n FlowEventNodeError,\n FlowEventNodePause,\n FlowEventNodeResume,\n FlowEventNodeStart,\n} from \"@uploadista/core/flow\";\nimport { EventType } from \"@uploadista/core/flow\";\nimport { useEffect } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\nimport { isFlowEvent } from \"./event-utils\";\n\n/**\n * Options for handling flow execution events.\n *\n * All callbacks are optional - only provide handlers for events you care about.\n */\nexport interface UseFlowEventsOptions {\n /** Called when a job starts execution */\n onJobStart?: (event: FlowEventJobStart) => void;\n /** Called when a job completes (success or failure) */\n onJobEnd?: (event: FlowEventJobEnd) => void;\n /** Called when a flow begins execution */\n onFlowStart?: (event: FlowEventFlowStart) => void;\n /** Called when a flow completes successfully */\n onFlowEnd?: (event: FlowEventFlowEnd) => void;\n /** Called when a flow encounters an error */\n onFlowError?: (event: FlowEventFlowError) => void;\n /** Called when a flow is paused by user request */\n onFlowPause?: (event: FlowEventFlowPause) => void;\n /** Called when a flow is cancelled by user request */\n onFlowCancel?: (event: FlowEventFlowCancel) => void;\n /** Called when a node starts processing */\n onNodeStart?: (event: FlowEventNodeStart) => void;\n /** Called when a node completes successfully */\n onNodeEnd?: (event: FlowEventNodeEnd) => void;\n /** Called when a node pauses (waiting for additional data) */\n onNodePause?: (event: FlowEventNodePause) => void;\n /** Called when a paused node resumes execution */\n onNodeResume?: (event: FlowEventNodeResume) => void;\n /** Called when a node encounters an error */\n onNodeError?: (event: FlowEventNodeError) => void;\n}\n\n/**\n * Structured hook for handling flow execution events with type-safe callbacks.\n *\n * This hook provides a clean API for listening to specific flow events without\n * needing to manually filter events or use type guards.\n *\n * Must be used within UploadistaProvider.\n *\n * @param options - Object with optional callbacks for each flow event type\n *\n * @example\n * ```tsx\n * import { useFlowEvents } from '@uploadista/react';\n *\n * function FlowMonitor() {\n * useFlowEvents({\n * onFlowStart: (event) => {\n * console.log('Flow started:', event.flowId);\n * },\n * onNodeStart: (event) => {\n * console.log('Node started:', event.nodeName);\n * },\n * onNodeEnd: (event) => {\n * console.log('Node completed:', event.nodeName, event.result);\n * },\n * onFlowEnd: (event) => {\n * console.log('Flow completed with outputs:', event.outputs);\n * },\n * onFlowError: (event) => {\n * console.error('Flow failed:', event.error);\n * },\n * });\n *\n * return <div>Monitoring flow execution...</div>;\n * }\n * ```\n */\nexport function useFlowEvents(options: UseFlowEventsOptions): void {\n const { subscribeToEvents } = useUploadistaContext();\n\n useEffect(() => {\n const unsubscribe = subscribeToEvents((event) => {\n // Only handle flow events\n if (!isFlowEvent(event)) return;\n\n // Route to appropriate callback based on event type\n switch (event.eventType) {\n case EventType.JobStart:\n options.onJobStart?.(event);\n break;\n case EventType.JobEnd:\n options.onJobEnd?.(event);\n break;\n case EventType.FlowStart:\n options.onFlowStart?.(event);\n break;\n case EventType.FlowEnd:\n options.onFlowEnd?.(event);\n break;\n case EventType.FlowError:\n options.onFlowError?.(event);\n break;\n case EventType.FlowPause:\n options.onFlowPause?.(event);\n break;\n case EventType.FlowCancel:\n options.onFlowCancel?.(event);\n break;\n case EventType.NodeStart:\n options.onNodeStart?.(event);\n break;\n case EventType.NodeEnd:\n options.onNodeEnd?.(event);\n break;\n case EventType.NodePause:\n options.onNodePause?.(event);\n break;\n case EventType.NodeResume:\n options.onNodeResume?.(event);\n break;\n case EventType.NodeError:\n options.onNodeError?.(event);\n break;\n }\n });\n\n return unsubscribe;\n }, [subscribeToEvents, options]);\n}\n","import { UploadEventType, type UploadEvent } from \"@uploadista/core/types\";\nimport { useEffect } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\nimport { isUploadEvent } from \"./event-utils\";\n\n/**\n * Upload progress event data\n */\nexport interface UploadProgressEventData {\n id: string;\n progress: number;\n total: number;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Upload started/complete event data (contains full UploadFile)\n */\nexport interface UploadFileEventData {\n // This will contain the full UploadFile schema\n [key: string]: unknown;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Upload failed event data\n */\nexport interface UploadFailedEventData {\n id: string;\n error: string;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Upload validation success event data\n */\nexport interface UploadValidationSuccessEventData {\n id: string;\n validationType: \"checksum\" | \"mimetype\";\n algorithm?: string;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Upload validation failed event data\n */\nexport interface UploadValidationFailedEventData {\n id: string;\n reason: string;\n expected: string;\n actual: string;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Upload validation warning event data\n */\nexport interface UploadValidationWarningEventData {\n id: string;\n message: string;\n flow?: {\n flowId: string;\n nodeId: string;\n jobId: string;\n };\n}\n\n/**\n * Options for handling upload events.\n *\n * All callbacks are optional - only provide handlers for events you care about.\n */\nexport interface UseUploadEventsOptions {\n /** Called when an upload starts */\n onUploadStarted?: (data: UploadFileEventData) => void;\n /** Called with upload progress updates */\n onUploadProgress?: (data: UploadProgressEventData) => void;\n /** Called when an upload completes successfully */\n onUploadComplete?: (data: UploadFileEventData) => void;\n /** Called when an upload fails */\n onUploadFailed?: (data: UploadFailedEventData) => void;\n /** Called when upload validation succeeds */\n onUploadValidationSuccess?: (data: UploadValidationSuccessEventData) => void;\n /** Called when upload validation fails */\n onUploadValidationFailed?: (data: UploadValidationFailedEventData) => void;\n /** Called when upload validation produces a warning */\n onUploadValidationWarning?: (data: UploadValidationWarningEventData) => void;\n}\n\n/**\n * Structured hook for handling upload events with type-safe callbacks.\n *\n * This hook provides a clean API for listening to specific upload events without\n * needing to manually filter events or use type guards.\n *\n * Must be used within UploadistaProvider.\n *\n * @param options - Object with optional callbacks for each upload event type\n *\n * @example\n * ```tsx\n * import { useUploadEvents } from '@uploadista/react';\n *\n * function UploadMonitor() {\n * useUploadEvents({\n * onUploadStarted: (data) => {\n * console.log('Upload started:', data.id);\n * },\n * onUploadProgress: (data) => {\n * const percent = (data.progress / data.total) * 100;\n * console.log(`Upload progress: ${percent}%`);\n * },\n * onUploadComplete: (data) => {\n * console.log('Upload completed:', data);\n * },\n * onUploadFailed: (data) => {\n * console.error('Upload failed:', data.error);\n * },\n * });\n *\n * return <div>Monitoring uploads...</div>;\n * }\n * ```\n */\nexport function useUploadEvents(options: UseUploadEventsOptions): void {\n const { subscribeToEvents } = useUploadistaContext();\n\n useEffect(() => {\n const unsubscribe = subscribeToEvents((event) => {\n // Only handle upload events\n if (!isUploadEvent(event)) return;\n\n // Route to appropriate callback based on event type\n // Note: flow context is at the top level of the event, not inside data\n const flowContext = \"flow\" in event ? event.flow : undefined;\n\n switch (event.type) {\n case UploadEventType.UPLOAD_STARTED:\n options.onUploadStarted?.({\n ...(event.data as unknown as Omit<UploadFileEventData, \"flow\">),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_PROGRESS:\n options.onUploadProgress?.({\n ...(event.data as unknown as Omit<\n UploadProgressEventData,\n \"flow\"\n >),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_COMPLETE:\n options.onUploadComplete?.({\n ...(event.data as unknown as Omit<UploadFileEventData, \"flow\">),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_FAILED:\n options.onUploadFailed?.({\n ...(event.data as unknown as Omit<UploadFailedEventData, \"flow\">),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_VALIDATION_SUCCESS:\n options.onUploadValidationSuccess?.({\n ...(event.data as unknown as Omit<\n UploadValidationSuccessEventData,\n \"flow\"\n >),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_VALIDATION_FAILED:\n options.onUploadValidationFailed?.({\n ...(event.data as unknown as Omit<\n UploadValidationFailedEventData,\n \"flow\"\n >),\n flow: flowContext,\n });\n break;\n case UploadEventType.UPLOAD_VALIDATION_WARNING:\n options.onUploadValidationWarning?.({\n ...(event.data as unknown as Omit<\n UploadValidationWarningEventData,\n \"flow\"\n >),\n flow: flowContext,\n });\n break;\n }\n });\n\n return unsubscribe;\n }, [subscribeToEvents, options]);\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 node type */\n nodeTypeId: 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 nodeTypeId: node.nodeTypeId,\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","/**\n * Generic React hook for flexible flow execution with arbitrary input types.\n *\n * This hook provides a flexible interface for executing flows with different input types:\n * - File/Blob: Traditional chunked file upload\n * - string (URL): Direct file fetch from external URL\n * - object: Structured data for custom input nodes\n *\n * The hook uses an inputBuilder pattern to transform trigger data into flow inputs,\n * enabling dynamic input preparation and validation before flow execution.\n *\n * @module hooks/use-flow-execution\n *\n * @example\n * ```tsx\n * // URL-based flow execution\n * function UrlImageProcessor() {\n * const execution = useFlowExecution<string>({\n * flowConfig: {\n * flowId: \"image-optimize\",\n * storageId: \"s3\"\n * },\n * inputBuilder: async (url) => {\n * // Find the input node\n * const { inputNodes, single } = await client.findInputNode(\"image-optimize\");\n * if (!single) throw new Error(\"Expected single input node\");\n *\n * return {\n * [inputNodes[0].id]: {\n * operation: \"url\",\n * url,\n * metadata: { source: \"external\" }\n * }\n * };\n * },\n * onSuccess: (outputs) => console.log(\"Done:\", outputs)\n * });\n *\n * return (\n * <button onClick={() => execution.execute(\"https://example.com/image.jpg\")}>\n * Process URL\n * </button>\n * );\n * }\n * ```\n */\n\nimport type { FlowUploadOptions } from \"@uploadista/client-browser\";\nimport type {\n FlowInputs,\n FlowManager,\n FlowUploadState,\n FlowUploadStatus,\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 for convenience\nexport type { FlowUploadState, FlowUploadStatus };\n\n/**\n * Input builder function that transforms trigger data into flow inputs.\n *\n * The builder receives the trigger data passed to execute() and returns\n * a FlowInputs object mapping node IDs to their input data.\n *\n * @template TTrigger - The type of data passed to execute()\n * @param trigger - The trigger data (e.g., File, URL string, structured data)\n * @returns Promise resolving to FlowInputs mapping or the mapping directly\n *\n * @example\n * ```typescript\n * // File upload builder\n * const fileBuilder: InputBuilder<File> = async (file) => ({\n * \"input-node\": {\n * operation: \"init\",\n * storageId: \"s3\",\n * metadata: { originalName: file.name, size: file.size }\n * }\n * });\n *\n * // URL fetch builder\n * const urlBuilder: InputBuilder<string> = (url) => ({\n * \"input-node\": {\n * operation: \"url\",\n * url,\n * metadata: { source: \"external\" }\n * }\n * });\n * ```\n */\nexport type InputBuilder<TTrigger = unknown> = (\n trigger: TTrigger,\n) => Promise<FlowInputs> | FlowInputs;\n\n/**\n * Options for the useFlowExecution hook.\n *\n * @template TTrigger - The type of trigger data passed to execute()\n * @template TOutput - The expected output type from the flow\n *\n * @property flowConfig - Flow configuration (flowId, storageId, etc.)\n * @property inputBuilder - Function to build flow inputs from trigger data\n * @property onJobStart - Called when flow job is created\n * @property onProgress - Called during upload progress (if applicable)\n * @property onChunkComplete - Called when upload chunk completes (if applicable)\n * @property onSuccess - Called with typed outputs when flow succeeds\n * @property onFlowComplete - Called with all outputs when flow completes\n * @property onError - Called when execution fails\n * @property onAbort - Called when execution is aborted\n * @property onShouldRetry - Custom retry logic (if applicable)\n */\nexport interface UseFlowExecutionOptions<\n TTrigger = unknown,\n TOutput = TypedOutput[],\n> {\n /**\n * Flow configuration\n */\n flowConfig: FlowUploadOptions[\"flowConfig\"];\n\n /**\n * Function to build flow inputs from trigger data.\n * Can be async to perform validation, API calls, etc.\n */\n inputBuilder: InputBuilder<TTrigger>;\n\n /**\n * Called when the flow job starts\n */\n onJobStart?: (jobId: string) => void;\n\n /**\n * Called during upload progress (for file uploads)\n */\n onProgress?: (\n uploadId: string,\n bytesUploaded: number,\n totalBytes: number | null,\n ) => void;\n\n /**\n * Called when an upload chunk completes (for file uploads)\n */\n onChunkComplete?: (\n chunkSize: number,\n bytesAccepted: number,\n bytesTotal: number | null,\n ) => void;\n\n /**\n * Called when flow execution succeeds with final outputs\n */\n onSuccess?: (outputs: TOutput) => void;\n\n /**\n * Called when flow completes (alternative to onSuccess)\n */\n onFlowComplete?: (outputs: TypedOutput[]) => void;\n\n /**\n * Called when execution fails\n */\n onError?: (error: Error) => void;\n\n /**\n * Called when execution is aborted\n */\n onAbort?: () => void;\n\n /**\n * Custom retry logic (for file uploads)\n */\n onShouldRetry?: (error: Error, retryAttempt: number) => boolean;\n}\n\n/**\n * Return value from useFlowExecution hook.\n *\n * @template TTrigger - The type of trigger data passed to execute()\n *\n * @property state - Current execution state with progress and outputs\n * @property execute - Function to trigger flow execution\n * @property abort - Cancel the current execution\n * @property pause - Pause the current execution (for file uploads)\n * @property reset - Reset state to idle\n * @property isExecuting - True when execution is active\n * @property isUploadingFile - True during file upload phase\n * @property isProcessing - True during flow processing phase\n */\nexport interface UseFlowExecutionReturn<TTrigger = unknown> {\n /**\n * Current execution state\n */\n state: FlowUploadState;\n\n /**\n * Execute the flow with trigger data\n */\n execute: (trigger: TTrigger) => Promise<void>;\n\n /**\n * Abort the current execution\n */\n abort: () => void;\n\n /**\n * Pause the current execution (if supported by input type)\n */\n pause: () => void;\n\n /**\n * Reset the execution state\n */\n reset: () => void;\n\n /**\n * Whether execution is active (uploading OR processing)\n */\n isExecuting: boolean;\n\n /**\n * Whether file upload is in progress\n */\n isUploadingFile: boolean;\n\n /**\n * Whether flow processing is in progress\n */\n isProcessing: 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 * Generic React hook for flexible flow execution.\n *\n * Provides a flexible interface for executing flows with arbitrary input types\n * through an inputBuilder pattern. The builder transforms trigger data into\n * flow inputs, enabling support for files, URLs, structured data, and more.\n *\n * Must be used within FlowManagerProvider (which must be within UploadistaProvider).\n *\n * @template TTrigger - The type of trigger data passed to execute()\n * @template TOutput - The expected output type from the flow\n *\n * @param options - Flow execution configuration with inputBuilder\n * @returns Execution state and control methods\n *\n * @example\n * ```tsx\n * // URL-based image processing\n * const urlExecution = useFlowExecution<string>({\n * flowConfig: { flowId: \"optimize\", storageId: \"s3\" },\n * inputBuilder: async (url) => {\n * const { inputNodes } = await client.findInputNode(\"optimize\");\n * return {\n * [inputNodes[0].id]: {\n * operation: \"url\",\n * url,\n * metadata: { source: \"external\" }\n * }\n * };\n * },\n * onSuccess: (outputs) => console.log(\"Processed:\", outputs)\n * });\n *\n * // Execute with URL\n * await urlExecution.execute(\"https://example.com/image.jpg\");\n *\n * // File upload (traditional pattern)\n * const fileExecution = useFlowExecution<File>({\n * flowConfig: { flowId: \"optimize\", storageId: \"s3\" },\n * inputBuilder: async (file) => {\n * const { inputNodes } = await client.findInputNode(\"optimize\");\n * return {\n * [inputNodes[0].id]: {\n * operation: \"init\",\n * storageId: \"s3\",\n * metadata: {\n * originalName: file.name,\n * mimeType: file.type,\n * size: file.size\n * }\n * }\n * };\n * }\n * });\n *\n * // Execute with file\n * await fileExecution.execute(myFile);\n * ```\n */\nexport function useFlowExecution<TTrigger = unknown, TOutput = TypedOutput[]>(\n options: UseFlowExecutionOptions<TTrigger, TOutput>,\n): UseFlowExecutionReturn<TTrigger> {\n const { client } = useUploadistaContext();\n const { getManager, releaseManager } = useFlowManagerContext();\n const [state, setState] = useState<FlowUploadState>(initialState);\n const managerRef = useRef<FlowManager<unknown> | null>(null);\n\n // Store callbacks and inputBuilder in refs for stable access\n const callbacksRef = useRef(options);\n const inputBuilderRef = useRef(options.inputBuilder);\n\n // Update refs when options change\n useEffect(() => {\n callbacksRef.current = options;\n inputBuilderRef.current = options.inputBuilder;\n });\n\n // Get or create manager from context\n useEffect(() => {\n const flowId = options.flowConfig.flowId;\n\n // Create stable callback wrappers\n const stableCallbacks = {\n onStateChange: setState,\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 as TOutput);\n },\n onError: (error: Error) => {\n callbacksRef.current.onError?.(error);\n },\n onAbort: () => {\n callbacksRef.current.onAbort?.();\n },\n };\n\n // Get or create manager for this flow\n const manager = getManager(flowId, stableCallbacks, {\n flowConfig: options.flowConfig,\n });\n managerRef.current = manager;\n\n return () => {\n if (managerRef.current) {\n releaseManager(flowId);\n managerRef.current = null;\n }\n };\n }, [options.flowConfig.flowId, getManager, releaseManager, options]);\n\n /**\n * Execute the flow with trigger data.\n * Calls inputBuilder to transform trigger into flow inputs.\n */\n const execute = useCallback(async (trigger: TTrigger) => {\n try {\n // Build flow inputs from trigger data\n const flowInputs = await inputBuilderRef.current(trigger);\n\n // For now, we need to determine if this is a file upload or URL operation\n // by inspecting the flowInputs structure\n const firstInputNodeId = Object.keys(flowInputs)[0];\n if (!firstInputNodeId) {\n throw new Error(\"flowInputs must contain at least one input node\");\n }\n const firstInput = flowInputs[firstInputNodeId];\n\n // Type guard: check if this is an init operation (file upload)\n const isFileUpload =\n typeof firstInput === \"object\" &&\n firstInput !== null &&\n \"operation\" in firstInput &&\n firstInput.operation === \"init\";\n\n if (isFileUpload) {\n // File upload path: use the standard upload mechanism\n // This requires the trigger to be a File/Blob\n if (managerRef.current) {\n await managerRef.current.upload(trigger as unknown);\n }\n } else {\n // Non-file path (URL, structured data, etc.)\n // Skip chunked upload and execute flow directly with provided inputs\n setState((prev) => ({\n ...prev,\n status: \"processing\",\n flowStarted: true,\n }));\n\n // Execute flow with the built inputs\n const result = await client.executeFlowWithInputs(\n options.flowConfig.flowId,\n flowInputs,\n {\n storageId: options.flowConfig.storageId,\n onJobStart: (jobId: string) => {\n setState((prev) => ({\n ...prev,\n jobId,\n }));\n callbacksRef.current.onJobStart?.(jobId);\n },\n },\n );\n\n // If job was created successfully, the FlowManager will handle\n // flow events via WebSocket and update state accordingly\n if (result.job?.id) {\n // State updates will come from flow events\n // Manager will receive FlowEnd event and update state to \"success\"\n } else {\n // No job created - treat as immediate completion\n setState((prev) => ({\n ...prev,\n status: \"success\",\n progress: 100,\n flowStarted: true,\n }));\n }\n }\n } catch (error) {\n // Handle inputBuilder errors\n const err = error instanceof Error ? error : new Error(String(error));\n setState((prev) => ({\n ...prev,\n status: \"error\",\n error: err,\n }));\n callbacksRef.current.onError?.(err);\n }\n }, []);\n\n /**\n * Abort the current execution\n */\n const abort = useCallback(() => {\n if (managerRef.current) {\n managerRef.current.abort();\n }\n }, []);\n\n /**\n * Pause the current execution\n */\n const pause = useCallback(() => {\n if (managerRef.current) {\n managerRef.current.pause();\n }\n }, []);\n\n /**\n * Reset the execution state\n */\n const reset = useCallback(() => {\n if (managerRef.current) {\n const flowId = options.flowConfig.flowId;\n managerRef.current.reset();\n managerRef.current.cleanup();\n releaseManager(flowId);\n managerRef.current = null;\n }\n setState(initialState);\n }, [options.flowConfig.flowId, releaseManager]);\n\n return {\n state,\n execute,\n abort,\n pause,\n reset,\n isExecuting: state.status === \"uploading\" || state.status === \"processing\",\n isUploadingFile: state.status === \"uploading\",\n isProcessing: state.status === \"processing\",\n };\n}\n","import type {\n ChunkMetrics,\n PerformanceInsights,\n UploadSessionMetrics,\n} from \"@uploadista/client-core\";\nimport React, { useCallback, useRef, useState } from \"react\";\nimport { useUploadistaContext } from \"../components/uploadista-provider\";\n\nexport type Timeout = ReturnType<typeof setInterval>;\n\nexport interface UploadMetrics {\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 * Overall upload speed in bytes per second\n */\n averageSpeed: number;\n\n /**\n * Current upload speed in bytes per second\n */\n currentSpeed: number;\n\n /**\n * Estimated time remaining in milliseconds\n */\n estimatedTimeRemaining: number | null;\n\n /**\n * Total number of files being tracked\n */\n totalFiles: number;\n\n /**\n * Number of files completed\n */\n completedFiles: number;\n\n /**\n * Number of files currently uploading\n */\n activeUploads: number;\n\n /**\n * Overall progress as percentage (0-100)\n */\n progress: number;\n\n /**\n * Peak upload speed achieved\n */\n peakSpeed: number;\n\n /**\n * Start time of the first upload\n */\n startTime: number | null;\n\n /**\n * End time of the last completed upload\n */\n endTime: number | null;\n\n /**\n * Total duration of all uploads\n */\n totalDuration: number | null;\n\n /**\n * Detailed performance insights from the upload client\n */\n insights: PerformanceInsights;\n\n /**\n * Session metrics for completed uploads\n */\n sessionMetrics: Partial<UploadSessionMetrics>[];\n\n /**\n * Detailed chunk metrics from recent uploads\n */\n chunkMetrics: ChunkMetrics[];\n}\n\nexport interface FileUploadMetrics {\n id: string;\n filename: string;\n size: number;\n bytesUploaded: number;\n progress: number;\n speed: number;\n startTime: number;\n endTime: number | null;\n duration: number | null;\n isComplete: boolean;\n}\n\nexport interface UseUploadMetricsOptions {\n /**\n * Interval for calculating current speed (in milliseconds)\n */\n speedCalculationInterval?: number;\n\n /**\n * Number of speed samples to keep for average calculation\n */\n speedSampleSize?: number;\n\n /**\n * Called when metrics are updated\n */\n onMetricsUpdate?: (metrics: UploadMetrics) => void;\n\n /**\n * Called when a file upload starts\n */\n onFileStart?: (fileMetrics: FileUploadMetrics) => void;\n\n /**\n * Called when a file upload progresses\n */\n onFileProgress?: (fileMetrics: FileUploadMetrics) => void;\n\n /**\n * Called when a file upload completes\n */\n onFileComplete?: (fileMetrics: FileUploadMetrics) => void;\n}\n\nexport interface UseUploadMetricsReturn {\n /**\n * Current overall metrics\n */\n metrics: UploadMetrics;\n\n /**\n * Individual file metrics\n */\n fileMetrics: FileUploadMetrics[];\n\n /**\n * Start tracking a new file upload\n */\n startFileUpload: (id: string, filename: string, size: number) => void;\n\n /**\n * Update progress for a file upload\n */\n updateFileProgress: (id: string, bytesUploaded: number) => void;\n\n /**\n * Mark a file upload as complete\n */\n completeFileUpload: (id: string) => void;\n\n /**\n * Remove a file from tracking\n */\n removeFile: (id: string) => void;\n\n /**\n * Reset all metrics\n */\n reset: () => void;\n\n /**\n * Get metrics for a specific file\n */\n getFileMetrics: (id: string) => FileUploadMetrics | undefined;\n\n /**\n * Export metrics as JSON\n */\n exportMetrics: () => {\n overall: UploadMetrics;\n files: FileUploadMetrics[];\n exportTime: number;\n };\n}\n\nconst initialMetrics: UploadMetrics = {\n totalBytesUploaded: 0,\n totalBytes: 0,\n averageSpeed: 0,\n currentSpeed: 0,\n estimatedTimeRemaining: null,\n totalFiles: 0,\n completedFiles: 0,\n activeUploads: 0,\n progress: 0,\n peakSpeed: 0,\n startTime: null,\n endTime: null,\n totalDuration: null,\n insights: {\n overallEfficiency: 0,\n chunkingEffectiveness: 0,\n networkStability: 0,\n recommendations: [],\n optimalChunkSizeRange: { min: 256 * 1024, max: 2 * 1024 * 1024 },\n },\n sessionMetrics: [],\n chunkMetrics: [],\n};\n\n/**\n * React hook for tracking detailed upload metrics and performance statistics.\n * Provides comprehensive monitoring of upload progress, speed, and timing data.\n *\n * @param options - Configuration and event handlers\n * @returns Upload metrics state and control methods\n *\n * @example\n * ```tsx\n * const uploadMetrics = useUploadMetrics({\n * speedCalculationInterval: 1000, // Update speed every second\n * speedSampleSize: 10, // Keep last 10 speed samples for average\n * onMetricsUpdate: (metrics) => {\n * console.log(`Overall progress: ${metrics.progress}%`);\n * console.log(`Speed: ${(metrics.currentSpeed / 1024).toFixed(1)} KB/s`);\n * console.log(`ETA: ${metrics.estimatedTimeRemaining}ms`);\n * },\n * onFileComplete: (fileMetrics) => {\n * console.log(`${fileMetrics.filename} completed in ${fileMetrics.duration}ms`);\n * },\n * });\n *\n * // Start tracking a file\n * const handleFileStart = (file: File) => {\n * uploadMetrics.startFileUpload(file.name, file.name, file.size);\n * };\n *\n * // Update progress during upload\n * const handleProgress = (fileId: string, bytesUploaded: number) => {\n * uploadMetrics.updateFileProgress(fileId, bytesUploaded);\n * };\n *\n * // Display metrics\n * return (\n * <div>\n * <div>Overall Progress: {uploadMetrics.metrics.progress}%</div>\n * <div>Speed: {(uploadMetrics.metrics.currentSpeed / 1024).toFixed(1)} KB/s</div>\n * <div>Files: {uploadMetrics.metrics.completedFiles}/{uploadMetrics.metrics.totalFiles}</div>\n *\n * {uploadMetrics.metrics.estimatedTimeRemaining && (\n * <div>ETA: {Math.round(uploadMetrics.metrics.estimatedTimeRemaining / 1000)}s</div>\n * )}\n *\n * {uploadMetrics.fileMetrics.map((file) => (\n * <div key={file.id}>\n * {file.filename}: {file.progress}% ({(file.speed / 1024).toFixed(1)} KB/s)\n * </div>\n * ))}\n * </div>\n * );\n * ```\n */\nexport function useUploadMetrics(\n options: UseUploadMetricsOptions = {},\n): UseUploadMetricsReturn {\n const {\n speedCalculationInterval = 1000,\n speedSampleSize = 10,\n onMetricsUpdate,\n onFileStart,\n onFileProgress,\n onFileComplete,\n } = options;\n\n const uploadClient = useUploadistaContext();\n\n const [metrics, setMetrics] = useState<UploadMetrics>(initialMetrics);\n const [fileMetrics, setFileMetrics] = useState<FileUploadMetrics[]>([]);\n\n const speedSamplesRef = useRef<Array<{ time: number; bytes: number }>>([]);\n const lastUpdateRef = useRef<number>(0);\n const intervalRef = useRef<Timeout | null>(null);\n\n const calculateSpeed = useCallback(\n (currentTime: number, totalBytesUploaded: number) => {\n const sample = { time: currentTime, bytes: totalBytesUploaded };\n speedSamplesRef.current.push(sample);\n\n // Keep only recent samples\n if (speedSamplesRef.current.length > speedSampleSize) {\n speedSamplesRef.current = speedSamplesRef.current.slice(\n -speedSampleSize,\n );\n }\n\n // Calculate current speed (bytes per second)\n let currentSpeed = 0;\n if (speedSamplesRef.current.length >= 2) {\n const recent =\n speedSamplesRef.current[speedSamplesRef.current.length - 1];\n const previous =\n speedSamplesRef.current[speedSamplesRef.current.length - 2];\n if (recent && previous) {\n const timeDiff = (recent.time - previous.time) / 1000; // Convert to seconds\n const bytesDiff = recent.bytes - previous.bytes;\n currentSpeed = timeDiff > 0 ? bytesDiff / timeDiff : 0;\n }\n }\n\n // Calculate average speed\n let averageSpeed = 0;\n if (speedSamplesRef.current.length >= 2) {\n const first = speedSamplesRef.current[0];\n const last =\n speedSamplesRef.current[speedSamplesRef.current.length - 1];\n if (first && last) {\n const totalTime = (last.time - first.time) / 1000; // Convert to seconds\n const totalBytes = last.bytes - first.bytes;\n averageSpeed = totalTime > 0 ? totalBytes / totalTime : 0;\n }\n }\n\n return { currentSpeed, averageSpeed };\n },\n [speedSampleSize],\n );\n\n const updateMetrics = useCallback(() => {\n const now = Date.now();\n\n // Calculate totals from file metrics\n const totalBytes = fileMetrics.reduce((sum, file) => sum + file.size, 0);\n const totalBytesUploaded = fileMetrics.reduce(\n (sum, file) => sum + file.bytesUploaded,\n 0,\n );\n const completedFiles = fileMetrics.filter((file) => file.isComplete).length;\n const activeUploads = fileMetrics.filter(\n (file) => !file.isComplete && file.bytesUploaded > 0,\n ).length;\n\n // Calculate speeds\n const { currentSpeed, averageSpeed } = calculateSpeed(\n now,\n totalBytesUploaded,\n );\n\n // Calculate progress\n const progress =\n totalBytes > 0 ? Math.round((totalBytesUploaded / totalBytes) * 100) : 0;\n\n // Calculate estimated time remaining\n let estimatedTimeRemaining: number | null = null;\n if (currentSpeed > 0) {\n const remainingBytes = totalBytes - totalBytesUploaded;\n estimatedTimeRemaining = (remainingBytes / currentSpeed) * 1000; // Convert to milliseconds\n }\n\n // Find start and end times\n const activeTimes = fileMetrics.filter((file) => file.startTime > 0);\n const startTime =\n activeTimes.length > 0\n ? Math.min(...activeTimes.map((file) => file.startTime))\n : null;\n\n const completedTimes = fileMetrics.filter((file) => file.endTime !== null);\n const endTime =\n completedTimes.length > 0 && completedFiles === fileMetrics.length\n ? Math.max(\n ...completedTimes\n .map((file) => file.endTime)\n .filter((time) => time !== null),\n )\n : null;\n\n const totalDuration = startTime && endTime ? endTime - startTime : null;\n\n const newMetrics: UploadMetrics = {\n totalBytesUploaded,\n totalBytes,\n averageSpeed,\n currentSpeed,\n estimatedTimeRemaining,\n totalFiles: fileMetrics.length,\n completedFiles,\n activeUploads,\n progress,\n peakSpeed: Math.max(metrics.peakSpeed, currentSpeed),\n startTime,\n endTime,\n totalDuration,\n insights: uploadClient.client.getChunkingInsights(),\n sessionMetrics: [uploadClient.client.exportMetrics().session],\n chunkMetrics: uploadClient.client.exportMetrics().chunks,\n };\n\n setMetrics(newMetrics);\n onMetricsUpdate?.(newMetrics);\n }, [\n fileMetrics,\n metrics.peakSpeed,\n calculateSpeed,\n onMetricsUpdate,\n uploadClient.client,\n ]);\n\n // Set up periodic speed calculations\n const setupSpeedCalculation = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n }\n\n intervalRef.current = setInterval(() => {\n if (\n fileMetrics.some((file) => !file.isComplete && file.bytesUploaded > 0)\n ) {\n updateMetrics();\n }\n }, speedCalculationInterval);\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [speedCalculationInterval, updateMetrics, fileMetrics]);\n\n const startFileUpload = useCallback(\n (id: string, filename: string, size: number) => {\n const now = Date.now();\n\n const fileMetric: FileUploadMetrics = {\n id,\n filename,\n size,\n bytesUploaded: 0,\n progress: 0,\n speed: 0,\n startTime: now,\n endTime: null,\n duration: null,\n isComplete: false,\n };\n\n setFileMetrics((prev) => {\n const existing = prev.find((file) => file.id === id);\n if (existing) {\n return prev.map((file) => (file.id === id ? fileMetric : file));\n }\n return [...prev, fileMetric];\n });\n\n onFileStart?.(fileMetric);\n\n // Start speed calculation if this is the first active upload\n if (fileMetrics.filter((file) => !file.isComplete).length === 0) {\n setupSpeedCalculation();\n }\n },\n [fileMetrics, onFileStart, setupSpeedCalculation],\n );\n\n const updateFileProgress = useCallback(\n (id: string, bytesUploaded: number) => {\n const now = Date.now();\n\n setFileMetrics((prev) =>\n prev.map((file) => {\n if (file.id !== id) return file;\n\n const timeDiff = (now - file.startTime) / 1000; // seconds\n const speed = timeDiff > 0 ? bytesUploaded / timeDiff : 0;\n const progress =\n file.size > 0 ? Math.round((bytesUploaded / file.size) * 100) : 0;\n\n const updatedFile = {\n ...file,\n bytesUploaded,\n progress,\n speed,\n };\n\n onFileProgress?.(updatedFile);\n return updatedFile;\n }),\n );\n\n // Trigger metrics update\n setTimeout(updateMetrics, 0);\n },\n [onFileProgress, updateMetrics],\n );\n\n const completeFileUpload = useCallback(\n (id: string) => {\n const now = Date.now();\n\n setFileMetrics((prev) =>\n prev.map((file) => {\n if (file.id !== id) return file;\n\n const duration = now - file.startTime;\n const speed = duration > 0 ? (file.size / duration) * 1000 : 0; // bytes per second\n\n const completedFile = {\n ...file,\n bytesUploaded: file.size,\n progress: 100,\n speed,\n endTime: now,\n duration,\n isComplete: true,\n };\n\n onFileComplete?.(completedFile);\n return completedFile;\n }),\n );\n\n // Trigger metrics update\n setTimeout(updateMetrics, 0);\n },\n [onFileComplete, updateMetrics],\n );\n\n const removeFile = useCallback(\n (id: string) => {\n setFileMetrics((prev) => prev.filter((file) => file.id !== id));\n setTimeout(updateMetrics, 0);\n },\n [updateMetrics],\n );\n\n const reset = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n\n setMetrics(initialMetrics);\n setFileMetrics([]);\n speedSamplesRef.current = [];\n lastUpdateRef.current = 0;\n }, []);\n\n const getFileMetrics = useCallback(\n (id: string) => {\n return fileMetrics.find((file) => file.id === id);\n },\n [fileMetrics],\n );\n\n const exportMetrics = useCallback(() => {\n return {\n overall: metrics,\n files: fileMetrics,\n exportTime: Date.now(),\n };\n }, [metrics, fileMetrics]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n }\n };\n }, []);\n\n return {\n metrics,\n fileMetrics,\n startFileUpload,\n updateFileProgress,\n completeFileUpload,\n removeFile,\n reset,\n getFileMetrics,\n exportMetrics,\n };\n}\n"],"mappings":"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"}