@uploadista/client-core 0.0.20-beta.6 → 0.0.20-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +909 -909
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/src/client/__tests__/flow-inputs.test.ts +43 -11
- package/src/client/create-uploadista-client.ts +27 -13
- package/src/index.ts +2 -2
- package/src/managers/__tests__/upload-manager.test.ts +557 -545
- package/src/testing/index.ts +14 -14
- package/src/testing/mock-service-container.ts +4 -5
- package/src/types/index.ts +2 -2
- package/src/upload/index.ts +1 -1
- package/src/utils/__tests__/flow-inputs-builder.test.ts +5 -8
- package/src/utils/__tests__/input-validation.test.ts +1 -1
- package/src/utils/flow-inputs-builder.ts +2 -1
- package/src/utils/index.ts +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { UploadStrategyNegotiator } from "@uploadista/core/upload";
|
|
2
2
|
import { DataStoreCapabilities, InputFile, UploadEvent, UploadFile } from "@uploadista/core/types";
|
|
3
|
-
import z from "zod";
|
|
4
3
|
import { FlowData, FlowEvent, FlowJob, TypedOutput } from "@uploadista/core/flow";
|
|
4
|
+
import z from "zod";
|
|
5
5
|
import * as _uploadista_core0 from "@uploadista/core";
|
|
6
6
|
import { UploadFile as UploadFile$1 } from "@uploadista/core";
|
|
7
7
|
|
|
@@ -2769,38 +2769,185 @@ declare function createUploadistaClient<UploadInput$1>({
|
|
|
2769
2769
|
*/
|
|
2770
2770
|
type UploadistaClient = ReturnType<typeof createUploadistaClient>;
|
|
2771
2771
|
//#endregion
|
|
2772
|
-
//#region src/
|
|
2772
|
+
//#region src/managers/event-subscription-manager.d.ts
|
|
2773
2773
|
/**
|
|
2774
|
-
*
|
|
2775
|
-
* Used when AsyncStorage is not available or for testing
|
|
2774
|
+
* Generic event type that the subscription manager can handle
|
|
2776
2775
|
*/
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
type: "success";
|
|
2782
|
-
value: TOutput;
|
|
2783
|
-
} | {
|
|
2784
|
-
type: "error";
|
|
2785
|
-
error: Error;
|
|
2786
|
-
} | {
|
|
2787
|
-
type: "cancelled";
|
|
2788
|
-
};
|
|
2789
|
-
//#endregion
|
|
2790
|
-
//#region src/types/flow-upload-item.d.ts
|
|
2776
|
+
interface GenericEvent {
|
|
2777
|
+
type: string;
|
|
2778
|
+
data?: unknown;
|
|
2779
|
+
}
|
|
2791
2780
|
/**
|
|
2792
|
-
*
|
|
2781
|
+
* Event handler callback function
|
|
2793
2782
|
*/
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2783
|
+
type SubscriptionEventHandler<T = GenericEvent> = (event: T) => void;
|
|
2784
|
+
/**
|
|
2785
|
+
* Unsubscribe function returned from subscriptions
|
|
2786
|
+
*/
|
|
2787
|
+
type UnsubscribeFunction = () => void;
|
|
2788
|
+
/**
|
|
2789
|
+
* Event source that provides subscription capabilities
|
|
2790
|
+
*/
|
|
2791
|
+
interface EventSource<T = GenericEvent> {
|
|
2792
|
+
/**
|
|
2793
|
+
* Subscribe to events from this source
|
|
2794
|
+
* @returns Unsubscribe function to clean up the subscription
|
|
2795
|
+
*/
|
|
2796
|
+
subscribe(handler: SubscriptionEventHandler<T>): UnsubscribeFunction;
|
|
2797
|
+
}
|
|
2798
|
+
/**
|
|
2799
|
+
* Options for event filtering
|
|
2800
|
+
*/
|
|
2801
|
+
interface EventFilterOptions {
|
|
2802
|
+
/**
|
|
2803
|
+
* Filter events by type (exact match)
|
|
2804
|
+
*/
|
|
2805
|
+
eventType?: string;
|
|
2806
|
+
/**
|
|
2807
|
+
* Filter events by upload/job ID
|
|
2808
|
+
* If provided, only events with matching ID will be passed to the handler
|
|
2809
|
+
*/
|
|
2810
|
+
uploadId?: string | null;
|
|
2811
|
+
/**
|
|
2812
|
+
* Custom filter function for advanced filtering
|
|
2813
|
+
* Return true to pass the event to the handler
|
|
2814
|
+
*/
|
|
2815
|
+
customFilter?: (event: GenericEvent) => boolean;
|
|
2816
|
+
}
|
|
2817
|
+
/**
|
|
2818
|
+
* Platform-agnostic event subscription manager that handles event filtering,
|
|
2819
|
+
* subscription tracking, and automatic cleanup.
|
|
2820
|
+
*
|
|
2821
|
+
* This manager simplifies event handling by:
|
|
2822
|
+
* - Filtering events by type and/or ID
|
|
2823
|
+
* - Tracking all active subscriptions
|
|
2824
|
+
* - Providing cleanup methods to unsubscribe from all events
|
|
2825
|
+
* - Supporting custom filter functions for advanced scenarios
|
|
2826
|
+
*
|
|
2827
|
+
* @example Basic event subscription
|
|
2828
|
+
* ```typescript
|
|
2829
|
+
* const manager = new EventSubscriptionManager(eventSource);
|
|
2830
|
+
*
|
|
2831
|
+
* manager.subscribe(
|
|
2832
|
+
* (event) => console.log('Upload progress:', event),
|
|
2833
|
+
* { eventType: 'UPLOAD_PROGRESS', uploadId: 'abc123' }
|
|
2834
|
+
* );
|
|
2835
|
+
*
|
|
2836
|
+
* // Clean up all subscriptions when done
|
|
2837
|
+
* manager.cleanup();
|
|
2838
|
+
* ```
|
|
2839
|
+
*
|
|
2840
|
+
* @example Multiple filtered subscriptions
|
|
2841
|
+
* ```typescript
|
|
2842
|
+
* const manager = new EventSubscriptionManager(eventSource);
|
|
2843
|
+
*
|
|
2844
|
+
* // Subscribe to progress events for specific upload
|
|
2845
|
+
* manager.subscribe(
|
|
2846
|
+
* onProgress,
|
|
2847
|
+
* { eventType: 'UPLOAD_PROGRESS', uploadId: currentUploadId }
|
|
2848
|
+
* );
|
|
2849
|
+
*
|
|
2850
|
+
* // Subscribe to error events for any upload
|
|
2851
|
+
* manager.subscribe(
|
|
2852
|
+
* onError,
|
|
2853
|
+
* { eventType: 'UPLOAD_ERROR' }
|
|
2854
|
+
* );
|
|
2855
|
+
*
|
|
2856
|
+
* // Subscribe to all events with custom filtering
|
|
2857
|
+
* manager.subscribe(
|
|
2858
|
+
* onEvent,
|
|
2859
|
+
* { customFilter: (e) => e.data?.priority === 'high' }
|
|
2860
|
+
* );
|
|
2861
|
+
* ```
|
|
2862
|
+
*/
|
|
2863
|
+
declare class EventSubscriptionManager<T extends GenericEvent = GenericEvent> {
|
|
2864
|
+
private readonly eventSource;
|
|
2865
|
+
private subscriptions;
|
|
2866
|
+
/**
|
|
2867
|
+
* Create a new EventSubscriptionManager
|
|
2868
|
+
*
|
|
2869
|
+
* @param eventSource - Source to subscribe to for events
|
|
2870
|
+
*/
|
|
2871
|
+
constructor(eventSource: EventSource<T>);
|
|
2872
|
+
/**
|
|
2873
|
+
* Subscribe to events with optional filtering
|
|
2874
|
+
*
|
|
2875
|
+
* @param handler - Callback function to invoke when matching events occur
|
|
2876
|
+
* @param filter - Optional filter options to narrow down which events trigger the handler
|
|
2877
|
+
* @returns Unsubscribe function to remove this specific subscription
|
|
2878
|
+
*
|
|
2879
|
+
* @example Subscribe to specific event type
|
|
2880
|
+
* ```typescript
|
|
2881
|
+
* const unsubscribe = manager.subscribe(
|
|
2882
|
+
* (event) => console.log('Progress:', event),
|
|
2883
|
+
* { eventType: 'UPLOAD_PROGRESS' }
|
|
2884
|
+
* );
|
|
2885
|
+
*
|
|
2886
|
+
* // Later, unsubscribe
|
|
2887
|
+
* unsubscribe();
|
|
2888
|
+
* ```
|
|
2889
|
+
*/
|
|
2890
|
+
subscribe(handler: SubscriptionEventHandler<T>, filter?: EventFilterOptions): UnsubscribeFunction;
|
|
2891
|
+
/**
|
|
2892
|
+
* Check if an event matches the filter criteria
|
|
2893
|
+
*
|
|
2894
|
+
* @param event - Event to check
|
|
2895
|
+
* @param filter - Filter options to apply
|
|
2896
|
+
* @returns True if the event passes all filters
|
|
2897
|
+
*/
|
|
2898
|
+
private shouldHandleEvent;
|
|
2899
|
+
/**
|
|
2900
|
+
* Get the number of active subscriptions
|
|
2901
|
+
*
|
|
2902
|
+
* @returns Number of tracked subscriptions
|
|
2903
|
+
*/
|
|
2904
|
+
getSubscriptionCount(): number;
|
|
2905
|
+
/**
|
|
2906
|
+
* Check if there are any active subscriptions
|
|
2907
|
+
*
|
|
2908
|
+
* @returns True if at least one subscription is active
|
|
2909
|
+
*/
|
|
2910
|
+
hasSubscriptions(): boolean;
|
|
2911
|
+
/**
|
|
2912
|
+
* Unsubscribe from all tracked subscriptions and clear the subscription list
|
|
2913
|
+
*
|
|
2914
|
+
* This is typically called when disposing of a component or cleaning up resources.
|
|
2915
|
+
*
|
|
2916
|
+
* @example Cleanup in framework hooks
|
|
2917
|
+
* ```typescript
|
|
2918
|
+
* // React
|
|
2919
|
+
* useEffect(() => {
|
|
2920
|
+
* const manager = new EventSubscriptionManager(eventSource);
|
|
2921
|
+
* manager.subscribe(handler, filter);
|
|
2922
|
+
*
|
|
2923
|
+
* return () => manager.cleanup();
|
|
2924
|
+
* }, []);
|
|
2925
|
+
*
|
|
2926
|
+
* // Vue
|
|
2927
|
+
* onUnmounted(() => {
|
|
2928
|
+
* manager.cleanup();
|
|
2929
|
+
* });
|
|
2930
|
+
* ```
|
|
2931
|
+
*/
|
|
2932
|
+
cleanup(): void;
|
|
2933
|
+
/**
|
|
2934
|
+
* Update the upload ID filter for all subscriptions that have an uploadId filter
|
|
2935
|
+
*
|
|
2936
|
+
* This is useful when the current upload changes and you want to update
|
|
2937
|
+
* all subscriptions to listen for the new upload's events.
|
|
2938
|
+
*
|
|
2939
|
+
* @param newUploadId - New upload ID to filter events by
|
|
2940
|
+
*
|
|
2941
|
+
* @example Update upload ID when starting new upload
|
|
2942
|
+
* ```typescript
|
|
2943
|
+
* const manager = new EventSubscriptionManager(eventSource);
|
|
2944
|
+
* manager.subscribe(onProgress, { eventType: 'UPLOAD_PROGRESS', uploadId: null });
|
|
2945
|
+
*
|
|
2946
|
+
* // When upload starts
|
|
2947
|
+
* manager.updateUploadIdFilter(uploadId);
|
|
2948
|
+
* ```
|
|
2949
|
+
*/
|
|
2950
|
+
updateUploadIdFilter(newUploadId: string | null): void;
|
|
2804
2951
|
}
|
|
2805
2952
|
//#endregion
|
|
2806
2953
|
//#region src/types/flow-upload-options.d.ts
|
|
@@ -2877,643 +3024,472 @@ interface FlowUploadOptions {
|
|
|
2877
3024
|
onShouldRetry?: (error: Error, retryAttempt: number) => boolean;
|
|
2878
3025
|
}
|
|
2879
3026
|
//#endregion
|
|
2880
|
-
//#region src/
|
|
3027
|
+
//#region src/managers/flow-manager.d.ts
|
|
2881
3028
|
/**
|
|
2882
|
-
*
|
|
2883
|
-
*
|
|
2884
|
-
* This module defines types for passing input data to flows with multiple input nodes.
|
|
2885
|
-
* The FlowInputs type maps node IDs to their respective input data, enabling support
|
|
2886
|
-
* for flows with single or multiple input points.
|
|
2887
|
-
*
|
|
2888
|
-
* @module types/flow-inputs
|
|
2889
|
-
*
|
|
2890
|
-
* @example
|
|
2891
|
-
* ```typescript
|
|
2892
|
-
* import type { FlowInputs } from "@uploadista/client-core";
|
|
2893
|
-
*
|
|
2894
|
-
* // Single input flow
|
|
2895
|
-
* const inputs: FlowInputs = {
|
|
2896
|
-
* "file-input": {
|
|
2897
|
-
* operation: "url",
|
|
2898
|
-
* url: "https://example.com/image.jpg"
|
|
2899
|
-
* }
|
|
2900
|
-
* };
|
|
2901
|
-
*
|
|
2902
|
-
* // Multi-input flow
|
|
2903
|
-
* const multiInputs: FlowInputs = {
|
|
2904
|
-
* "file-input": {
|
|
2905
|
-
* operation: "init",
|
|
2906
|
-
* storageId: "s3",
|
|
2907
|
-
* metadata: { originalName: "image.jpg" }
|
|
2908
|
-
* },
|
|
2909
|
-
* "metadata-input": {
|
|
2910
|
-
* title: "My Image",
|
|
2911
|
-
* tags: ["photo", "landscape"]
|
|
2912
|
-
* }
|
|
2913
|
-
* };
|
|
2914
|
-
* ```
|
|
3029
|
+
* Flow upload status representing the current state of a flow upload lifecycle.
|
|
3030
|
+
* Flow uploads progress through: idle → uploading → processing → success/error/aborted
|
|
2915
3031
|
*/
|
|
3032
|
+
type FlowUploadStatus = "idle" | "uploading" | "processing" | "success" | "error" | "aborted";
|
|
2916
3033
|
/**
|
|
2917
|
-
*
|
|
2918
|
-
*
|
|
2919
|
-
* This type represents a map of input node IDs to their respective input data.
|
|
2920
|
-
* Each key is a node ID, and each value is the data to pass to that node.
|
|
2921
|
-
* The data structure depends on the node's registered input type.
|
|
2922
|
-
*
|
|
2923
|
-
* @remarks
|
|
2924
|
-
* Input data is validated against each node's registered type schema before
|
|
2925
|
-
* flow execution begins. Invalid data will result in validation errors.
|
|
2926
|
-
*
|
|
2927
|
-
* @example
|
|
2928
|
-
* ```typescript
|
|
2929
|
-
* // For streaming input node (init operation)
|
|
2930
|
-
* const fileUploadInputs: FlowInputs = {
|
|
2931
|
-
* "input-node-1": {
|
|
2932
|
-
* operation: "init",
|
|
2933
|
-
* storageId: "my-storage",
|
|
2934
|
-
* metadata: {
|
|
2935
|
-
* originalName: "photo.jpg",
|
|
2936
|
-
* mimeType: "image/jpeg",
|
|
2937
|
-
* size: 1024000
|
|
2938
|
-
* }
|
|
2939
|
-
* }
|
|
2940
|
-
* };
|
|
2941
|
-
*
|
|
2942
|
-
* // For streaming input node (URL operation)
|
|
2943
|
-
* const urlInputs: FlowInputs = {
|
|
2944
|
-
* "input-node-1": {
|
|
2945
|
-
* operation: "url",
|
|
2946
|
-
* url: "https://example.com/photo.jpg",
|
|
2947
|
-
* storageId: "my-storage",
|
|
2948
|
-
* metadata: {
|
|
2949
|
-
* source: "external"
|
|
2950
|
-
* }
|
|
2951
|
-
* }
|
|
2952
|
-
* };
|
|
2953
|
-
* ```
|
|
2954
|
-
*/
|
|
2955
|
-
type FlowInputs = Record<string, unknown>;
|
|
2956
|
-
/**
|
|
2957
|
-
* Helper type for single-input flows.
|
|
2958
|
-
*
|
|
2959
|
-
* Many flows have exactly one input node. This helper type makes it easier
|
|
2960
|
-
* to work with single-input scenarios without needing to know the node ID upfront.
|
|
2961
|
-
*
|
|
2962
|
-
* @example
|
|
2963
|
-
* ```typescript
|
|
2964
|
-
* const singleInput: SingleFlowInput = {
|
|
2965
|
-
* operation: "url",
|
|
2966
|
-
* url: "https://example.com/image.jpg"
|
|
2967
|
-
* };
|
|
2968
|
-
*
|
|
2969
|
-
* // The client can auto-discover the input node ID and convert this to FlowInputs
|
|
2970
|
-
* ```
|
|
2971
|
-
*/
|
|
2972
|
-
type SingleFlowInput = unknown;
|
|
2973
|
-
/**
|
|
2974
|
-
* Result of input node discovery.
|
|
2975
|
-
*
|
|
2976
|
-
* Contains information about discovered input nodes in a flow, including
|
|
2977
|
-
* their IDs, types, and whether the flow has a single or multiple inputs.
|
|
2978
|
-
*
|
|
2979
|
-
* @property inputNodes - Array of input node information
|
|
2980
|
-
* @property single - True if flow has exactly one input node
|
|
3034
|
+
* Complete state information for a flow upload operation.
|
|
3035
|
+
* Tracks both the upload phase (file transfer) and processing phase (flow execution).
|
|
2981
3036
|
*/
|
|
2982
|
-
interface
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
/**
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
/**
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
/**
|
|
3002
|
-
* Called when an individual upload progresses
|
|
3003
|
-
*/
|
|
3004
|
-
onItemProgress?: (item: FlowUploadItem<UploadInput$1>) => void;
|
|
3005
|
-
/**
|
|
3006
|
-
* Called when an individual upload succeeds
|
|
3007
|
-
*/
|
|
3008
|
-
onItemSuccess?: (item: FlowUploadItem<UploadInput$1>) => void;
|
|
3009
|
-
/**
|
|
3010
|
-
* Called when an individual upload fails
|
|
3011
|
-
*/
|
|
3012
|
-
onItemError?: (item: FlowUploadItem<UploadInput$1>, error: Error) => void;
|
|
3013
|
-
/**
|
|
3014
|
-
* Called when all uploads complete
|
|
3015
|
-
*/
|
|
3016
|
-
onComplete?: (items: FlowUploadItem<UploadInput$1>[]) => void;
|
|
3037
|
+
interface FlowUploadState {
|
|
3038
|
+
/** Current upload status */
|
|
3039
|
+
status: FlowUploadStatus;
|
|
3040
|
+
/** Upload progress percentage (0-100) */
|
|
3041
|
+
progress: number;
|
|
3042
|
+
/** Number of bytes uploaded */
|
|
3043
|
+
bytesUploaded: number;
|
|
3044
|
+
/** Total bytes to upload, null if unknown */
|
|
3045
|
+
totalBytes: number | null;
|
|
3046
|
+
/** Error if upload or processing failed */
|
|
3047
|
+
error: Error | null;
|
|
3048
|
+
/** Unique identifier for the flow execution job */
|
|
3049
|
+
jobId: string | null;
|
|
3050
|
+
/** Whether the flow processing has started */
|
|
3051
|
+
flowStarted: boolean;
|
|
3052
|
+
/** Name of the currently executing flow node */
|
|
3053
|
+
currentNodeName: string | null;
|
|
3054
|
+
/** Type of the currently executing flow node */
|
|
3055
|
+
currentNodeType: string | null;
|
|
3017
3056
|
/**
|
|
3018
|
-
*
|
|
3057
|
+
* Complete typed outputs from all output nodes in the flow.
|
|
3058
|
+
* Each output includes nodeId, optional nodeType, data, and timestamp.
|
|
3059
|
+
* Available when status is "success".
|
|
3019
3060
|
*/
|
|
3020
|
-
|
|
3061
|
+
flowOutputs: TypedOutput[] | null;
|
|
3021
3062
|
}
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3063
|
+
/**
|
|
3064
|
+
* State for a single input in a multi-input flow.
|
|
3065
|
+
*/
|
|
3066
|
+
interface InputExecutionState {
|
|
3067
|
+
/** Input node ID */
|
|
3068
|
+
nodeId: string;
|
|
3069
|
+
/** Input type (file, url, data) */
|
|
3070
|
+
type: "file" | "url" | "data";
|
|
3071
|
+
/** Current status of this input */
|
|
3072
|
+
status: "pending" | "uploading" | "complete" | "error";
|
|
3073
|
+
/** Progress percentage for file uploads (0-100) */
|
|
3074
|
+
progress: number;
|
|
3075
|
+
/** Bytes uploaded for file uploads */
|
|
3076
|
+
bytesUploaded: number;
|
|
3077
|
+
/** Total bytes for file uploads */
|
|
3078
|
+
totalBytes: number | null;
|
|
3079
|
+
/** Error if this input failed */
|
|
3080
|
+
error: Error | null;
|
|
3081
|
+
/** Abort controller for this specific input */
|
|
3082
|
+
abortController: FlowUploadAbortController | null;
|
|
3030
3083
|
}
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
* Upload metadata to attach to the file
|
|
3036
|
-
*/
|
|
3037
|
-
metadata?: Record<string, string>;
|
|
3038
|
-
/**
|
|
3039
|
-
* Whether to defer the upload size calculation
|
|
3040
|
-
*/
|
|
3041
|
-
uploadLengthDeferred?: boolean;
|
|
3084
|
+
/**
|
|
3085
|
+
* Callbacks that FlowManager invokes during the flow upload lifecycle
|
|
3086
|
+
*/
|
|
3087
|
+
interface FlowManagerCallbacks {
|
|
3042
3088
|
/**
|
|
3043
|
-
*
|
|
3089
|
+
* Called when the flow upload state changes
|
|
3044
3090
|
*/
|
|
3045
|
-
|
|
3091
|
+
onStateChange: (state: FlowUploadState) => void;
|
|
3046
3092
|
/**
|
|
3047
3093
|
* Called when upload progress updates
|
|
3048
|
-
*
|
|
3049
|
-
* @param
|
|
3050
|
-
* @param
|
|
3051
|
-
* @param totalBytes - Total bytes to upload, null if unknown/deferred
|
|
3094
|
+
* @param progress - Progress percentage (0-100)
|
|
3095
|
+
* @param bytesUploaded - Number of bytes uploaded
|
|
3096
|
+
* @param totalBytes - Total bytes to upload, null if unknown
|
|
3052
3097
|
*/
|
|
3053
3098
|
onProgress?: (uploadId: string, bytesUploaded: number, totalBytes: number | null) => void;
|
|
3054
3099
|
/**
|
|
3055
3100
|
* Called when a chunk completes
|
|
3056
|
-
*
|
|
3057
|
-
* @param
|
|
3058
|
-
* @param
|
|
3059
|
-
* @param bytesTotal - Total bytes to upload, null if unknown/deferred
|
|
3101
|
+
* @param chunkSize - Size of the completed chunk
|
|
3102
|
+
* @param bytesAccepted - Total bytes accepted so far
|
|
3103
|
+
* @param bytesTotal - Total bytes to upload, null if unknown
|
|
3060
3104
|
*/
|
|
3061
3105
|
onChunkComplete?: (chunkSize: number, bytesAccepted: number, bytesTotal: number | null) => void;
|
|
3062
3106
|
/**
|
|
3063
|
-
* Called when
|
|
3107
|
+
* Called when the flow completes successfully (receives full flow outputs)
|
|
3108
|
+
* Each output includes nodeId, optional nodeType (e.g., "storage-output-v1"), data, and timestamp.
|
|
3064
3109
|
*
|
|
3065
|
-
* @param
|
|
3110
|
+
* @param outputs - Array of typed outputs from all output nodes
|
|
3111
|
+
*
|
|
3112
|
+
* @example
|
|
3113
|
+
* ```typescript
|
|
3114
|
+
* onFlowComplete: (outputs) => {
|
|
3115
|
+
* for (const output of outputs) {
|
|
3116
|
+
* console.log(`${output.nodeId} (${output.nodeType}):`, output.data);
|
|
3117
|
+
* }
|
|
3118
|
+
* }
|
|
3119
|
+
* ```
|
|
3066
3120
|
*/
|
|
3067
|
-
|
|
3121
|
+
onFlowComplete?: (outputs: TypedOutput[]) => void;
|
|
3068
3122
|
/**
|
|
3069
|
-
* Called when upload
|
|
3123
|
+
* Called when upload succeeds (receives typed outputs from all output nodes)
|
|
3124
|
+
* Each output includes nodeId, optional nodeType (e.g., "storage-output-v1"), data, and timestamp.
|
|
3070
3125
|
*
|
|
3071
|
-
* @param
|
|
3126
|
+
* @param outputs - Array of typed outputs from all output nodes
|
|
3127
|
+
*
|
|
3128
|
+
* @example
|
|
3129
|
+
* ```typescript
|
|
3130
|
+
* onSuccess: (outputs) => {
|
|
3131
|
+
* for (const output of outputs) {
|
|
3132
|
+
* console.log(`${output.nodeId} completed:`, output.data);
|
|
3133
|
+
* }
|
|
3134
|
+
* }
|
|
3135
|
+
* ```
|
|
3072
3136
|
*/
|
|
3073
|
-
|
|
3137
|
+
onSuccess?: (outputs: TypedOutput[]) => void;
|
|
3074
3138
|
/**
|
|
3075
|
-
* Called when upload
|
|
3139
|
+
* Called when upload or flow processing fails with an error
|
|
3140
|
+
* @param error - The error that occurred
|
|
3076
3141
|
*/
|
|
3077
|
-
|
|
3142
|
+
onError?: (error: Error) => void;
|
|
3078
3143
|
/**
|
|
3079
|
-
*
|
|
3080
|
-
*
|
|
3081
|
-
* @param error - The error that triggered the retry check
|
|
3082
|
-
* @param retryAttempt - The current retry attempt number (0-indexed)
|
|
3083
|
-
* @returns true to retry, false to fail
|
|
3144
|
+
* Called when upload or flow is aborted
|
|
3084
3145
|
*/
|
|
3085
|
-
|
|
3146
|
+
onAbort?: () => void;
|
|
3086
3147
|
}
|
|
3087
|
-
//#endregion
|
|
3088
|
-
//#region src/types/upload-metrics.d.ts
|
|
3089
3148
|
/**
|
|
3090
|
-
*
|
|
3091
|
-
*
|
|
3092
|
-
* Provides access to all performance metrics, insights, and network
|
|
3093
|
-
* statistics for upload monitoring and optimization.
|
|
3094
|
-
*
|
|
3095
|
-
* This interface is implemented by all framework packages (React, Vue, React Native)
|
|
3096
|
-
* to ensure consistent metrics API across platforms.
|
|
3097
|
-
*
|
|
3098
|
-
* @example React usage
|
|
3099
|
-
* ```tsx
|
|
3100
|
-
* const upload = useUpload();
|
|
3101
|
-
* const insights = upload.metrics.getInsights();
|
|
3102
|
-
* const metrics = upload.metrics.exportMetrics();
|
|
3103
|
-
* ```
|
|
3104
|
-
*
|
|
3105
|
-
* @example Vue usage
|
|
3106
|
-
* ```vue
|
|
3107
|
-
* <script setup>
|
|
3108
|
-
* const upload = useUpload();
|
|
3109
|
-
* const insights = upload.metrics.getInsights();
|
|
3110
|
-
* </script>
|
|
3111
|
-
* ```
|
|
3149
|
+
* Generic flow execution input type - can be any value that the flow execution client accepts.
|
|
3150
|
+
* Common types include File, Blob, string (for URLs), or structured data objects.
|
|
3112
3151
|
*
|
|
3113
|
-
* @
|
|
3114
|
-
*
|
|
3115
|
-
*
|
|
3116
|
-
*
|
|
3117
|
-
*
|
|
3152
|
+
* @remarks
|
|
3153
|
+
* The flexibility of this type enables different flow execution patterns:
|
|
3154
|
+
* - File/Blob: Traditional chunked file upload with init/finalize operations
|
|
3155
|
+
* - string (URL): Direct file fetch from external URL
|
|
3156
|
+
* - object: Structured data for non-file input nodes (future)
|
|
3118
3157
|
*/
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
};
|
|
3158
|
+
type FlowUploadInput = unknown;
|
|
3159
|
+
/**
|
|
3160
|
+
* Flow configuration for upload
|
|
3161
|
+
*/
|
|
3162
|
+
interface FlowConfig {
|
|
3163
|
+
flowId: string;
|
|
3164
|
+
storageId: string;
|
|
3165
|
+
outputNodeId?: string;
|
|
3166
|
+
metadata?: Record<string, string>;
|
|
3167
|
+
}
|
|
3168
|
+
/**
|
|
3169
|
+
* Abort and pause controller interface for canceling/pausing flow uploads
|
|
3170
|
+
*/
|
|
3171
|
+
interface FlowUploadAbortController {
|
|
3172
|
+
abort: () => void | Promise<void>;
|
|
3173
|
+
pause: () => void | Promise<void>;
|
|
3174
|
+
}
|
|
3175
|
+
/**
|
|
3176
|
+
* Internal upload options used by the flow upload function.
|
|
3177
|
+
* The upload phase always returns UploadFile, regardless of the final TOutput type.
|
|
3178
|
+
*/
|
|
3179
|
+
interface InternalFlowUploadOptions {
|
|
3180
|
+
onJobStart?: (jobId: string) => void;
|
|
3181
|
+
onProgress?: (uploadId: string, bytesUploaded: number, totalBytes: number | null) => void;
|
|
3182
|
+
onChunkComplete?: (chunkSize: number, bytesAccepted: number, bytesTotal: number | null) => void;
|
|
3183
|
+
onSuccess?: (result: UploadFile) => void;
|
|
3184
|
+
onError?: (error: Error) => void;
|
|
3185
|
+
onAbort?: () => void;
|
|
3186
|
+
onShouldRetry?: (error: Error, retryAttempt: number) => boolean;
|
|
3187
|
+
}
|
|
3188
|
+
/**
|
|
3189
|
+
* Flow upload function that performs the actual upload with flow processing.
|
|
3190
|
+
* Returns a promise that resolves to an abort controller with pause capability.
|
|
3191
|
+
*
|
|
3192
|
+
* Note: The upload phase onSuccess always receives UploadFile. The final TOutput
|
|
3193
|
+
* result comes from the flow execution and is handled via FlowEnd events.
|
|
3194
|
+
*/
|
|
3195
|
+
type FlowUploadFunction<TInput = FlowUploadInput> = (input: TInput, flowConfig: FlowConfig, options: InternalFlowUploadOptions) => Promise<FlowUploadAbortController>;
|
|
3196
|
+
/**
|
|
3197
|
+
* Callbacks for tracking individual input progress in multi-input flows
|
|
3198
|
+
*/
|
|
3199
|
+
interface MultiInputCallbacks {
|
|
3162
3200
|
/**
|
|
3163
|
-
*
|
|
3164
|
-
*
|
|
3165
|
-
*
|
|
3166
|
-
*
|
|
3167
|
-
*
|
|
3168
|
-
* @returns Current network performance metrics
|
|
3169
|
-
*
|
|
3170
|
-
* @example
|
|
3171
|
-
* ```typescript
|
|
3172
|
-
* const network = metrics.getNetworkMetrics();
|
|
3173
|
-
* console.log(`Speed: ${network.currentSpeed} B/s`);
|
|
3174
|
-
* console.log(`Quality: ${network.condition.quality}`);
|
|
3175
|
-
* ```
|
|
3201
|
+
* Called when an input's progress updates
|
|
3202
|
+
* @param nodeId - The input node ID
|
|
3203
|
+
* @param progress - Progress percentage (0-100)
|
|
3204
|
+
* @param bytesUploaded - Bytes uploaded for this input
|
|
3205
|
+
* @param totalBytes - Total bytes for this input
|
|
3176
3206
|
*/
|
|
3177
|
-
|
|
3207
|
+
onInputProgress?: (nodeId: string, progress: number, bytesUploaded: number, totalBytes: number | null) => void;
|
|
3178
3208
|
/**
|
|
3179
|
-
*
|
|
3180
|
-
*
|
|
3181
|
-
* Provides assessment of current network quality with
|
|
3182
|
-
* recommendations for adaptive upload strategies.
|
|
3183
|
-
*
|
|
3184
|
-
* @returns Network condition assessment
|
|
3185
|
-
*
|
|
3186
|
-
* @example
|
|
3187
|
-
* ```typescript
|
|
3188
|
-
* const condition = metrics.getNetworkCondition();
|
|
3189
|
-
* if (condition.quality === 'poor') {
|
|
3190
|
-
* console.log('Consider reducing chunk size');
|
|
3191
|
-
* }
|
|
3192
|
-
* ```
|
|
3209
|
+
* Called when an input completes successfully
|
|
3210
|
+
* @param nodeId - The input node ID
|
|
3193
3211
|
*/
|
|
3194
|
-
|
|
3212
|
+
onInputComplete?: (nodeId: string) => void;
|
|
3195
3213
|
/**
|
|
3196
|
-
*
|
|
3197
|
-
*
|
|
3198
|
-
*
|
|
3199
|
-
* Useful when starting a new upload session.
|
|
3200
|
-
*
|
|
3201
|
-
* @example
|
|
3202
|
-
* ```typescript
|
|
3203
|
-
* // Reset metrics before starting new upload
|
|
3204
|
-
* metrics.resetMetrics();
|
|
3205
|
-
* upload(newFile);
|
|
3206
|
-
* ```
|
|
3214
|
+
* Called when an input fails
|
|
3215
|
+
* @param nodeId - The input node ID
|
|
3216
|
+
* @param error - The error that occurred
|
|
3207
3217
|
*/
|
|
3208
|
-
|
|
3218
|
+
onInputError?: (nodeId: string, error: Error) => void;
|
|
3209
3219
|
}
|
|
3210
|
-
//#endregion
|
|
3211
|
-
//#region src/types/upload-result.d.ts
|
|
3212
3220
|
/**
|
|
3213
|
-
*
|
|
3214
|
-
*
|
|
3215
|
-
* Provides a type-safe way to handle the three possible outcomes of an upload:
|
|
3216
|
-
* success, error, or cancellation. This pattern enables exhaustive checking
|
|
3217
|
-
* of all cases at compile time.
|
|
3221
|
+
* Multi-input flow upload function that coordinates multiple inputs in a single flow.
|
|
3222
|
+
* Platform packages should implement this to enable parallel multi-input upload support.
|
|
3218
3223
|
*
|
|
3219
|
-
* @
|
|
3224
|
+
* @param inputs - Record of nodeId to input data (File, URL string, or structured data)
|
|
3225
|
+
* @param flowConfig - Flow configuration
|
|
3226
|
+
* @param options - Upload callbacks and configuration
|
|
3227
|
+
* @param multiInputCallbacks - Per-input progress tracking callbacks
|
|
3228
|
+
* @returns Promise resolving to abort controller for the entire flow execution
|
|
3220
3229
|
*
|
|
3221
|
-
* @example
|
|
3230
|
+
* @example
|
|
3222
3231
|
* ```typescript
|
|
3223
|
-
*
|
|
3224
|
-
*
|
|
3225
|
-
*
|
|
3226
|
-
*
|
|
3227
|
-
*
|
|
3228
|
-
*
|
|
3229
|
-
*
|
|
3230
|
-
*
|
|
3231
|
-
*
|
|
3232
|
-
*
|
|
3233
|
-
*
|
|
3234
|
-
*
|
|
3235
|
-
* }
|
|
3232
|
+
* const uploadFn: MultiInputFlowUploadFunction = async (inputs, flowConfig, options, callbacks) => {
|
|
3233
|
+
* // 1. Start flow and create job
|
|
3234
|
+
* const jobId = await startFlow(flowConfig.flowId, flowConfig.storageId);
|
|
3235
|
+
*
|
|
3236
|
+
* // 2. Initialize all inputs in parallel using orchestrator functions
|
|
3237
|
+
* const initPromises = Object.entries(inputs).map(([nodeId, data]) =>
|
|
3238
|
+
* initializeFlowInput({ nodeId, jobId, source: data, ... })
|
|
3239
|
+
* );
|
|
3240
|
+
*
|
|
3241
|
+
* // 3. Upload files in parallel
|
|
3242
|
+
* // 4. Finalize all inputs
|
|
3243
|
+
* // 5. Return abort controller
|
|
3244
|
+
* };
|
|
3236
3245
|
* ```
|
|
3246
|
+
*/
|
|
3247
|
+
type MultiInputFlowUploadFunction = (inputs: Record<string, unknown>, flowConfig: FlowConfig, options: InternalFlowUploadOptions, multiInputCallbacks?: MultiInputCallbacks) => Promise<FlowUploadAbortController>;
|
|
3248
|
+
/**
|
|
3249
|
+
* Platform-agnostic flow execution manager that handles flow state machine,
|
|
3250
|
+
* progress tracking, flow event handling, error handling, abort, pause, reset, and retry logic.
|
|
3237
3251
|
*
|
|
3238
|
-
*
|
|
3252
|
+
* Supports multiple input types through generic TInput parameter:
|
|
3253
|
+
* - File/Blob: Chunked file upload with progress tracking
|
|
3254
|
+
* - string (URL): Direct file fetch from external source
|
|
3255
|
+
* - object: Structured data for custom input nodes
|
|
3256
|
+
*
|
|
3257
|
+
* Framework packages (React, Vue, React Native) should wrap this manager
|
|
3258
|
+
* with framework-specific hooks/composables.
|
|
3259
|
+
*
|
|
3260
|
+
* @template TInput - The type of input data accepted by the flow (File, Blob, string, object, etc.)
|
|
3261
|
+
*
|
|
3262
|
+
* @example
|
|
3239
3263
|
* ```typescript
|
|
3240
|
-
*
|
|
3241
|
-
*
|
|
3242
|
-
*
|
|
3243
|
-
* height: number;
|
|
3244
|
-
* }
|
|
3264
|
+
* // File upload flow
|
|
3265
|
+
* const fileFlowManager = new FlowManager<File>(...);
|
|
3266
|
+
* await fileFlowManager.upload(myFile);
|
|
3245
3267
|
*
|
|
3246
|
-
*
|
|
3268
|
+
* // URL fetch flow
|
|
3269
|
+
* const urlFlowManager = new FlowManager<string>(...);
|
|
3270
|
+
* await urlFlowManager.upload("https://example.com/image.jpg");
|
|
3247
3271
|
*
|
|
3248
|
-
*
|
|
3249
|
-
*
|
|
3250
|
-
* }
|
|
3272
|
+
* // Structured data flow
|
|
3273
|
+
* const dataFlowManager = new FlowManager<{ text: string }>(...);
|
|
3274
|
+
* await dataFlowManager.upload({ text: "Process this" });
|
|
3251
3275
|
* ```
|
|
3252
3276
|
*/
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
/**
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
/**
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
/**
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
/**
|
|
3285
|
-
* Event source that provides subscription capabilities
|
|
3286
|
-
*/
|
|
3287
|
-
interface EventSource<T = GenericEvent> {
|
|
3277
|
+
declare class FlowManager<TInput = FlowUploadInput> {
|
|
3278
|
+
private readonly flowUploadFn;
|
|
3279
|
+
private readonly callbacks;
|
|
3280
|
+
private readonly options;
|
|
3281
|
+
private readonly multiInputUploadFn?;
|
|
3282
|
+
private state;
|
|
3283
|
+
private abortController;
|
|
3284
|
+
private inputStates;
|
|
3285
|
+
/** Tracks the nodeId when executing a single-input flow via executeFlow() */
|
|
3286
|
+
private currentSingleInputNodeId;
|
|
3287
|
+
/**
|
|
3288
|
+
* Create a new FlowManager
|
|
3289
|
+
*
|
|
3290
|
+
* @param flowUploadFn - Flow upload function to use for uploads
|
|
3291
|
+
* @param callbacks - Callbacks to invoke during flow upload lifecycle
|
|
3292
|
+
* @param options - Flow upload configuration options
|
|
3293
|
+
* @param multiInputUploadFn - Optional multi-input upload function for executeFlow()
|
|
3294
|
+
*/
|
|
3295
|
+
constructor(flowUploadFn: FlowUploadFunction<TInput>, callbacks: FlowManagerCallbacks, options: FlowUploadOptions, multiInputUploadFn?: MultiInputFlowUploadFunction | undefined);
|
|
3296
|
+
/**
|
|
3297
|
+
* Get the current flow upload state
|
|
3298
|
+
*/
|
|
3299
|
+
getState(): FlowUploadState;
|
|
3300
|
+
/**
|
|
3301
|
+
* Check if an upload or flow is currently active
|
|
3302
|
+
*/
|
|
3303
|
+
isUploading(): boolean;
|
|
3304
|
+
/**
|
|
3305
|
+
* Check if file upload is in progress
|
|
3306
|
+
*/
|
|
3307
|
+
isUploadingFile(): boolean;
|
|
3288
3308
|
/**
|
|
3289
|
-
*
|
|
3290
|
-
* @returns Unsubscribe function to clean up the subscription
|
|
3309
|
+
* Check if flow processing is in progress
|
|
3291
3310
|
*/
|
|
3292
|
-
|
|
3293
|
-
}
|
|
3294
|
-
/**
|
|
3295
|
-
* Options for event filtering
|
|
3296
|
-
*/
|
|
3297
|
-
interface EventFilterOptions {
|
|
3311
|
+
isProcessing(): boolean;
|
|
3298
3312
|
/**
|
|
3299
|
-
*
|
|
3313
|
+
* Get the current job ID
|
|
3300
3314
|
*/
|
|
3301
|
-
|
|
3315
|
+
getJobId(): string | null;
|
|
3302
3316
|
/**
|
|
3303
|
-
*
|
|
3304
|
-
* If provided, only events with matching ID will be passed to the handler
|
|
3317
|
+
* Update the internal state and notify callbacks
|
|
3305
3318
|
*/
|
|
3306
|
-
|
|
3319
|
+
private updateState;
|
|
3307
3320
|
/**
|
|
3308
|
-
*
|
|
3309
|
-
*
|
|
3321
|
+
* Handle flow events from the event subscription
|
|
3322
|
+
* This method should be called by the framework wrapper when it receives flow events
|
|
3323
|
+
*
|
|
3324
|
+
* @param event - Flow event to process
|
|
3310
3325
|
*/
|
|
3311
|
-
|
|
3312
|
-
}
|
|
3313
|
-
/**
|
|
3314
|
-
* Platform-agnostic event subscription manager that handles event filtering,
|
|
3315
|
-
* subscription tracking, and automatic cleanup.
|
|
3316
|
-
*
|
|
3317
|
-
* This manager simplifies event handling by:
|
|
3318
|
-
* - Filtering events by type and/or ID
|
|
3319
|
-
* - Tracking all active subscriptions
|
|
3320
|
-
* - Providing cleanup methods to unsubscribe from all events
|
|
3321
|
-
* - Supporting custom filter functions for advanced scenarios
|
|
3322
|
-
*
|
|
3323
|
-
* @example Basic event subscription
|
|
3324
|
-
* ```typescript
|
|
3325
|
-
* const manager = new EventSubscriptionManager(eventSource);
|
|
3326
|
-
*
|
|
3327
|
-
* manager.subscribe(
|
|
3328
|
-
* (event) => console.log('Upload progress:', event),
|
|
3329
|
-
* { eventType: 'UPLOAD_PROGRESS', uploadId: 'abc123' }
|
|
3330
|
-
* );
|
|
3331
|
-
*
|
|
3332
|
-
* // Clean up all subscriptions when done
|
|
3333
|
-
* manager.cleanup();
|
|
3334
|
-
* ```
|
|
3335
|
-
*
|
|
3336
|
-
* @example Multiple filtered subscriptions
|
|
3337
|
-
* ```typescript
|
|
3338
|
-
* const manager = new EventSubscriptionManager(eventSource);
|
|
3339
|
-
*
|
|
3340
|
-
* // Subscribe to progress events for specific upload
|
|
3341
|
-
* manager.subscribe(
|
|
3342
|
-
* onProgress,
|
|
3343
|
-
* { eventType: 'UPLOAD_PROGRESS', uploadId: currentUploadId }
|
|
3344
|
-
* );
|
|
3345
|
-
*
|
|
3346
|
-
* // Subscribe to error events for any upload
|
|
3347
|
-
* manager.subscribe(
|
|
3348
|
-
* onError,
|
|
3349
|
-
* { eventType: 'UPLOAD_ERROR' }
|
|
3350
|
-
* );
|
|
3351
|
-
*
|
|
3352
|
-
* // Subscribe to all events with custom filtering
|
|
3353
|
-
* manager.subscribe(
|
|
3354
|
-
* onEvent,
|
|
3355
|
-
* { customFilter: (e) => e.data?.priority === 'high' }
|
|
3356
|
-
* );
|
|
3357
|
-
* ```
|
|
3358
|
-
*/
|
|
3359
|
-
declare class EventSubscriptionManager<T extends GenericEvent = GenericEvent> {
|
|
3360
|
-
private readonly eventSource;
|
|
3361
|
-
private subscriptions;
|
|
3326
|
+
handleFlowEvent(event: FlowEvent): void;
|
|
3362
3327
|
/**
|
|
3363
|
-
*
|
|
3328
|
+
* Handle upload progress events from the event subscription
|
|
3329
|
+
* This method should be called by the framework wrapper when it receives upload progress events
|
|
3364
3330
|
*
|
|
3365
|
-
* @param
|
|
3331
|
+
* @param uploadId - The unique identifier for this upload
|
|
3332
|
+
* @param bytesUploaded - Number of bytes uploaded
|
|
3333
|
+
* @param totalBytes - Total bytes to upload, null if unknown
|
|
3366
3334
|
*/
|
|
3367
|
-
|
|
3335
|
+
handleUploadProgress(uploadId: string, bytesUploaded: number, totalBytes: number | null): void;
|
|
3368
3336
|
/**
|
|
3369
|
-
*
|
|
3337
|
+
* Execute a flow with the provided input data.
|
|
3370
3338
|
*
|
|
3371
|
-
*
|
|
3372
|
-
*
|
|
3373
|
-
*
|
|
3339
|
+
* The input type and execution behavior depends on the generic TInput type:
|
|
3340
|
+
* - File/Blob: Initiates chunked upload with progress tracking
|
|
3341
|
+
* - string (URL): Directly passes URL to flow for fetching
|
|
3342
|
+
* - object: Passes structured data to flow input nodes
|
|
3374
3343
|
*
|
|
3375
|
-
* @
|
|
3344
|
+
* @param input - Input data for the flow execution (type determined by TInput generic)
|
|
3345
|
+
*
|
|
3346
|
+
* @example
|
|
3376
3347
|
* ```typescript
|
|
3377
|
-
*
|
|
3378
|
-
*
|
|
3379
|
-
* { eventType: 'UPLOAD_PROGRESS' }
|
|
3380
|
-
* );
|
|
3348
|
+
* // File upload
|
|
3349
|
+
* await manager.upload(fileObject);
|
|
3381
3350
|
*
|
|
3382
|
-
* //
|
|
3383
|
-
*
|
|
3351
|
+
* // URL fetch
|
|
3352
|
+
* await manager.upload("https://example.com/image.jpg");
|
|
3384
3353
|
* ```
|
|
3385
3354
|
*/
|
|
3386
|
-
|
|
3355
|
+
upload(input: TInput): Promise<void>;
|
|
3387
3356
|
/**
|
|
3388
|
-
*
|
|
3389
|
-
*
|
|
3390
|
-
* @param event - Event to check
|
|
3391
|
-
* @param filter - Filter options to apply
|
|
3392
|
-
* @returns True if the event passes all filters
|
|
3357
|
+
* Abort the current flow upload
|
|
3393
3358
|
*/
|
|
3394
|
-
|
|
3359
|
+
abort(): void;
|
|
3395
3360
|
/**
|
|
3396
|
-
*
|
|
3397
|
-
*
|
|
3398
|
-
* @returns Number of tracked subscriptions
|
|
3361
|
+
* Pause the current flow upload
|
|
3399
3362
|
*/
|
|
3400
|
-
|
|
3363
|
+
pause(): void;
|
|
3401
3364
|
/**
|
|
3402
|
-
*
|
|
3403
|
-
*
|
|
3404
|
-
* @returns True if at least one subscription is active
|
|
3365
|
+
* Reset the flow upload state to idle
|
|
3405
3366
|
*/
|
|
3406
|
-
|
|
3367
|
+
reset(): void;
|
|
3407
3368
|
/**
|
|
3408
|
-
*
|
|
3409
|
-
*
|
|
3410
|
-
|
|
3369
|
+
* Aggregate progress across multiple inputs.
|
|
3370
|
+
* Uses simple average for Phase 1 (size-weighted can be added in Phase 2).
|
|
3371
|
+
*/
|
|
3372
|
+
private aggregateProgress;
|
|
3373
|
+
/**
|
|
3374
|
+
* Execute a flow with multiple inputs (generic execution path).
|
|
3411
3375
|
*
|
|
3412
|
-
*
|
|
3413
|
-
*
|
|
3414
|
-
*
|
|
3415
|
-
*
|
|
3416
|
-
*
|
|
3417
|
-
* manager.subscribe(handler, filter);
|
|
3376
|
+
* This method:
|
|
3377
|
+
* 1. Builds FlowInputs with auto-detection
|
|
3378
|
+
* 2. Validates inputs (optional, to be added in integration)
|
|
3379
|
+
* 3. Executes flow with the inputs
|
|
3380
|
+
* 4. Tracks multi-input state
|
|
3418
3381
|
*
|
|
3419
|
-
*
|
|
3420
|
-
* }, []);
|
|
3382
|
+
* @param inputs - Map of nodeId to raw input data
|
|
3421
3383
|
*
|
|
3422
|
-
*
|
|
3423
|
-
*
|
|
3424
|
-
*
|
|
3384
|
+
* @example
|
|
3385
|
+
* ```typescript
|
|
3386
|
+
* await manager.executeFlow({
|
|
3387
|
+
* "file-input": myFile,
|
|
3388
|
+
* "url-input": "https://example.com/image.jpg"
|
|
3425
3389
|
* });
|
|
3426
3390
|
* ```
|
|
3427
3391
|
*/
|
|
3392
|
+
executeFlow(inputs: Record<string, unknown>): Promise<void>;
|
|
3393
|
+
/**
|
|
3394
|
+
* Get the input execution states (for multi-input flows).
|
|
3395
|
+
* @returns Map of nodeId to input state
|
|
3396
|
+
*/
|
|
3397
|
+
getInputStates(): ReadonlyMap<string, InputExecutionState>;
|
|
3398
|
+
/**
|
|
3399
|
+
* Clean up resources (call when disposing the manager)
|
|
3400
|
+
*/
|
|
3428
3401
|
cleanup(): void;
|
|
3402
|
+
}
|
|
3403
|
+
//#endregion
|
|
3404
|
+
//#region src/types/upload-options.d.ts
|
|
3405
|
+
interface UploadOptions {
|
|
3429
3406
|
/**
|
|
3430
|
-
*
|
|
3407
|
+
* Upload metadata to attach to the file
|
|
3408
|
+
*/
|
|
3409
|
+
metadata?: Record<string, string>;
|
|
3410
|
+
/**
|
|
3411
|
+
* Whether to defer the upload size calculation
|
|
3412
|
+
*/
|
|
3413
|
+
uploadLengthDeferred?: boolean;
|
|
3414
|
+
/**
|
|
3415
|
+
* Manual upload size override
|
|
3416
|
+
*/
|
|
3417
|
+
uploadSize?: number;
|
|
3418
|
+
/**
|
|
3419
|
+
* Called when upload progress updates
|
|
3431
3420
|
*
|
|
3432
|
-
*
|
|
3433
|
-
*
|
|
3421
|
+
* @param uploadId - The unique identifier for this upload
|
|
3422
|
+
* @param bytesUploaded - Number of bytes uploaded so far
|
|
3423
|
+
* @param totalBytes - Total bytes to upload, null if unknown/deferred
|
|
3424
|
+
*/
|
|
3425
|
+
onProgress?: (uploadId: string, bytesUploaded: number, totalBytes: number | null) => void;
|
|
3426
|
+
/**
|
|
3427
|
+
* Called when a chunk completes
|
|
3434
3428
|
*
|
|
3435
|
-
* @param
|
|
3429
|
+
* @param chunkSize - Size of the completed chunk in bytes
|
|
3430
|
+
* @param bytesAccepted - Total bytes accepted by server so far
|
|
3431
|
+
* @param bytesTotal - Total bytes to upload, null if unknown/deferred
|
|
3432
|
+
*/
|
|
3433
|
+
onChunkComplete?: (chunkSize: number, bytesAccepted: number, bytesTotal: number | null) => void;
|
|
3434
|
+
/**
|
|
3435
|
+
* Called when upload succeeds
|
|
3436
3436
|
*
|
|
3437
|
-
* @
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3437
|
+
* @param result - The uploaded file result
|
|
3438
|
+
*/
|
|
3439
|
+
onSuccess?: (result: UploadFile$1) => void;
|
|
3440
|
+
/**
|
|
3441
|
+
* Called when upload fails
|
|
3441
3442
|
*
|
|
3442
|
-
*
|
|
3443
|
-
* manager.updateUploadIdFilter(uploadId);
|
|
3444
|
-
* ```
|
|
3443
|
+
* @param error - The error that caused the failure
|
|
3445
3444
|
*/
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
* Flow upload status representing the current state of a flow upload lifecycle.
|
|
3452
|
-
* Flow uploads progress through: idle → uploading → processing → success/error/aborted
|
|
3453
|
-
*/
|
|
3454
|
-
type FlowUploadStatus = "idle" | "uploading" | "processing" | "success" | "error" | "aborted";
|
|
3455
|
-
/**
|
|
3456
|
-
* Complete state information for a flow upload operation.
|
|
3457
|
-
* Tracks both the upload phase (file transfer) and processing phase (flow execution).
|
|
3458
|
-
*/
|
|
3459
|
-
interface FlowUploadState {
|
|
3460
|
-
/** Current upload status */
|
|
3461
|
-
status: FlowUploadStatus;
|
|
3462
|
-
/** Upload progress percentage (0-100) */
|
|
3463
|
-
progress: number;
|
|
3464
|
-
/** Number of bytes uploaded */
|
|
3465
|
-
bytesUploaded: number;
|
|
3466
|
-
/** Total bytes to upload, null if unknown */
|
|
3467
|
-
totalBytes: number | null;
|
|
3468
|
-
/** Error if upload or processing failed */
|
|
3469
|
-
error: Error | null;
|
|
3470
|
-
/** Unique identifier for the flow execution job */
|
|
3471
|
-
jobId: string | null;
|
|
3472
|
-
/** Whether the flow processing has started */
|
|
3473
|
-
flowStarted: boolean;
|
|
3474
|
-
/** Name of the currently executing flow node */
|
|
3475
|
-
currentNodeName: string | null;
|
|
3476
|
-
/** Type of the currently executing flow node */
|
|
3477
|
-
currentNodeType: string | null;
|
|
3445
|
+
onError?: (error: Error) => void;
|
|
3446
|
+
/**
|
|
3447
|
+
* Called when upload is aborted
|
|
3448
|
+
*/
|
|
3449
|
+
onAbort?: () => void;
|
|
3478
3450
|
/**
|
|
3479
|
-
*
|
|
3480
|
-
*
|
|
3481
|
-
*
|
|
3451
|
+
* Custom retry logic
|
|
3452
|
+
*
|
|
3453
|
+
* @param error - The error that triggered the retry check
|
|
3454
|
+
* @param retryAttempt - The current retry attempt number (0-indexed)
|
|
3455
|
+
* @returns true to retry, false to fail
|
|
3482
3456
|
*/
|
|
3483
|
-
|
|
3457
|
+
onShouldRetry?: (error: Error, retryAttempt: number) => boolean;
|
|
3484
3458
|
}
|
|
3459
|
+
//#endregion
|
|
3460
|
+
//#region src/managers/upload-manager.d.ts
|
|
3485
3461
|
/**
|
|
3486
|
-
*
|
|
3462
|
+
* Upload status representing the current state of an upload
|
|
3487
3463
|
*/
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
/** Current status of
|
|
3494
|
-
status:
|
|
3495
|
-
/**
|
|
3464
|
+
type UploadStatus = "idle" | "uploading" | "success" | "error" | "aborted";
|
|
3465
|
+
/**
|
|
3466
|
+
* Complete upload state
|
|
3467
|
+
*/
|
|
3468
|
+
interface UploadState {
|
|
3469
|
+
/** Current status of the upload */
|
|
3470
|
+
status: UploadStatus;
|
|
3471
|
+
/** Upload progress percentage (0-100) */
|
|
3496
3472
|
progress: number;
|
|
3497
|
-
/**
|
|
3473
|
+
/** Number of bytes uploaded */
|
|
3498
3474
|
bytesUploaded: number;
|
|
3499
|
-
/** Total bytes
|
|
3475
|
+
/** Total bytes to upload, null if unknown/deferred */
|
|
3500
3476
|
totalBytes: number | null;
|
|
3501
|
-
/** Error if
|
|
3477
|
+
/** Error if upload failed */
|
|
3502
3478
|
error: Error | null;
|
|
3503
|
-
/**
|
|
3504
|
-
|
|
3479
|
+
/** Result if upload succeeded */
|
|
3480
|
+
result: UploadFile | null;
|
|
3505
3481
|
}
|
|
3506
3482
|
/**
|
|
3507
|
-
* Callbacks that
|
|
3483
|
+
* Callbacks that UploadManager invokes during the upload lifecycle
|
|
3508
3484
|
*/
|
|
3509
|
-
interface
|
|
3485
|
+
interface UploadManagerCallbacks {
|
|
3510
3486
|
/**
|
|
3511
|
-
* Called when the
|
|
3487
|
+
* Called when the upload state changes
|
|
3512
3488
|
*/
|
|
3513
|
-
onStateChange: (state:
|
|
3489
|
+
onStateChange: (state: UploadState) => void;
|
|
3514
3490
|
/**
|
|
3515
3491
|
* Called when upload progress updates
|
|
3516
|
-
* @param
|
|
3492
|
+
* @param uploadId - The unique identifier for this upload
|
|
3517
3493
|
* @param bytesUploaded - Number of bytes uploaded
|
|
3518
3494
|
* @param totalBytes - Total bytes to upload, null if unknown
|
|
3519
3495
|
*/
|
|
@@ -3526,452 +3502,476 @@ interface FlowManagerCallbacks {
|
|
|
3526
3502
|
*/
|
|
3527
3503
|
onChunkComplete?: (chunkSize: number, bytesAccepted: number, bytesTotal: number | null) => void;
|
|
3528
3504
|
/**
|
|
3529
|
-
* Called when
|
|
3530
|
-
*
|
|
3531
|
-
*
|
|
3532
|
-
* @param outputs - Array of typed outputs from all output nodes
|
|
3533
|
-
*
|
|
3534
|
-
* @example
|
|
3535
|
-
* ```typescript
|
|
3536
|
-
* onFlowComplete: (outputs) => {
|
|
3537
|
-
* for (const output of outputs) {
|
|
3538
|
-
* console.log(`${output.nodeId} (${output.nodeType}):`, output.data);
|
|
3539
|
-
* }
|
|
3540
|
-
* }
|
|
3541
|
-
* ```
|
|
3542
|
-
*/
|
|
3543
|
-
onFlowComplete?: (outputs: TypedOutput[]) => void;
|
|
3544
|
-
/**
|
|
3545
|
-
* Called when upload succeeds (receives typed outputs from all output nodes)
|
|
3546
|
-
* Each output includes nodeId, optional nodeType (e.g., "storage-output-v1"), data, and timestamp.
|
|
3547
|
-
*
|
|
3548
|
-
* @param outputs - Array of typed outputs from all output nodes
|
|
3549
|
-
*
|
|
3550
|
-
* @example
|
|
3551
|
-
* ```typescript
|
|
3552
|
-
* onSuccess: (outputs) => {
|
|
3553
|
-
* for (const output of outputs) {
|
|
3554
|
-
* console.log(`${output.nodeId} completed:`, output.data);
|
|
3555
|
-
* }
|
|
3556
|
-
* }
|
|
3557
|
-
* ```
|
|
3505
|
+
* Called when upload completes successfully
|
|
3506
|
+
* @param result - The uploaded file result
|
|
3558
3507
|
*/
|
|
3559
|
-
onSuccess?: (
|
|
3508
|
+
onSuccess?: (result: UploadFile) => void;
|
|
3560
3509
|
/**
|
|
3561
|
-
* Called when upload
|
|
3510
|
+
* Called when upload fails with an error
|
|
3562
3511
|
* @param error - The error that occurred
|
|
3563
3512
|
*/
|
|
3564
3513
|
onError?: (error: Error) => void;
|
|
3565
3514
|
/**
|
|
3566
|
-
* Called when upload
|
|
3515
|
+
* Called when upload is aborted
|
|
3567
3516
|
*/
|
|
3568
3517
|
onAbort?: () => void;
|
|
3569
3518
|
}
|
|
3570
3519
|
/**
|
|
3571
|
-
* Generic
|
|
3572
|
-
* Common types include File, Blob, string (for URLs), or structured data objects.
|
|
3573
|
-
*
|
|
3574
|
-
* @remarks
|
|
3575
|
-
* The flexibility of this type enables different flow execution patterns:
|
|
3576
|
-
* - File/Blob: Traditional chunked file upload with init/finalize operations
|
|
3577
|
-
* - string (URL): Direct file fetch from external URL
|
|
3578
|
-
* - object: Structured data for non-file input nodes (future)
|
|
3579
|
-
*/
|
|
3580
|
-
type FlowUploadInput = unknown;
|
|
3581
|
-
/**
|
|
3582
|
-
* Flow configuration for upload
|
|
3583
|
-
*/
|
|
3584
|
-
interface FlowConfig {
|
|
3585
|
-
flowId: string;
|
|
3586
|
-
storageId: string;
|
|
3587
|
-
outputNodeId?: string;
|
|
3588
|
-
metadata?: Record<string, string>;
|
|
3589
|
-
}
|
|
3590
|
-
/**
|
|
3591
|
-
* Abort and pause controller interface for canceling/pausing flow uploads
|
|
3592
|
-
*/
|
|
3593
|
-
interface FlowUploadAbortController {
|
|
3594
|
-
abort: () => void | Promise<void>;
|
|
3595
|
-
pause: () => void | Promise<void>;
|
|
3596
|
-
}
|
|
3597
|
-
/**
|
|
3598
|
-
* Internal upload options used by the flow upload function.
|
|
3599
|
-
* The upload phase always returns UploadFile, regardless of the final TOutput type.
|
|
3600
|
-
*/
|
|
3601
|
-
interface InternalFlowUploadOptions {
|
|
3602
|
-
onJobStart?: (jobId: string) => void;
|
|
3603
|
-
onProgress?: (uploadId: string, bytesUploaded: number, totalBytes: number | null) => void;
|
|
3604
|
-
onChunkComplete?: (chunkSize: number, bytesAccepted: number, bytesTotal: number | null) => void;
|
|
3605
|
-
onSuccess?: (result: UploadFile) => void;
|
|
3606
|
-
onError?: (error: Error) => void;
|
|
3607
|
-
onAbort?: () => void;
|
|
3608
|
-
onShouldRetry?: (error: Error, retryAttempt: number) => boolean;
|
|
3609
|
-
}
|
|
3610
|
-
/**
|
|
3611
|
-
* Flow upload function that performs the actual upload with flow processing.
|
|
3612
|
-
* Returns a promise that resolves to an abort controller with pause capability.
|
|
3613
|
-
*
|
|
3614
|
-
* Note: The upload phase onSuccess always receives UploadFile. The final TOutput
|
|
3615
|
-
* result comes from the flow execution and is handled via FlowEnd events.
|
|
3520
|
+
* Generic upload input type - can be any value that the upload client accepts
|
|
3616
3521
|
*/
|
|
3617
|
-
type
|
|
3522
|
+
type UploadInput = unknown;
|
|
3618
3523
|
/**
|
|
3619
|
-
*
|
|
3524
|
+
* Abort controller interface for canceling uploads
|
|
3620
3525
|
*/
|
|
3621
|
-
interface
|
|
3622
|
-
|
|
3623
|
-
* Called when an input's progress updates
|
|
3624
|
-
* @param nodeId - The input node ID
|
|
3625
|
-
* @param progress - Progress percentage (0-100)
|
|
3626
|
-
* @param bytesUploaded - Bytes uploaded for this input
|
|
3627
|
-
* @param totalBytes - Total bytes for this input
|
|
3628
|
-
*/
|
|
3629
|
-
onInputProgress?: (nodeId: string, progress: number, bytesUploaded: number, totalBytes: number | null) => void;
|
|
3630
|
-
/**
|
|
3631
|
-
* Called when an input completes successfully
|
|
3632
|
-
* @param nodeId - The input node ID
|
|
3633
|
-
*/
|
|
3634
|
-
onInputComplete?: (nodeId: string) => void;
|
|
3635
|
-
/**
|
|
3636
|
-
* Called when an input fails
|
|
3637
|
-
* @param nodeId - The input node ID
|
|
3638
|
-
* @param error - The error that occurred
|
|
3639
|
-
*/
|
|
3640
|
-
onInputError?: (nodeId: string, error: Error) => void;
|
|
3526
|
+
interface UploadAbortController {
|
|
3527
|
+
abort: () => void;
|
|
3641
3528
|
}
|
|
3642
3529
|
/**
|
|
3643
|
-
*
|
|
3644
|
-
*
|
|
3645
|
-
*
|
|
3646
|
-
* @param inputs - Record of nodeId to input data (File, URL string, or structured data)
|
|
3647
|
-
* @param flowConfig - Flow configuration
|
|
3648
|
-
* @param options - Upload callbacks and configuration
|
|
3649
|
-
* @param multiInputCallbacks - Per-input progress tracking callbacks
|
|
3650
|
-
* @returns Promise resolving to abort controller for the entire flow execution
|
|
3651
|
-
*
|
|
3652
|
-
* @example
|
|
3653
|
-
* ```typescript
|
|
3654
|
-
* const uploadFn: MultiInputFlowUploadFunction = async (inputs, flowConfig, options, callbacks) => {
|
|
3655
|
-
* // 1. Start flow and create job
|
|
3656
|
-
* const jobId = await startFlow(flowConfig.flowId, flowConfig.storageId);
|
|
3657
|
-
*
|
|
3658
|
-
* // 2. Initialize all inputs in parallel using orchestrator functions
|
|
3659
|
-
* const initPromises = Object.entries(inputs).map(([nodeId, data]) =>
|
|
3660
|
-
* initializeFlowInput({ nodeId, jobId, source: data, ... })
|
|
3661
|
-
* );
|
|
3662
|
-
*
|
|
3663
|
-
* // 3. Upload files in parallel
|
|
3664
|
-
* // 4. Finalize all inputs
|
|
3665
|
-
* // 5. Return abort controller
|
|
3666
|
-
* };
|
|
3667
|
-
* ```
|
|
3530
|
+
* Upload function that performs the actual upload.
|
|
3531
|
+
* Returns a promise that resolves to an abort controller.
|
|
3668
3532
|
*/
|
|
3669
|
-
type
|
|
3533
|
+
type UploadFunction<TInput = UploadInput, TOptions extends UploadOptions = UploadOptions> = (input: TInput, options: TOptions) => Promise<UploadAbortController>;
|
|
3670
3534
|
/**
|
|
3671
|
-
* Platform-agnostic
|
|
3672
|
-
* progress tracking,
|
|
3673
|
-
*
|
|
3674
|
-
* Supports multiple input types through generic TInput parameter:
|
|
3675
|
-
* - File/Blob: Chunked file upload with progress tracking
|
|
3676
|
-
* - string (URL): Direct file fetch from external source
|
|
3677
|
-
* - object: Structured data for custom input nodes
|
|
3535
|
+
* Platform-agnostic upload manager that handles upload state machine,
|
|
3536
|
+
* progress tracking, error handling, abort, reset, and retry logic.
|
|
3678
3537
|
*
|
|
3679
3538
|
* Framework packages (React, Vue, React Native) should wrap this manager
|
|
3680
3539
|
* with framework-specific hooks/composables.
|
|
3681
3540
|
*
|
|
3682
|
-
* @template TInput - The type of input data accepted by the flow (File, Blob, string, object, etc.)
|
|
3683
|
-
*
|
|
3684
3541
|
* @example
|
|
3685
3542
|
* ```typescript
|
|
3686
|
-
*
|
|
3687
|
-
* const
|
|
3688
|
-
*
|
|
3689
|
-
*
|
|
3690
|
-
*
|
|
3691
|
-
*
|
|
3692
|
-
*
|
|
3543
|
+
* const uploadFn = (input, options) => client.upload(input, options);
|
|
3544
|
+
* const manager = new UploadManager(uploadFn, {
|
|
3545
|
+
* onStateChange: (state) => setState(state),
|
|
3546
|
+
* onProgress: (progress) => console.log(`${progress}%`),
|
|
3547
|
+
* onSuccess: (result) => console.log('Upload complete:', result),
|
|
3548
|
+
* onError: (error) => console.error('Upload failed:', error),
|
|
3549
|
+
* });
|
|
3693
3550
|
*
|
|
3694
|
-
*
|
|
3695
|
-
* const dataFlowManager = new FlowManager<{ text: string }>(...);
|
|
3696
|
-
* await dataFlowManager.upload({ text: "Process this" });
|
|
3551
|
+
* await manager.upload(file);
|
|
3697
3552
|
* ```
|
|
3698
3553
|
*/
|
|
3699
|
-
declare class
|
|
3700
|
-
private readonly
|
|
3554
|
+
declare class UploadManager<TInput = UploadInput, TOptions extends UploadOptions = UploadOptions> {
|
|
3555
|
+
private readonly uploadFn;
|
|
3701
3556
|
private readonly callbacks;
|
|
3702
|
-
private readonly options
|
|
3703
|
-
private readonly multiInputUploadFn?;
|
|
3557
|
+
private readonly options?;
|
|
3704
3558
|
private state;
|
|
3705
3559
|
private abortController;
|
|
3706
|
-
private
|
|
3707
|
-
|
|
3708
|
-
private currentSingleInputNodeId;
|
|
3560
|
+
private lastInput;
|
|
3561
|
+
private uploadId;
|
|
3709
3562
|
/**
|
|
3710
|
-
* Create a new
|
|
3563
|
+
* Create a new UploadManager
|
|
3711
3564
|
*
|
|
3712
|
-
* @param
|
|
3713
|
-
* @param callbacks - Callbacks to invoke during
|
|
3714
|
-
* @param options -
|
|
3715
|
-
* @param multiInputUploadFn - Optional multi-input upload function for executeFlow()
|
|
3716
|
-
*/
|
|
3717
|
-
constructor(flowUploadFn: FlowUploadFunction<TInput>, callbacks: FlowManagerCallbacks, options: FlowUploadOptions, multiInputUploadFn?: MultiInputFlowUploadFunction | undefined);
|
|
3718
|
-
/**
|
|
3719
|
-
* Get the current flow upload state
|
|
3720
|
-
*/
|
|
3721
|
-
getState(): FlowUploadState;
|
|
3722
|
-
/**
|
|
3723
|
-
* Check if an upload or flow is currently active
|
|
3724
|
-
*/
|
|
3725
|
-
isUploading(): boolean;
|
|
3726
|
-
/**
|
|
3727
|
-
* Check if file upload is in progress
|
|
3728
|
-
*/
|
|
3729
|
-
isUploadingFile(): boolean;
|
|
3730
|
-
/**
|
|
3731
|
-
* Check if flow processing is in progress
|
|
3565
|
+
* @param uploadFn - Upload function to use for uploads
|
|
3566
|
+
* @param callbacks - Callbacks to invoke during upload lifecycle
|
|
3567
|
+
* @param options - Upload configuration options
|
|
3732
3568
|
*/
|
|
3733
|
-
|
|
3569
|
+
constructor(uploadFn: UploadFunction<TInput, TOptions>, callbacks: UploadManagerCallbacks, options?: TOptions | undefined);
|
|
3734
3570
|
/**
|
|
3735
|
-
* Get the current
|
|
3571
|
+
* Get the current upload state
|
|
3736
3572
|
*/
|
|
3737
|
-
|
|
3573
|
+
getState(): UploadState;
|
|
3738
3574
|
/**
|
|
3739
|
-
*
|
|
3575
|
+
* Check if an upload is currently active
|
|
3740
3576
|
*/
|
|
3741
|
-
|
|
3577
|
+
isUploading(): boolean;
|
|
3742
3578
|
/**
|
|
3743
|
-
*
|
|
3744
|
-
* This method should be called by the framework wrapper when it receives flow events
|
|
3745
|
-
*
|
|
3746
|
-
* @param event - Flow event to process
|
|
3579
|
+
* Check if the upload can be retried
|
|
3747
3580
|
*/
|
|
3748
|
-
|
|
3581
|
+
canRetry(): boolean;
|
|
3749
3582
|
/**
|
|
3750
|
-
*
|
|
3751
|
-
* This method should be called by the framework wrapper when it receives upload progress events
|
|
3752
|
-
*
|
|
3753
|
-
* @param uploadId - The unique identifier for this upload
|
|
3754
|
-
* @param bytesUploaded - Number of bytes uploaded
|
|
3755
|
-
* @param totalBytes - Total bytes to upload, null if unknown
|
|
3583
|
+
* Update the internal state and notify callbacks
|
|
3756
3584
|
*/
|
|
3757
|
-
|
|
3585
|
+
private updateState;
|
|
3758
3586
|
/**
|
|
3759
|
-
*
|
|
3760
|
-
*
|
|
3761
|
-
* The input type and execution behavior depends on the generic TInput type:
|
|
3762
|
-
* - File/Blob: Initiates chunked upload with progress tracking
|
|
3763
|
-
* - string (URL): Directly passes URL to flow for fetching
|
|
3764
|
-
* - object: Passes structured data to flow input nodes
|
|
3765
|
-
*
|
|
3766
|
-
* @param input - Input data for the flow execution (type determined by TInput generic)
|
|
3767
|
-
*
|
|
3768
|
-
* @example
|
|
3769
|
-
* ```typescript
|
|
3770
|
-
* // File upload
|
|
3771
|
-
* await manager.upload(fileObject);
|
|
3587
|
+
* Start uploading a file or input
|
|
3772
3588
|
*
|
|
3773
|
-
*
|
|
3774
|
-
* await manager.upload("https://example.com/image.jpg");
|
|
3775
|
-
* ```
|
|
3589
|
+
* @param input - File or input to upload (type depends on platform)
|
|
3776
3590
|
*/
|
|
3777
3591
|
upload(input: TInput): Promise<void>;
|
|
3778
3592
|
/**
|
|
3779
|
-
* Abort the current
|
|
3593
|
+
* Abort the current upload
|
|
3780
3594
|
*/
|
|
3781
3595
|
abort(): void;
|
|
3782
3596
|
/**
|
|
3783
|
-
*
|
|
3784
|
-
*/
|
|
3785
|
-
pause(): void;
|
|
3786
|
-
/**
|
|
3787
|
-
* Reset the flow upload state to idle
|
|
3597
|
+
* Reset the upload state to idle
|
|
3788
3598
|
*/
|
|
3789
3599
|
reset(): void;
|
|
3790
3600
|
/**
|
|
3791
|
-
*
|
|
3792
|
-
* Uses simple average for Phase 1 (size-weighted can be added in Phase 2).
|
|
3793
|
-
*/
|
|
3794
|
-
private aggregateProgress;
|
|
3795
|
-
/**
|
|
3796
|
-
* Execute a flow with multiple inputs (generic execution path).
|
|
3797
|
-
*
|
|
3798
|
-
* This method:
|
|
3799
|
-
* 1. Builds FlowInputs with auto-detection
|
|
3800
|
-
* 2. Validates inputs (optional, to be added in integration)
|
|
3801
|
-
* 3. Executes flow with the inputs
|
|
3802
|
-
* 4. Tracks multi-input state
|
|
3803
|
-
*
|
|
3804
|
-
* @param inputs - Map of nodeId to raw input data
|
|
3805
|
-
*
|
|
3806
|
-
* @example
|
|
3807
|
-
* ```typescript
|
|
3808
|
-
* await manager.executeFlow({
|
|
3809
|
-
* "file-input": myFile,
|
|
3810
|
-
* "url-input": "https://example.com/image.jpg"
|
|
3811
|
-
* });
|
|
3812
|
-
* ```
|
|
3813
|
-
*/
|
|
3814
|
-
executeFlow(inputs: Record<string, unknown>): Promise<void>;
|
|
3815
|
-
/**
|
|
3816
|
-
* Get the input execution states (for multi-input flows).
|
|
3817
|
-
* @returns Map of nodeId to input state
|
|
3601
|
+
* Retry the last failed or aborted upload
|
|
3818
3602
|
*/
|
|
3819
|
-
|
|
3603
|
+
retry(): void;
|
|
3820
3604
|
/**
|
|
3821
3605
|
* Clean up resources (call when disposing the manager)
|
|
3822
3606
|
*/
|
|
3823
3607
|
cleanup(): void;
|
|
3824
3608
|
}
|
|
3825
3609
|
//#endregion
|
|
3826
|
-
//#region src/
|
|
3610
|
+
//#region src/storage/in-memory-storage-service.d.ts
|
|
3827
3611
|
/**
|
|
3828
|
-
*
|
|
3612
|
+
* In-memory fallback storage service for Expo
|
|
3613
|
+
* Used when AsyncStorage is not available or for testing
|
|
3829
3614
|
*/
|
|
3830
|
-
|
|
3615
|
+
declare function createInMemoryStorageService(): StorageService;
|
|
3616
|
+
//#endregion
|
|
3617
|
+
//#region src/types/flow-inputs.d.ts
|
|
3831
3618
|
/**
|
|
3832
|
-
*
|
|
3619
|
+
* Type definitions for flexible flow input specifications.
|
|
3620
|
+
*
|
|
3621
|
+
* This module defines types for passing input data to flows with multiple input nodes.
|
|
3622
|
+
* The FlowInputs type maps node IDs to their respective input data, enabling support
|
|
3623
|
+
* for flows with single or multiple input points.
|
|
3624
|
+
*
|
|
3625
|
+
* @module types/flow-inputs
|
|
3626
|
+
*
|
|
3627
|
+
* @example
|
|
3628
|
+
* ```typescript
|
|
3629
|
+
* import type { FlowInputs } from "@uploadista/client-core";
|
|
3630
|
+
*
|
|
3631
|
+
* // Single input flow
|
|
3632
|
+
* const inputs: FlowInputs = {
|
|
3633
|
+
* "file-input": {
|
|
3634
|
+
* operation: "url",
|
|
3635
|
+
* url: "https://example.com/image.jpg"
|
|
3636
|
+
* }
|
|
3637
|
+
* };
|
|
3638
|
+
*
|
|
3639
|
+
* // Multi-input flow
|
|
3640
|
+
* const multiInputs: FlowInputs = {
|
|
3641
|
+
* "file-input": {
|
|
3642
|
+
* operation: "init",
|
|
3643
|
+
* storageId: "s3",
|
|
3644
|
+
* metadata: { originalName: "image.jpg" }
|
|
3645
|
+
* },
|
|
3646
|
+
* "metadata-input": {
|
|
3647
|
+
* title: "My Image",
|
|
3648
|
+
* tags: ["photo", "landscape"]
|
|
3649
|
+
* }
|
|
3650
|
+
* };
|
|
3651
|
+
* ```
|
|
3833
3652
|
*/
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3653
|
+
/**
|
|
3654
|
+
* Flow input specification mapping node IDs to their input data.
|
|
3655
|
+
*
|
|
3656
|
+
* This type represents a map of input node IDs to their respective input data.
|
|
3657
|
+
* Each key is a node ID, and each value is the data to pass to that node.
|
|
3658
|
+
* The data structure depends on the node's registered input type.
|
|
3659
|
+
*
|
|
3660
|
+
* @remarks
|
|
3661
|
+
* Input data is validated against each node's registered type schema before
|
|
3662
|
+
* flow execution begins. Invalid data will result in validation errors.
|
|
3663
|
+
*
|
|
3664
|
+
* @example
|
|
3665
|
+
* ```typescript
|
|
3666
|
+
* // For streaming input node (init operation)
|
|
3667
|
+
* const fileUploadInputs: FlowInputs = {
|
|
3668
|
+
* "input-node-1": {
|
|
3669
|
+
* operation: "init",
|
|
3670
|
+
* storageId: "my-storage",
|
|
3671
|
+
* metadata: {
|
|
3672
|
+
* originalName: "photo.jpg",
|
|
3673
|
+
* mimeType: "image/jpeg",
|
|
3674
|
+
* size: 1024000
|
|
3675
|
+
* }
|
|
3676
|
+
* }
|
|
3677
|
+
* };
|
|
3678
|
+
*
|
|
3679
|
+
* // For streaming input node (URL operation)
|
|
3680
|
+
* const urlInputs: FlowInputs = {
|
|
3681
|
+
* "input-node-1": {
|
|
3682
|
+
* operation: "url",
|
|
3683
|
+
* url: "https://example.com/photo.jpg",
|
|
3684
|
+
* storageId: "my-storage",
|
|
3685
|
+
* metadata: {
|
|
3686
|
+
* source: "external"
|
|
3687
|
+
* }
|
|
3688
|
+
* }
|
|
3689
|
+
* };
|
|
3690
|
+
* ```
|
|
3691
|
+
*/
|
|
3692
|
+
type FlowInputs = Record<string, unknown>;
|
|
3693
|
+
/**
|
|
3694
|
+
* Helper type for single-input flows.
|
|
3695
|
+
*
|
|
3696
|
+
* Many flows have exactly one input node. This helper type makes it easier
|
|
3697
|
+
* to work with single-input scenarios without needing to know the node ID upfront.
|
|
3698
|
+
*
|
|
3699
|
+
* @example
|
|
3700
|
+
* ```typescript
|
|
3701
|
+
* const singleInput: SingleFlowInput = {
|
|
3702
|
+
* operation: "url",
|
|
3703
|
+
* url: "https://example.com/image.jpg"
|
|
3704
|
+
* };
|
|
3705
|
+
*
|
|
3706
|
+
* // The client can auto-discover the input node ID and convert this to FlowInputs
|
|
3707
|
+
* ```
|
|
3708
|
+
*/
|
|
3709
|
+
type SingleFlowInput = unknown;
|
|
3710
|
+
/**
|
|
3711
|
+
* Result of input node discovery.
|
|
3712
|
+
*
|
|
3713
|
+
* Contains information about discovered input nodes in a flow, including
|
|
3714
|
+
* their IDs, types, and whether the flow has a single or multiple inputs.
|
|
3715
|
+
*
|
|
3716
|
+
* @property inputNodes - Array of input node information
|
|
3717
|
+
* @property single - True if flow has exactly one input node
|
|
3718
|
+
*/
|
|
3719
|
+
interface InputNodeDiscovery {
|
|
3720
|
+
inputNodes: Array<{
|
|
3721
|
+
id: string;
|
|
3722
|
+
type: string;
|
|
3723
|
+
name?: string;
|
|
3724
|
+
}>;
|
|
3725
|
+
single: boolean;
|
|
3726
|
+
}
|
|
3727
|
+
//#endregion
|
|
3728
|
+
//#region src/types/flow-result.d.ts
|
|
3729
|
+
type FlowResult<TOutput = UploadFile> = {
|
|
3730
|
+
type: "success";
|
|
3731
|
+
value: TOutput;
|
|
3732
|
+
} | {
|
|
3733
|
+
type: "error";
|
|
3734
|
+
error: Error;
|
|
3735
|
+
} | {
|
|
3736
|
+
type: "cancelled";
|
|
3737
|
+
};
|
|
3738
|
+
//#endregion
|
|
3739
|
+
//#region src/types/flow-upload-item.d.ts
|
|
3740
|
+
/**
|
|
3741
|
+
* Flow upload item for multi-flow-upload tracking
|
|
3742
|
+
*/
|
|
3743
|
+
interface FlowUploadItem<UploadInput$1> {
|
|
3744
|
+
id: string;
|
|
3745
|
+
file: UploadInput$1;
|
|
3746
|
+
status: "pending" | "uploading" | "success" | "error" | "aborted";
|
|
3838
3747
|
progress: number;
|
|
3839
|
-
/** Number of bytes uploaded */
|
|
3840
3748
|
bytesUploaded: number;
|
|
3841
|
-
|
|
3842
|
-
totalBytes: number | null;
|
|
3843
|
-
/** Error if upload failed */
|
|
3749
|
+
totalBytes: number;
|
|
3844
3750
|
error: Error | null;
|
|
3845
|
-
|
|
3846
|
-
|
|
3751
|
+
result: UploadFile$1 | null;
|
|
3752
|
+
jobId: string | null;
|
|
3847
3753
|
}
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
interface UploadManagerCallbacks {
|
|
3754
|
+
//#endregion
|
|
3755
|
+
//#region src/types/multi-flow-upload-options.d.ts
|
|
3756
|
+
interface MultiFlowUploadOptions<UploadInput$1> {
|
|
3852
3757
|
/**
|
|
3853
|
-
*
|
|
3758
|
+
* Flow configuration
|
|
3854
3759
|
*/
|
|
3855
|
-
|
|
3760
|
+
flowConfig: FlowUploadConfig;
|
|
3856
3761
|
/**
|
|
3857
|
-
*
|
|
3858
|
-
* @param uploadId - The unique identifier for this upload
|
|
3859
|
-
* @param bytesUploaded - Number of bytes uploaded
|
|
3860
|
-
* @param totalBytes - Total bytes to upload, null if unknown
|
|
3762
|
+
* Maximum number of concurrent uploads (default: 3)
|
|
3861
3763
|
*/
|
|
3862
|
-
|
|
3764
|
+
maxConcurrent?: number;
|
|
3863
3765
|
/**
|
|
3864
|
-
* Called when
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3766
|
+
* Called when an individual upload progresses
|
|
3767
|
+
*/
|
|
3768
|
+
onItemProgress?: (item: FlowUploadItem<UploadInput$1>) => void;
|
|
3769
|
+
/**
|
|
3770
|
+
* Called when an individual upload succeeds
|
|
3868
3771
|
*/
|
|
3869
|
-
|
|
3772
|
+
onItemSuccess?: (item: FlowUploadItem<UploadInput$1>) => void;
|
|
3870
3773
|
/**
|
|
3871
|
-
* Called when upload
|
|
3872
|
-
* @param result - The uploaded file result
|
|
3774
|
+
* Called when an individual upload fails
|
|
3873
3775
|
*/
|
|
3874
|
-
|
|
3776
|
+
onItemError?: (item: FlowUploadItem<UploadInput$1>, error: Error) => void;
|
|
3875
3777
|
/**
|
|
3876
|
-
* Called when
|
|
3877
|
-
* @param error - The error that occurred
|
|
3778
|
+
* Called when all uploads complete
|
|
3878
3779
|
*/
|
|
3879
|
-
|
|
3780
|
+
onComplete?: (items: FlowUploadItem<UploadInput$1>[]) => void;
|
|
3880
3781
|
/**
|
|
3881
|
-
*
|
|
3782
|
+
* Custom retry logic
|
|
3882
3783
|
*/
|
|
3883
|
-
|
|
3784
|
+
onShouldRetry?: (error: Error, retryAttempt: number) => boolean;
|
|
3884
3785
|
}
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
abort: () => void;
|
|
3786
|
+
//#endregion
|
|
3787
|
+
//#region src/types/multi-flow-upload-state.d.ts
|
|
3788
|
+
interface MultiFlowUploadState<UploadInput$1> {
|
|
3789
|
+
items: FlowUploadItem<UploadInput$1>[];
|
|
3790
|
+
totalProgress: number;
|
|
3791
|
+
activeUploads: number;
|
|
3792
|
+
completedUploads: number;
|
|
3793
|
+
failedUploads: number;
|
|
3894
3794
|
}
|
|
3795
|
+
//#endregion
|
|
3796
|
+
//#region src/types/upload-metrics.d.ts
|
|
3895
3797
|
/**
|
|
3896
|
-
*
|
|
3897
|
-
* Returns a promise that resolves to an abort controller.
|
|
3898
|
-
*/
|
|
3899
|
-
type UploadFunction<TInput = UploadInput, TOptions extends UploadOptions = UploadOptions> = (input: TInput, options: TOptions) => Promise<UploadAbortController>;
|
|
3900
|
-
/**
|
|
3901
|
-
* Platform-agnostic upload manager that handles upload state machine,
|
|
3902
|
-
* progress tracking, error handling, abort, reset, and retry logic.
|
|
3798
|
+
* Comprehensive upload metrics interface
|
|
3903
3799
|
*
|
|
3904
|
-
*
|
|
3905
|
-
*
|
|
3800
|
+
* Provides access to all performance metrics, insights, and network
|
|
3801
|
+
* statistics for upload monitoring and optimization.
|
|
3906
3802
|
*
|
|
3907
|
-
*
|
|
3908
|
-
*
|
|
3909
|
-
* const uploadFn = (input, options) => client.upload(input, options);
|
|
3910
|
-
* const manager = new UploadManager(uploadFn, {
|
|
3911
|
-
* onStateChange: (state) => setState(state),
|
|
3912
|
-
* onProgress: (progress) => console.log(`${progress}%`),
|
|
3913
|
-
* onSuccess: (result) => console.log('Upload complete:', result),
|
|
3914
|
-
* onError: (error) => console.error('Upload failed:', error),
|
|
3915
|
-
* });
|
|
3803
|
+
* This interface is implemented by all framework packages (React, Vue, React Native)
|
|
3804
|
+
* to ensure consistent metrics API across platforms.
|
|
3916
3805
|
*
|
|
3917
|
-
*
|
|
3806
|
+
* @example React usage
|
|
3807
|
+
* ```tsx
|
|
3808
|
+
* const upload = useUpload();
|
|
3809
|
+
* const insights = upload.metrics.getInsights();
|
|
3810
|
+
* const metrics = upload.metrics.exportMetrics();
|
|
3811
|
+
* ```
|
|
3812
|
+
*
|
|
3813
|
+
* @example Vue usage
|
|
3814
|
+
* ```vue
|
|
3815
|
+
* <script setup>
|
|
3816
|
+
* const upload = useUpload();
|
|
3817
|
+
* const insights = upload.metrics.getInsights();
|
|
3818
|
+
* </script>
|
|
3819
|
+
* ```
|
|
3820
|
+
*
|
|
3821
|
+
* @example React Native usage
|
|
3822
|
+
* ```tsx
|
|
3823
|
+
* const upload = useUpload();
|
|
3824
|
+
* const networkMetrics = upload.metrics.getNetworkMetrics();
|
|
3918
3825
|
* ```
|
|
3919
3826
|
*/
|
|
3920
|
-
|
|
3921
|
-
private readonly uploadFn;
|
|
3922
|
-
private readonly callbacks;
|
|
3923
|
-
private readonly options?;
|
|
3924
|
-
private state;
|
|
3925
|
-
private abortController;
|
|
3926
|
-
private lastInput;
|
|
3927
|
-
private uploadId;
|
|
3827
|
+
interface UploadMetrics {
|
|
3928
3828
|
/**
|
|
3929
|
-
*
|
|
3829
|
+
* Get performance insights from the upload client
|
|
3930
3830
|
*
|
|
3931
|
-
*
|
|
3932
|
-
*
|
|
3933
|
-
* @param options - Upload configuration options
|
|
3934
|
-
*/
|
|
3935
|
-
constructor(uploadFn: UploadFunction<TInput, TOptions>, callbacks: UploadManagerCallbacks, options?: TOptions | undefined);
|
|
3936
|
-
/**
|
|
3937
|
-
* Get the current upload state
|
|
3938
|
-
*/
|
|
3939
|
-
getState(): UploadState;
|
|
3940
|
-
/**
|
|
3941
|
-
* Check if an upload is currently active
|
|
3942
|
-
*/
|
|
3943
|
-
isUploading(): boolean;
|
|
3944
|
-
/**
|
|
3945
|
-
* Check if the upload can be retried
|
|
3946
|
-
*/
|
|
3947
|
-
canRetry(): boolean;
|
|
3948
|
-
/**
|
|
3949
|
-
* Update the internal state and notify callbacks
|
|
3950
|
-
*/
|
|
3951
|
-
private updateState;
|
|
3952
|
-
/**
|
|
3953
|
-
* Start uploading a file or input
|
|
3831
|
+
* Provides high-level analysis with recommendations for
|
|
3832
|
+
* optimizing upload performance.
|
|
3954
3833
|
*
|
|
3955
|
-
* @
|
|
3834
|
+
* @returns Performance insights including efficiency scores and recommendations
|
|
3835
|
+
*
|
|
3836
|
+
* @example
|
|
3837
|
+
* ```typescript
|
|
3838
|
+
* const insights = metrics.getInsights();
|
|
3839
|
+
* console.log(`Efficiency: ${insights.overallEfficiency}%`);
|
|
3840
|
+
* console.log(`Recommendations:`, insights.recommendations);
|
|
3841
|
+
* ```
|
|
3956
3842
|
*/
|
|
3957
|
-
|
|
3843
|
+
getInsights: () => PerformanceInsights;
|
|
3958
3844
|
/**
|
|
3959
|
-
*
|
|
3845
|
+
* Export detailed metrics from the upload client
|
|
3846
|
+
*
|
|
3847
|
+
* Returns comprehensive metrics including session data,
|
|
3848
|
+
* per-chunk statistics, and performance insights.
|
|
3849
|
+
*
|
|
3850
|
+
* Useful for analytics, debugging, and performance monitoring.
|
|
3851
|
+
*
|
|
3852
|
+
* @returns Object containing session metrics, chunk metrics, and insights
|
|
3853
|
+
*
|
|
3854
|
+
* @example
|
|
3855
|
+
* ```typescript
|
|
3856
|
+
* const metrics = metrics.exportMetrics();
|
|
3857
|
+
* console.log(`Uploaded ${metrics.session.totalBytesUploaded} bytes`);
|
|
3858
|
+
* console.log(`Average speed: ${metrics.session.averageSpeed} B/s`);
|
|
3859
|
+
* console.log(`Chunks: ${metrics.chunks.length}`);
|
|
3860
|
+
* ```
|
|
3960
3861
|
*/
|
|
3961
|
-
|
|
3862
|
+
exportMetrics: () => {
|
|
3863
|
+
/** Session-level aggregated metrics */
|
|
3864
|
+
session: Partial<UploadSessionMetrics>;
|
|
3865
|
+
/** Per-chunk detailed metrics */
|
|
3866
|
+
chunks: ChunkMetrics[];
|
|
3867
|
+
/** Performance insights and recommendations */
|
|
3868
|
+
insights: PerformanceInsights;
|
|
3869
|
+
};
|
|
3962
3870
|
/**
|
|
3963
|
-
*
|
|
3871
|
+
* Get current network metrics
|
|
3872
|
+
*
|
|
3873
|
+
* Provides real-time network statistics including speed,
|
|
3874
|
+
* errors, and network condition assessment.
|
|
3875
|
+
*
|
|
3876
|
+
* @returns Current network performance metrics
|
|
3877
|
+
*
|
|
3878
|
+
* @example
|
|
3879
|
+
* ```typescript
|
|
3880
|
+
* const network = metrics.getNetworkMetrics();
|
|
3881
|
+
* console.log(`Speed: ${network.currentSpeed} B/s`);
|
|
3882
|
+
* console.log(`Quality: ${network.condition.quality}`);
|
|
3883
|
+
* ```
|
|
3964
3884
|
*/
|
|
3965
|
-
|
|
3885
|
+
getNetworkMetrics: () => NetworkMetrics;
|
|
3966
3886
|
/**
|
|
3967
|
-
*
|
|
3887
|
+
* Get current network condition
|
|
3888
|
+
*
|
|
3889
|
+
* Provides assessment of current network quality with
|
|
3890
|
+
* recommendations for adaptive upload strategies.
|
|
3891
|
+
*
|
|
3892
|
+
* @returns Network condition assessment
|
|
3893
|
+
*
|
|
3894
|
+
* @example
|
|
3895
|
+
* ```typescript
|
|
3896
|
+
* const condition = metrics.getNetworkCondition();
|
|
3897
|
+
* if (condition.quality === 'poor') {
|
|
3898
|
+
* console.log('Consider reducing chunk size');
|
|
3899
|
+
* }
|
|
3900
|
+
* ```
|
|
3968
3901
|
*/
|
|
3969
|
-
|
|
3902
|
+
getNetworkCondition: () => NetworkCondition;
|
|
3970
3903
|
/**
|
|
3971
|
-
*
|
|
3904
|
+
* Reset all metrics
|
|
3905
|
+
*
|
|
3906
|
+
* Clears all accumulated metrics and resets counters.
|
|
3907
|
+
* Useful when starting a new upload session.
|
|
3908
|
+
*
|
|
3909
|
+
* @example
|
|
3910
|
+
* ```typescript
|
|
3911
|
+
* // Reset metrics before starting new upload
|
|
3912
|
+
* metrics.resetMetrics();
|
|
3913
|
+
* upload(newFile);
|
|
3914
|
+
* ```
|
|
3972
3915
|
*/
|
|
3973
|
-
|
|
3916
|
+
resetMetrics: () => void;
|
|
3974
3917
|
}
|
|
3975
3918
|
//#endregion
|
|
3919
|
+
//#region src/types/upload-result.d.ts
|
|
3920
|
+
/**
|
|
3921
|
+
* Discriminated union representing the result of an upload operation.
|
|
3922
|
+
*
|
|
3923
|
+
* Provides a type-safe way to handle the three possible outcomes of an upload:
|
|
3924
|
+
* success, error, or cancellation. This pattern enables exhaustive checking
|
|
3925
|
+
* of all cases at compile time.
|
|
3926
|
+
*
|
|
3927
|
+
* @template TOutput - The type of the successful result value. Defaults to UploadFile
|
|
3928
|
+
*
|
|
3929
|
+
* @example Handling upload results
|
|
3930
|
+
* ```typescript
|
|
3931
|
+
* function handleUploadResult(result: UploadResult) {
|
|
3932
|
+
* switch (result.type) {
|
|
3933
|
+
* case 'success':
|
|
3934
|
+
* console.log('Upload complete:', result.value.id);
|
|
3935
|
+
* break;
|
|
3936
|
+
* case 'error':
|
|
3937
|
+
* console.error('Upload failed:', result.error.message);
|
|
3938
|
+
* break;
|
|
3939
|
+
* case 'cancelled':
|
|
3940
|
+
* console.log('Upload was cancelled by user');
|
|
3941
|
+
* break;
|
|
3942
|
+
* }
|
|
3943
|
+
* }
|
|
3944
|
+
* ```
|
|
3945
|
+
*
|
|
3946
|
+
* @example With custom output type
|
|
3947
|
+
* ```typescript
|
|
3948
|
+
* interface ProcessedImage {
|
|
3949
|
+
* url: string;
|
|
3950
|
+
* width: number;
|
|
3951
|
+
* height: number;
|
|
3952
|
+
* }
|
|
3953
|
+
*
|
|
3954
|
+
* const result: UploadResult<ProcessedImage> = await uploadAndProcess(file);
|
|
3955
|
+
*
|
|
3956
|
+
* if (result.type === 'success') {
|
|
3957
|
+
* console.log(`Image processed: ${result.value.width}x${result.value.height}`);
|
|
3958
|
+
* }
|
|
3959
|
+
* ```
|
|
3960
|
+
*/
|
|
3961
|
+
type UploadResult<TOutput = UploadFile$1> = {
|
|
3962
|
+
/** Indicates the upload completed successfully */
|
|
3963
|
+
type: "success";
|
|
3964
|
+
/** The successful result value (e.g., upload metadata or processed output) */
|
|
3965
|
+
value: TOutput;
|
|
3966
|
+
} | {
|
|
3967
|
+
/** Indicates the upload failed with an error */
|
|
3968
|
+
type: "error";
|
|
3969
|
+
/** The error that caused the upload to fail */
|
|
3970
|
+
error: Error;
|
|
3971
|
+
} | {
|
|
3972
|
+
/** Indicates the upload was cancelled by the user or application */
|
|
3973
|
+
type: "cancelled";
|
|
3974
|
+
};
|
|
3975
|
+
//#endregion
|
|
3976
3976
|
export { AbortControllerFactory, AbortControllerLike, AbortSignalLike, Base64Service, ChecksumService, ChunkBuffer, ChunkBufferConfig, ChunkMetrics, ClientStorage, ConnectionHealth, ConnectionMetrics, ConnectionPoolConfig, DetailedConnectionMetrics, type EventFilterOptions, type EventSource, EventSubscriptionManager, FileReaderService, FileSource, FingerprintService, type FlowConfig, FlowInputs, FlowManager, type FlowManagerCallbacks, FlowResponse, FlowResult, type FlowUploadAbortController, FlowUploadConfig, type FlowUploadFunction, type FlowUploadInput, FlowUploadItem, FlowUploadOptions, type FlowUploadState, type FlowUploadStatus, type GenericEvent, HeadersLike, Http2Info, HttpClient, HttpRequestOptions, HttpResponse, IdGenerationService, type InputExecutionState, InputNodeDiscovery, type InternalFlowUploadOptions, LogFunction, Logger, MultiFlowUploadOptions, MultiFlowUploadState, type MultiInputCallbacks, type MultiInputFlowUploadFunction, NetworkCondition, NetworkMetrics, NetworkMonitor, NetworkMonitorConfig, PerformanceInsights, PlatformService, PreviousUpload, RequestBody, ServiceContainer, SingleFlowInput, SliceResult, StorageService, type SubscriptionEventHandler, Timeout, type UnsubscribeFunction, type UploadAbortController, type UploadFunction, type UploadInput, UploadManager, type UploadManagerCallbacks, UploadMetrics, UploadOptions, UploadResponse, UploadResult, UploadSample, UploadSessionMetrics, type UploadState, type UploadStatus, UploadistaApi, UploadistaClient, UploadistaClientOptions, UploadistaDeleteUploadResponse, UploadistaError, UploadistaErrorName, UploadistaEvent, UploadistaUploadOptions, UploadistaUploadResponse, UploadistaWebSocketEventHandler, UploadistaWebSocketManager, UploadistaWebSocketMessage, WebSocketEventMap, WebSocketFactory, WebSocketLike, createClientStorage, createInMemoryStorageService, createLogger, createUploadistaApi, createUploadistaClient, defaultConnectionPoolingConfig, previousUploadSchema, wait };
|
|
3977
3977
|
//# sourceMappingURL=index.d.mts.map
|