@umituz/react-native-ai-generation-content 1.29.0 → 1.30.0
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/package.json +1 -1
- package/src/domains/generation/presentation/useAIGeneration.hook.ts +0 -4
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +2 -2
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +1 -2
- package/src/domains/generation/wizard/infrastructure/strategies/wizard-strategy.types.ts +1 -4
- package/src/domains/generation/wizard/presentation/components/GenericWizardFlow.tsx +0 -6
- package/src/domains/generation/wizard/presentation/hooks/useWizardGeneration.ts +2 -9
- package/src/features/image-to-video/presentation/hooks/useImageToVideoFeature.ts +1 -6
- package/src/features/text-to-image/presentation/hooks/useGeneration.ts +1 -3
- package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +1 -6
- package/src/infrastructure/services/video-feature-executor.service.ts +1 -3
- package/src/infrastructure/services/video-feature-executor.types.ts +0 -1
- package/src/presentation/hooks/generation/orchestrator.ts +8 -14
- package/src/presentation/hooks/generation/types.ts +1 -3
- package/src/presentation/hooks/generation/useImageGeneration.ts +1 -2
- package/src/presentation/hooks/generation/useVideoGeneration.ts +1 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.0",
|
|
4
4
|
"description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -52,9 +52,6 @@ export interface UseAIGenerationReturn {
|
|
|
52
52
|
|
|
53
53
|
/** Whether generation is in progress */
|
|
54
54
|
isGenerating: boolean;
|
|
55
|
-
|
|
56
|
-
/** Current progress (0-100) */
|
|
57
|
-
progress: number;
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
// ============================================================================
|
|
@@ -107,6 +104,5 @@ export function useAIGeneration(
|
|
|
107
104
|
return {
|
|
108
105
|
generate: orchestrator.generate,
|
|
109
106
|
isGenerating: orchestrator.isGenerating,
|
|
110
|
-
progress: orchestrator.progress,
|
|
111
107
|
};
|
|
112
108
|
}
|
package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts
CHANGED
|
@@ -225,7 +225,7 @@ export function createImageStrategy(options: CreateImageStrategyOptions): Wizard
|
|
|
225
225
|
let lastInputRef: ImageGenerationInput | null = null;
|
|
226
226
|
|
|
227
227
|
return {
|
|
228
|
-
execute: async (input: unknown
|
|
228
|
+
execute: async (input: unknown) => {
|
|
229
229
|
const imageInput = input as ImageGenerationInput;
|
|
230
230
|
if (!scenario.model) {
|
|
231
231
|
throw new Error("Model is required for image generation");
|
|
@@ -233,7 +233,7 @@ export function createImageStrategy(options: CreateImageStrategyOptions): Wizard
|
|
|
233
233
|
|
|
234
234
|
lastInputRef = imageInput;
|
|
235
235
|
|
|
236
|
-
const result = await executeImageGeneration(imageInput, scenario.model
|
|
236
|
+
const result = await executeImageGeneration(imageInput, scenario.model);
|
|
237
237
|
|
|
238
238
|
if (!result.success || !result.imageUrl) {
|
|
239
239
|
throw new Error(result.error || "Image generation failed");
|
package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts
CHANGED
|
@@ -130,7 +130,7 @@ export function createVideoStrategy(options: CreateVideoStrategyOptions): Wizard
|
|
|
130
130
|
let lastInputRef: VideoGenerationInput | null = null;
|
|
131
131
|
|
|
132
132
|
return {
|
|
133
|
-
execute: async (input: unknown
|
|
133
|
+
execute: async (input: unknown) => {
|
|
134
134
|
const videoInput = input as VideoGenerationInput;
|
|
135
135
|
lastInputRef = videoInput;
|
|
136
136
|
|
|
@@ -146,7 +146,6 @@ export function createVideoStrategy(options: CreateVideoStrategyOptions): Wizard
|
|
|
146
146
|
resolution: videoInput.resolution,
|
|
147
147
|
},
|
|
148
148
|
},
|
|
149
|
-
{ onProgress },
|
|
150
149
|
);
|
|
151
150
|
|
|
152
151
|
if (!result.success || !result.videoUrl) {
|
|
@@ -4,10 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
export interface WizardStrategy {
|
|
7
|
-
execute: (
|
|
8
|
-
input: unknown,
|
|
9
|
-
onProgress?: (progress: number) => void,
|
|
10
|
-
) => Promise<{ imageUrl?: string; videoUrl?: string }>;
|
|
7
|
+
execute: (input: unknown) => Promise<{ imageUrl?: string; videoUrl?: string }>;
|
|
11
8
|
getCreditCost: () => number;
|
|
12
9
|
save?: (result: unknown, userId: string) => Promise<void>;
|
|
13
10
|
}
|
|
@@ -88,7 +88,6 @@ export const GenericWizardFlow: React.FC<GenericWizardFlowProps> = ({
|
|
|
88
88
|
nextStep,
|
|
89
89
|
previousStep,
|
|
90
90
|
setCustomData,
|
|
91
|
-
updateProgress,
|
|
92
91
|
setResult,
|
|
93
92
|
} = flow;
|
|
94
93
|
|
|
@@ -101,10 +100,6 @@ export const GenericWizardFlow: React.FC<GenericWizardFlowProps> = ({
|
|
|
101
100
|
|
|
102
101
|
const validatedScenario = useMemo(() => validateScenario(scenario), [scenario]);
|
|
103
102
|
|
|
104
|
-
const handleProgressChange = useCallback((progress: number) => {
|
|
105
|
-
updateProgress(progress);
|
|
106
|
-
}, [updateProgress]);
|
|
107
|
-
|
|
108
103
|
const handleGenerationComplete = useCallback((result: unknown) => {
|
|
109
104
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
110
105
|
console.log("[GenericWizardFlow] Generation completed", { skipResultStep });
|
|
@@ -129,7 +124,6 @@ export const GenericWizardFlow: React.FC<GenericWizardFlowProps> = ({
|
|
|
129
124
|
alertMessages,
|
|
130
125
|
onSuccess: handleGenerationComplete,
|
|
131
126
|
onError: onGenerationError,
|
|
132
|
-
onProgressChange: handleProgressChange,
|
|
133
127
|
onCreditsExhausted,
|
|
134
128
|
});
|
|
135
129
|
|
|
@@ -31,13 +31,11 @@ export interface UseWizardGenerationProps {
|
|
|
31
31
|
readonly alertMessages?: AlertMessages;
|
|
32
32
|
readonly onSuccess?: (result: unknown) => void;
|
|
33
33
|
readonly onError?: (error: string) => void;
|
|
34
|
-
readonly onProgressChange?: (progress: number) => void;
|
|
35
34
|
readonly onCreditsExhausted?: () => void;
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
export interface UseWizardGenerationReturn {
|
|
39
38
|
readonly isGenerating: boolean;
|
|
40
|
-
readonly progress: number;
|
|
41
39
|
}
|
|
42
40
|
|
|
43
41
|
export const useWizardGeneration = (
|
|
@@ -51,7 +49,6 @@ export const useWizardGeneration = (
|
|
|
51
49
|
alertMessages,
|
|
52
50
|
onSuccess,
|
|
53
51
|
onError,
|
|
54
|
-
onProgressChange,
|
|
55
52
|
onCreditsExhausted,
|
|
56
53
|
} = props;
|
|
57
54
|
|
|
@@ -74,7 +71,7 @@ export const useWizardGeneration = (
|
|
|
74
71
|
});
|
|
75
72
|
}, [scenario, wizardData]);
|
|
76
73
|
|
|
77
|
-
const { generate, isGenerating
|
|
74
|
+
const { generate, isGenerating } = useGenerationOrchestrator(
|
|
78
75
|
strategy,
|
|
79
76
|
{
|
|
80
77
|
userId,
|
|
@@ -101,10 +98,6 @@ export const useWizardGeneration = (
|
|
|
101
98
|
},
|
|
102
99
|
);
|
|
103
100
|
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
if (onProgressChange) onProgressChange(progress);
|
|
106
|
-
}, [progress, onProgressChange]);
|
|
107
|
-
|
|
108
101
|
useEffect(() => {
|
|
109
102
|
if (isGeneratingStep && !hasStarted.current && !isGenerating) {
|
|
110
103
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
@@ -139,5 +132,5 @@ export const useWizardGeneration = (
|
|
|
139
132
|
}
|
|
140
133
|
}, [isGeneratingStep, scenario, wizardData, isGenerating, generate, onError]);
|
|
141
134
|
|
|
142
|
-
return { isGenerating
|
|
135
|
+
return { isGenerating };
|
|
143
136
|
};
|
|
@@ -72,7 +72,7 @@ export function useImageToVideoFeature(props: UseImageToVideoFeatureProps): UseI
|
|
|
72
72
|
|
|
73
73
|
const strategy: GenerationStrategy<VideoGenerationInput, ImageToVideoResult> = useMemo(
|
|
74
74
|
() => ({
|
|
75
|
-
execute: async (input
|
|
75
|
+
execute: async (input) => {
|
|
76
76
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
77
77
|
console.log("[ImageToVideo] Executing generation, creationId:", input.creationId);
|
|
78
78
|
}
|
|
@@ -98,11 +98,6 @@ export function useImageToVideoFeature(props: UseImageToVideoFeatureProps): UseI
|
|
|
98
98
|
model: config.model,
|
|
99
99
|
buildInput: config.buildInput,
|
|
100
100
|
extractResult: config.extractResult,
|
|
101
|
-
onProgress: (progress) => {
|
|
102
|
-
setState((prev) => ({ ...prev, progress }));
|
|
103
|
-
onProgress?.(progress);
|
|
104
|
-
callbacks?.onProgress?.(progress);
|
|
105
|
-
},
|
|
106
101
|
},
|
|
107
102
|
);
|
|
108
103
|
|
|
@@ -27,7 +27,6 @@ export interface UseGenerationOptions {
|
|
|
27
27
|
|
|
28
28
|
export interface TextToImageGenerationState {
|
|
29
29
|
isGenerating: boolean;
|
|
30
|
-
progress: number;
|
|
31
30
|
error: string | null;
|
|
32
31
|
}
|
|
33
32
|
|
|
@@ -72,7 +71,7 @@ export function useGeneration(options: UseGenerationOptions): UseGenerationRetur
|
|
|
72
71
|
);
|
|
73
72
|
|
|
74
73
|
// Use orchestrator
|
|
75
|
-
const { generate, isGenerating,
|
|
74
|
+
const { generate, isGenerating, error } = useGenerationOrchestrator(strategy, {
|
|
76
75
|
userId,
|
|
77
76
|
alertMessages: DEFAULT_ALERT_MESSAGES,
|
|
78
77
|
onCreditsExhausted: () => callbacks.onCreditsRequired?.(totalCost),
|
|
@@ -131,7 +130,6 @@ export function useGeneration(options: UseGenerationOptions): UseGenerationRetur
|
|
|
131
130
|
return {
|
|
132
131
|
generationState: {
|
|
133
132
|
isGenerating,
|
|
134
|
-
progress,
|
|
135
133
|
error: error?.message || null,
|
|
136
134
|
},
|
|
137
135
|
totalCost,
|
|
@@ -76,7 +76,7 @@ export function useTextToVideoFeature(props: UseTextToVideoFeatureProps): UseTex
|
|
|
76
76
|
|
|
77
77
|
const strategy: GenerationStrategy<VideoGenerationInput, TextToVideoResult> = useMemo(
|
|
78
78
|
() => ({
|
|
79
|
-
execute: async (input
|
|
79
|
+
execute: async (input) => {
|
|
80
80
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
81
81
|
console.log("[TextToVideo] Executing generation:", input.prompt.slice(0, 100));
|
|
82
82
|
}
|
|
@@ -94,11 +94,6 @@ export function useTextToVideoFeature(props: UseTextToVideoFeatureProps): UseTex
|
|
|
94
94
|
model: config.model,
|
|
95
95
|
buildInput,
|
|
96
96
|
extractResult,
|
|
97
|
-
onProgress: (progress) => {
|
|
98
|
-
setState((prev) => ({ ...prev, progress }));
|
|
99
|
-
onProgress?.(progress);
|
|
100
|
-
callbacks.onProgress?.(progress);
|
|
101
|
-
},
|
|
102
97
|
},
|
|
103
98
|
);
|
|
104
99
|
|
|
@@ -36,7 +36,7 @@ export async function executeVideoFeature(
|
|
|
36
36
|
return { success: false, error: "AI provider not initialized" };
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
const { extractResult,
|
|
39
|
+
const { extractResult, onStatusChange } = options ?? {};
|
|
40
40
|
|
|
41
41
|
const model = provider.getVideoFeatureModel(featureType);
|
|
42
42
|
|
|
@@ -70,8 +70,6 @@ export async function executeVideoFeature(
|
|
|
70
70
|
const extractor = extractResult ?? extractVideoResult;
|
|
71
71
|
const videoUrl = extractor(result);
|
|
72
72
|
|
|
73
|
-
onProgress?.(100);
|
|
74
|
-
|
|
75
73
|
if (!videoUrl) {
|
|
76
74
|
if (__DEV__) {
|
|
77
75
|
console.log(`[Video:${featureType}] No video URL found in result`);
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
* Handles AI generation execution with:
|
|
4
4
|
* - Network check
|
|
5
5
|
* - Content moderation (optional)
|
|
6
|
-
* - Progress tracking
|
|
7
6
|
* - Credit deduction (after success)
|
|
8
7
|
* - Error handling
|
|
9
8
|
*
|
|
10
9
|
* NOTE: Credit CHECK is handled by useFeatureGate before generation starts.
|
|
11
10
|
* This orchestrator only DEDUCTS credits after successful generation.
|
|
11
|
+
*
|
|
12
|
+
* Progress is NOT tracked here - UI uses indeterminate progress bar with
|
|
13
|
+
* time-based phase detection (see useGenerationPhase hook).
|
|
12
14
|
*/
|
|
13
15
|
|
|
14
16
|
import { useState, useCallback, useRef, useEffect } from "react";
|
|
@@ -28,7 +30,6 @@ declare const __DEV__: boolean;
|
|
|
28
30
|
const INITIAL_STATE = {
|
|
29
31
|
status: "idle" as const,
|
|
30
32
|
isGenerating: false,
|
|
31
|
-
progress: 0,
|
|
32
33
|
result: null,
|
|
33
34
|
error: null,
|
|
34
35
|
};
|
|
@@ -81,17 +82,13 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
81
82
|
|
|
82
83
|
const executeGeneration = useCallback(
|
|
83
84
|
async (input: TInput) => {
|
|
84
|
-
setState((prev) => ({ ...prev, status: "generating"
|
|
85
|
+
setState((prev) => ({ ...prev, status: "generating" }));
|
|
85
86
|
|
|
86
87
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
87
88
|
console.log("[Orchestrator] Starting generation");
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
const result = await strategy.execute(input
|
|
91
|
-
if (isMountedRef.current) setState((prev) => ({ ...prev, progress }));
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
if (isMountedRef.current) setState((prev) => ({ ...prev, progress: 70 }));
|
|
91
|
+
const result = await strategy.execute(input);
|
|
95
92
|
|
|
96
93
|
if (strategy.save && userId) {
|
|
97
94
|
if (isMountedRef.current) setState((prev) => ({ ...prev, status: "saving" }));
|
|
@@ -106,8 +103,6 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
105
|
|
|
109
|
-
if (isMountedRef.current) setState((prev) => ({ ...prev, progress: 90 }));
|
|
110
|
-
|
|
111
106
|
const creditCost = strategy.getCreditCost();
|
|
112
107
|
const creditDeducted = await deductCredit(creditCost);
|
|
113
108
|
if (!creditDeducted) {
|
|
@@ -115,7 +110,7 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
115
110
|
}
|
|
116
111
|
|
|
117
112
|
if (isMountedRef.current) {
|
|
118
|
-
setState({ status: "success", isGenerating: false,
|
|
113
|
+
setState({ status: "success", isGenerating: false, result, error: null });
|
|
119
114
|
}
|
|
120
115
|
|
|
121
116
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
@@ -167,7 +162,7 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
167
162
|
} catch (err) {
|
|
168
163
|
const error = parseError(err);
|
|
169
164
|
if (isMountedRef.current) {
|
|
170
|
-
setState({ status: "error", isGenerating: false,
|
|
165
|
+
setState({ status: "error", isGenerating: false, result: null, error });
|
|
171
166
|
}
|
|
172
167
|
showError("Error", getAlertMessage(error, alertMessages));
|
|
173
168
|
onError?.(error);
|
|
@@ -190,7 +185,7 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
190
185
|
console.log("[Orchestrator] Error:", error);
|
|
191
186
|
}
|
|
192
187
|
if (isMountedRef.current) {
|
|
193
|
-
setState({ status: "error", isGenerating: false,
|
|
188
|
+
setState({ status: "error", isGenerating: false, result: null, error });
|
|
194
189
|
}
|
|
195
190
|
showError("Error", getAlertMessage(error, alertMessages));
|
|
196
191
|
onError?.(error);
|
|
@@ -221,7 +216,6 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
221
216
|
reset,
|
|
222
217
|
status: state.status,
|
|
223
218
|
isGenerating: state.isGenerating,
|
|
224
|
-
progress: state.progress,
|
|
225
219
|
result: state.result,
|
|
226
220
|
error: state.error,
|
|
227
221
|
};
|
|
@@ -13,7 +13,7 @@ export type OrchestratorStatus =
|
|
|
13
13
|
| "error";
|
|
14
14
|
|
|
15
15
|
export interface GenerationStrategy<TInput, TResult> {
|
|
16
|
-
execute: (input: TInput
|
|
16
|
+
execute: (input: TInput) => Promise<TResult>;
|
|
17
17
|
getCreditCost: () => number;
|
|
18
18
|
save?: (result: TResult, userId: string) => Promise<void>;
|
|
19
19
|
}
|
|
@@ -65,7 +65,6 @@ export interface GenerationConfig {
|
|
|
65
65
|
export interface GenerationState<TResult> {
|
|
66
66
|
readonly status: OrchestratorStatus;
|
|
67
67
|
readonly isGenerating: boolean;
|
|
68
|
-
readonly progress: number;
|
|
69
68
|
readonly result: TResult | null;
|
|
70
69
|
readonly error: GenerationError | null;
|
|
71
70
|
}
|
|
@@ -83,7 +82,6 @@ export interface UseGenerationOrchestratorReturn<TInput, TResult> {
|
|
|
83
82
|
readonly reset: () => void;
|
|
84
83
|
readonly status: OrchestratorStatus;
|
|
85
84
|
readonly isGenerating: boolean;
|
|
86
|
-
readonly progress: number;
|
|
87
85
|
readonly result: TResult | null;
|
|
88
86
|
readonly error: GenerationError | null;
|
|
89
87
|
}
|
|
@@ -107,7 +107,7 @@ export const useImageGeneration = <
|
|
|
107
107
|
|
|
108
108
|
const strategy: GenerationStrategy<TInput, TResult> = useMemo(
|
|
109
109
|
() => ({
|
|
110
|
-
execute: async (input
|
|
110
|
+
execute: async (input) => {
|
|
111
111
|
// Build executor input
|
|
112
112
|
const executorInput = buildExecutorInput
|
|
113
113
|
? buildExecutorInput(input)
|
|
@@ -118,7 +118,6 @@ export const useImageGeneration = <
|
|
|
118
118
|
const result = await executeImageFeature(
|
|
119
119
|
featureType,
|
|
120
120
|
executorInput,
|
|
121
|
-
{ onProgress },
|
|
122
121
|
);
|
|
123
122
|
|
|
124
123
|
if (!result.success || !result.imageUrl) {
|
|
@@ -62,7 +62,7 @@ export const useVideoGeneration = <TResult>(
|
|
|
62
62
|
|
|
63
63
|
const strategy: GenerationStrategy<DualImageVideoInput, TResult> = useMemo(
|
|
64
64
|
() => ({
|
|
65
|
-
execute: async (input
|
|
65
|
+
execute: async (input) => {
|
|
66
66
|
const result = await executeVideoFeature(
|
|
67
67
|
featureType,
|
|
68
68
|
{
|
|
@@ -70,7 +70,6 @@ export const useVideoGeneration = <TResult>(
|
|
|
70
70
|
targetImageBase64: input.targetImageBase64,
|
|
71
71
|
prompt: input.prompt,
|
|
72
72
|
},
|
|
73
|
-
{ onProgress },
|
|
74
73
|
);
|
|
75
74
|
|
|
76
75
|
if (!result.success || !result.videoUrl) {
|