@umituz/react-native-ai-generation-content 1.61.25 → 1.61.26
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/core/types/error.types.ts +3 -30
- package/src/core/types/provider.types.ts +35 -188
- package/src/core/types/result.types.ts +12 -96
- package/src/domain/entities/flow-config.types.ts +2 -2
- package/src/domains/generation/domain/generation.types.ts +4 -7
- package/src/domains/generation/index.ts +1 -1
- package/src/domains/generation/presentation/useAIGeneration.hook.ts +3 -15
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.ts +1 -1
- package/src/features/image-to-video/infrastructure/services/image-to-video-executor.ts +10 -37
- package/src/features/image-to-video/presentation/hooks/image-to-video-feature.types.ts +2 -12
- package/src/features/image-to-video/presentation/hooks/useImageToVideoFeature.ts +24 -13
- package/src/features/text-to-video/infrastructure/services/text-to-video-executor.ts +5 -37
- package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +26 -26
- package/src/infrastructure/orchestration/GenerationOrchestrator.ts +17 -14
- package/src/infrastructure/orchestration/orchestrator.types.ts +2 -5
- package/src/infrastructure/services/generation-orchestrator.service.ts +6 -6
- package/src/infrastructure/utils/README.md +7 -7
- package/src/infrastructure/utils/base64.util.ts +15 -0
- package/src/infrastructure/utils/error-classifier.util.ts +27 -10
- package/src/infrastructure/utils/error-message-extractor.util.ts +3 -3
- package/src/infrastructure/utils/error-patterns.constants.ts +21 -8
- package/src/infrastructure/utils/id-generator.util.ts +11 -0
- package/src/infrastructure/utils/index.ts +3 -0
- package/src/infrastructure/utils/provider-validator.util.ts +2 -2
- package/src/infrastructure/utils/video-result-extractor.util.ts +38 -0
- package/src/presentation/constants/alert-messages.ts +14 -0
- package/src/presentation/hooks/generation/errors.ts +5 -1
- package/src/presentation/hooks/generation/useImageGeneration.ts +6 -2
- package/src/presentation/hooks/generation/useVideoGeneration.ts +6 -2
- package/src/presentation/hooks/useGenerationFlow.ts +18 -23
- package/src/presentation/layouts/DualImageFeatureLayout.tsx +0 -1
- package/src/presentation/layouts/DualImageVideoFeatureLayout.tsx +1 -1
- package/src/presentation/layouts/SingleImageFeatureLayout.tsx +1 -1
- package/src/presentation/layouts/SingleImageWithPromptFeatureLayout.tsx +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Video Result Extractor Utility
|
|
3
|
+
* Shared extractor for video generation results
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface ExtractedVideoResult {
|
|
7
|
+
videoUrl?: string;
|
|
8
|
+
thumbnailUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Default extractor for video generation results.
|
|
13
|
+
* Handles common provider response formats.
|
|
14
|
+
*/
|
|
15
|
+
export function defaultExtractVideoResult(
|
|
16
|
+
result: unknown,
|
|
17
|
+
): ExtractedVideoResult | undefined {
|
|
18
|
+
if (typeof result !== "object" || result === null) return undefined;
|
|
19
|
+
|
|
20
|
+
const r = result as Record<string, unknown>;
|
|
21
|
+
|
|
22
|
+
if (typeof r.video === "string") {
|
|
23
|
+
return { videoUrl: r.video };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (r.video && typeof r.video === "object") {
|
|
27
|
+
const video = r.video as Record<string, unknown>;
|
|
28
|
+
if (typeof video.url === "string") {
|
|
29
|
+
return {
|
|
30
|
+
videoUrl: video.url,
|
|
31
|
+
thumbnailUrl:
|
|
32
|
+
typeof r.thumbnail === "string" ? r.thumbnail : undefined,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Alert Messages
|
|
3
|
+
* Shared constant for generation error messages
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { AlertMessages } from "../hooks/generation/types";
|
|
7
|
+
|
|
8
|
+
export const DEFAULT_ALERT_MESSAGES: AlertMessages = {
|
|
9
|
+
networkError: "No internet connection. Please check your network.",
|
|
10
|
+
policyViolation: "Content not allowed. Please try again.",
|
|
11
|
+
saveFailed: "Failed to save. Please try again.",
|
|
12
|
+
creditFailed: "Credit operation failed. Please try again.",
|
|
13
|
+
unknown: "An error occurred. Please try again.",
|
|
14
|
+
};
|
|
@@ -58,11 +58,15 @@ export const parseError = (err: unknown): GenerationError => {
|
|
|
58
58
|
return createGenerationError("unknown", "Generation failed");
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
+
const VALID_ERROR_TYPES: readonly string[] = ["network", "credits", "policy", "save", "unknown"];
|
|
62
|
+
|
|
61
63
|
const isGenerationError = (err: unknown): err is GenerationError => {
|
|
62
64
|
return (
|
|
63
65
|
typeof err === "object" &&
|
|
64
66
|
err !== null &&
|
|
65
67
|
"type" in err &&
|
|
66
|
-
"message" in err
|
|
68
|
+
"message" in err &&
|
|
69
|
+
typeof (err as GenerationError).type === "string" &&
|
|
70
|
+
VALID_ERROR_TYPES.includes((err as GenerationError).type)
|
|
67
71
|
);
|
|
68
72
|
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Uses centralized orchestrator for credit/error handling
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { useMemo, useCallback } from "react";
|
|
7
|
+
import { useMemo, useCallback, useRef } from "react";
|
|
8
8
|
import { useGenerationOrchestrator } from "./orchestrator";
|
|
9
9
|
import type { GenerationStrategy, AlertMessages } from "./types";
|
|
10
10
|
import { executeImageFeature } from "../../../infrastructure/services";
|
|
@@ -105,9 +105,13 @@ export const useImageGeneration = <
|
|
|
105
105
|
[],
|
|
106
106
|
);
|
|
107
107
|
|
|
108
|
+
const lastInputRef = useRef<TInput | null>(null);
|
|
109
|
+
|
|
108
110
|
const strategy: GenerationStrategy<TInput, TResult> = useMemo(
|
|
109
111
|
() => ({
|
|
110
112
|
execute: async (input) => {
|
|
113
|
+
lastInputRef.current = input;
|
|
114
|
+
|
|
111
115
|
// Build executor input
|
|
112
116
|
const executorInput = buildExecutorInput
|
|
113
117
|
? buildExecutorInput(input)
|
|
@@ -129,7 +133,7 @@ export const useImageGeneration = <
|
|
|
129
133
|
getCreditCost: () => creditCost,
|
|
130
134
|
save: buildCreation
|
|
131
135
|
? async (result, uid) => {
|
|
132
|
-
const creation = buildCreation(result, {} as TInput);
|
|
136
|
+
const creation = buildCreation(result, lastInputRef.current ?? {} as TInput);
|
|
133
137
|
if (creation) {
|
|
134
138
|
await repository.create(uid, creation);
|
|
135
139
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Uses centralized orchestrator for credit/error handling
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { useMemo, useCallback } from "react";
|
|
7
|
+
import { useMemo, useCallback, useRef } from "react";
|
|
8
8
|
import { useGenerationOrchestrator } from "./orchestrator";
|
|
9
9
|
import type { GenerationStrategy, AlertMessages } from "./types";
|
|
10
10
|
import { executeVideoFeature } from "../../../infrastructure/services";
|
|
@@ -60,9 +60,13 @@ export const useVideoGeneration = <TResult>(
|
|
|
60
60
|
[],
|
|
61
61
|
);
|
|
62
62
|
|
|
63
|
+
const lastInputRef = useRef<DualImageVideoInput | null>(null);
|
|
64
|
+
|
|
63
65
|
const strategy: GenerationStrategy<DualImageVideoInput, TResult> = useMemo(
|
|
64
66
|
() => ({
|
|
65
67
|
execute: async (input) => {
|
|
68
|
+
lastInputRef.current = input;
|
|
69
|
+
|
|
66
70
|
const result = await executeVideoFeature(
|
|
67
71
|
featureType,
|
|
68
72
|
{
|
|
@@ -81,7 +85,7 @@ export const useVideoGeneration = <TResult>(
|
|
|
81
85
|
getCreditCost: () => creditCost,
|
|
82
86
|
save: buildCreation
|
|
83
87
|
? async (result, uid) => {
|
|
84
|
-
const creation = buildCreation(result, {} as DualImageVideoInput);
|
|
88
|
+
const creation = buildCreation(result, lastInputRef.current ?? {} as DualImageVideoInput);
|
|
85
89
|
if (creation) {
|
|
86
90
|
await repository.create(uid, creation);
|
|
87
91
|
}
|
|
@@ -84,29 +84,26 @@ export const useGenerationFlow = ({
|
|
|
84
84
|
const goNext = useCallback(() => {
|
|
85
85
|
if (!canGoNext) return;
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (nextIndex >= config.photoSteps.length) {
|
|
91
|
-
const newState = { ...prev, isComplete: true };
|
|
92
|
-
onComplete?.(newState);
|
|
93
|
-
return newState;
|
|
94
|
-
}
|
|
87
|
+
const nextIndex = state.currentStepIndex + 1;
|
|
88
|
+
const isLastStep = nextIndex >= config.photoSteps.length;
|
|
95
89
|
|
|
90
|
+
if (isLastStep) {
|
|
91
|
+
const newState = { ...state, isComplete: true };
|
|
92
|
+
setState(newState);
|
|
93
|
+
onComplete?.(newState);
|
|
94
|
+
} else {
|
|
95
|
+
setState((prev) => ({ ...prev, currentStepIndex: nextIndex }));
|
|
96
96
|
onStepChange?.(nextIndex, config.photoSteps[nextIndex]);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}, [canGoNext, config.photoSteps, onComplete, onStepChange]);
|
|
97
|
+
}
|
|
98
|
+
}, [canGoNext, state, config.photoSteps, onComplete, onStepChange]);
|
|
100
99
|
|
|
101
100
|
const goBack = useCallback(() => {
|
|
102
101
|
if (!canGoBack) return;
|
|
103
102
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
109
|
-
}, [canGoBack, config.photoSteps, onStepChange]);
|
|
103
|
+
const prevIndex = state.currentStepIndex - 1;
|
|
104
|
+
setState((prev) => ({ ...prev, currentStepIndex: prevIndex, isComplete: false }));
|
|
105
|
+
onStepChange?.(prevIndex, config.photoSteps[prevIndex]);
|
|
106
|
+
}, [canGoBack, state.currentStepIndex, config.photoSteps, onStepChange]);
|
|
110
107
|
|
|
111
108
|
const updatePhoto = useCallback((imageUri: string, previewUrl?: string) => {
|
|
112
109
|
setState((prev) =>
|
|
@@ -159,12 +156,10 @@ export const useGenerationFlow = ({
|
|
|
159
156
|
}, [config]);
|
|
160
157
|
|
|
161
158
|
const complete = useCallback(() => {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
});
|
|
167
|
-
}, [onComplete]);
|
|
159
|
+
const newState = { ...state, isComplete: true };
|
|
160
|
+
setState(newState);
|
|
161
|
+
onComplete?.(newState);
|
|
162
|
+
}, [state, onComplete]);
|
|
168
163
|
|
|
169
164
|
return {
|
|
170
165
|
state,
|
|
@@ -122,7 +122,6 @@ export const DualImageFeatureLayout: React.FC<DualImageFeatureLayoutProps> = ({
|
|
|
122
122
|
onGenerate={handleProcess}
|
|
123
123
|
isGenerating={feature.isProcessing}
|
|
124
124
|
isDisabled={!feature.sourceImageUri || !feature.targetImageUri}
|
|
125
|
-
progress={feature.progress}
|
|
126
125
|
translations={{
|
|
127
126
|
generateButton: translations.processButtonText,
|
|
128
127
|
generatingButton: translations.processingText,
|
|
@@ -115,7 +115,7 @@ export const DualImageVideoFeatureLayout: React.FC<DualImageVideoFeatureLayoutPr
|
|
|
115
115
|
<AIGenerationForm
|
|
116
116
|
onGenerate={handleProcess}
|
|
117
117
|
isGenerating={feature.isProcessing}
|
|
118
|
-
|
|
118
|
+
isDisabled={!feature.sourceImageUri || !feature.targetImageUri}
|
|
119
119
|
translations={{
|
|
120
120
|
generateButton: translations.processButtonText,
|
|
121
121
|
generatingButton: translations.processingText,
|
|
@@ -138,7 +138,7 @@ export const SingleImageFeatureLayout: React.FC<SingleImageFeatureLayoutProps> =
|
|
|
138
138
|
<AIGenerationForm
|
|
139
139
|
onGenerate={handleProcess}
|
|
140
140
|
isGenerating={feature.isProcessing}
|
|
141
|
-
|
|
141
|
+
isDisabled={!feature.imageUri}
|
|
142
142
|
translations={{
|
|
143
143
|
generateButton: translations.processButtonText,
|
|
144
144
|
generatingButton: translations.processingText,
|
|
@@ -125,7 +125,7 @@ export const SingleImageWithPromptFeatureLayout: React.FC<SingleImageWithPromptF
|
|
|
125
125
|
<AIGenerationForm
|
|
126
126
|
onGenerate={handleProcess}
|
|
127
127
|
isGenerating={feature.isProcessing}
|
|
128
|
-
|
|
128
|
+
isDisabled={!feature.imageUri}
|
|
129
129
|
translations={{
|
|
130
130
|
generateButton: translations.processButtonText,
|
|
131
131
|
generatingButton: translations.processingText,
|