@umituz/react-native-ai-generation-content 1.65.0 → 1.65.2
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/domain/constants/processing-modes-catalog.constants.ts +97 -0
- package/src/domain/constants/processing-modes-filters.ts +34 -0
- package/src/domain/constants/processing-modes-getters.ts +20 -0
- package/src/domain/constants/processing-modes.constants.ts +8 -134
- package/src/domain/entities/feature-flow-config.types.ts +17 -0
- package/src/domain/entities/flow-actions.types.ts +26 -0
- package/src/domain/entities/flow-config-data.types.ts +41 -0
- package/src/domain/entities/flow-config.types.ts +17 -169
- package/src/domain/entities/flow-configuration.types.ts +44 -0
- package/src/domain/entities/flow-state.types.ts +30 -0
- package/src/domain/entities/flow-step.types.ts +56 -0
- package/src/domain/entities/scenario-step-config.types.ts +32 -0
- package/src/domain/entities/step-config.types.ts +14 -129
- package/src/domain/entities/step-definition.types.ts +50 -0
- package/src/domain/entities/step-input-config.types.ts +36 -0
- package/src/domain/entities/step-upload-config.types.ts +17 -0
- package/src/domain/interfaces/ai-provider-capabilities.types.ts +27 -0
- package/src/domain/interfaces/ai-provider-config.types.ts +30 -0
- package/src/domain/interfaces/ai-provider-feature-types.ts +22 -0
- package/src/domain/interfaces/ai-provider-input.types.ts +28 -0
- package/src/domain/interfaces/ai-provider-progress.types.ts +37 -0
- package/src/domain/interfaces/ai-provider-status.types.ts +41 -0
- package/src/domain/interfaces/ai-provider.interface.ts +32 -142
- package/src/domain/types/result-constructors.ts +20 -0
- package/src/domain/types/result-guards.ts +20 -0
- package/src/domain/types/result-transformers.ts +36 -0
- package/src/domain/types/result-type-definitions.ts +27 -0
- package/src/domain/types/result-unwrappers.ts +28 -0
- package/src/domain/types/result.types.ts +11 -100
- package/src/domains/background/infrastructure/utils/polling-interval.util.ts +3 -8
- package/src/domains/background/infrastructure/utils/result-validation-logic.ts +88 -0
- package/src/domains/background/infrastructure/utils/result-validator-constants.ts +18 -0
- package/src/domains/background/infrastructure/utils/result-validator.types.ts +16 -0
- package/src/domains/background/infrastructure/utils/result-validator.util.ts +8 -109
- package/src/domains/background/infrastructure/utils/status-checker.types.ts +11 -0
- package/src/domains/background/infrastructure/utils/status-checker.util.ts +9 -119
- package/src/domains/background/infrastructure/utils/status-error-detector.ts +61 -0
- package/src/domains/background/infrastructure/utils/status-extraction-helpers.ts +25 -0
- package/src/domains/background/infrastructure/utils/status-predicates.ts +37 -0
- package/src/domains/creations/domain-exports.ts +79 -0
- package/src/domains/creations/index.ts +9 -169
- package/src/domains/creations/infrastructure/repositories/creation-create.operations.ts +40 -0
- package/src/domains/creations/infrastructure/repositories/creation-delete.operations.ts +63 -0
- package/src/domains/creations/infrastructure/repositories/creation-update.operations.ts +77 -0
- package/src/domains/creations/infrastructure/repositories/creations-operations.ts +9 -210
- package/src/domains/creations/infrastructure-exports.ts +9 -0
- package/src/domains/creations/presentation-exports.ts +59 -0
- package/src/domains/generation/infrastructure/executors/text-to-image-executor.helpers.ts +81 -0
- package/src/domains/generation/infrastructure/executors/text-to-image-executor.ts +4 -100
- package/src/domains/generation/infrastructure/executors/text-to-image-executor.types.ts +19 -0
- package/src/domains/generation/infrastructure/flow/use-flow-store.types.ts +19 -0
- package/src/domains/generation/infrastructure/flow/useFlowStore.ts +33 -65
- package/src/domains/generation/wizard/domain/entities/wizard-config-builder.ts +75 -0
- package/src/domains/generation/wizard/domain/entities/wizard-feature-config.types.ts +29 -0
- package/src/domains/generation/wizard/domain/entities/wizard-feature.types.ts +9 -114
- package/src/domains/generation/wizard/domain/entities/wizard-presets.constants.ts +23 -0
- package/src/domains/generation/wizard/infrastructure/strategies/shared/unified-prompt-builder.ts +1 -1
- package/src/domains/generation/wizard/infrastructure/utils/creation-persistence-factory.ts +33 -0
- package/src/domains/generation/wizard/infrastructure/utils/creation-persistence.types.ts +22 -0
- package/src/domains/generation/wizard/infrastructure/utils/creation-persistence.util.ts +11 -135
- package/src/domains/generation/wizard/infrastructure/utils/creation-save-operations.ts +48 -0
- package/src/domains/generation/wizard/infrastructure/utils/creation-update-operations.ts +72 -0
- package/src/domains/generation/wizard/presentation/hooks/use-video-queue-generation.types.ts +21 -0
- package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +14 -35
- package/src/domains/image-to-video/domain/types/image-to-video-callbacks.types.ts +33 -0
- package/src/domains/image-to-video/domain/types/image-to-video-config.types.ts +29 -0
- package/src/domains/image-to-video/domain/types/image-to-video-request.types.ts +31 -0
- package/src/domains/image-to-video/domain/types/image-to-video-result.types.ts +17 -0
- package/src/domains/image-to-video/domain/types/image-to-video-state.types.ts +24 -0
- package/src/domains/image-to-video/domain/types/image-to-video.types.ts +24 -114
- package/src/domains/image-to-video/infrastructure/services/image-to-video-executor.ts +26 -99
- package/src/domains/image-to-video/infrastructure/services/image-to-video-executor.types.ts +15 -0
- package/src/domains/prompts/domain/base/constants.ts +47 -0
- package/src/domains/prompts/domain/base/creators.ts +76 -0
- package/src/domains/prompts/domain/base/types.ts +10 -0
- package/src/domains/prompts/domain/entities/MultiPersonPromptStructure.ts +1 -1
- package/src/domains/prompts/index.ts +4 -2
- package/src/domains/prompts/infrastructure/services/ImagePromptBuilder.ts +2 -72
- package/src/domains/prompts/infrastructure/services/image-prompt-builder.types.ts +17 -0
- package/src/domains/result-preview/presentation/types/result-components.types.ts +47 -0
- package/src/domains/result-preview/presentation/types/result-creation.types.ts +14 -0
- package/src/domains/result-preview/presentation/types/result-data.types.ts +35 -0
- package/src/domains/result-preview/presentation/types/result-hooks.types.ts +35 -0
- package/src/domains/result-preview/presentation/types/result-preview.types.ts +19 -182
- package/src/domains/result-preview/presentation/types/result-screen.types.ts +69 -0
- package/src/domains/text-to-image/domain-exports.ts +50 -0
- package/src/domains/text-to-image/index.ts +11 -102
- package/src/domains/text-to-image/infrastructure-exports.ts +6 -0
- package/src/domains/text-to-image/presentation/hooks/useFormState.ts +39 -24
- package/src/domains/text-to-image/presentation/hooks/useGeneration.ts +5 -3
- package/src/domains/text-to-image/presentation-exports.ts +41 -0
- package/src/domains/text-to-video/domain/types/action-component.types.ts +15 -0
- package/src/domains/text-to-video/domain/types/component.types.ts +16 -103
- package/src/domains/text-to-video/domain/types/content-component.types.ts +30 -0
- package/src/domains/text-to-video/domain/types/panel-component.types.ts +24 -0
- package/src/domains/text-to-video/domain/types/selector-component.types.ts +31 -0
- package/src/domains/text-to-video/domain/types/tab-component.types.ts +26 -0
- package/src/index.ts +0 -10
- package/src/infrastructure/executors/base-executor.ts +40 -112
- package/src/infrastructure/executors/base-executor.types.ts +10 -0
- package/src/infrastructure/http/http-client-methods.ts +73 -0
- package/src/infrastructure/http/http-client.util.ts +8 -163
- package/src/infrastructure/http/http-fetch-handler.ts +53 -0
- package/src/infrastructure/http/http-methods.constants.ts +23 -0
- package/src/infrastructure/http/http-request-executor.ts +49 -0
- package/src/infrastructure/http/http-response-parser.ts +53 -0
- package/src/infrastructure/orchestration/GenerationOrchestrator.ts +8 -43
- package/src/infrastructure/utils/classifier-helpers.ts +36 -0
- package/src/infrastructure/utils/content-validators.ts +92 -0
- package/src/infrastructure/utils/domain-guards.ts +22 -0
- package/src/infrastructure/utils/error-classification.ts +122 -0
- package/src/infrastructure/utils/error-classifier.util.ts +8 -181
- package/src/infrastructure/utils/error-classifiers.ts +49 -0
- package/src/infrastructure/utils/error-extractors.ts +42 -0
- package/src/infrastructure/utils/error-factory.ts +25 -0
- package/src/infrastructure/utils/error-handlers.ts +51 -0
- package/src/infrastructure/utils/error-handling.util.ts +7 -186
- package/src/infrastructure/utils/error-message-extractor.util.ts +10 -172
- package/src/infrastructure/utils/error-retry.ts +44 -0
- package/src/infrastructure/utils/error-types.ts +23 -0
- package/src/infrastructure/utils/extraction-types.ts +37 -0
- package/src/infrastructure/utils/fal-error-checker.ts +44 -0
- package/src/infrastructure/utils/general-validators.ts +64 -0
- package/src/infrastructure/utils/id-validators.ts +39 -0
- package/src/infrastructure/utils/message-extractor.ts +89 -0
- package/src/infrastructure/utils/primitive-guards.ts +66 -0
- package/src/infrastructure/utils/result-polling.ts +39 -0
- package/src/infrastructure/utils/structure-guards.ts +75 -0
- package/src/infrastructure/utils/type-guards.util.ts +22 -149
- package/src/infrastructure/utils/validation-types.ts +8 -0
- package/src/infrastructure/utils/validation.util.ts +14 -184
- package/src/presentation/hooks/ai-feature-callbacks-auth.hooks.ts +43 -0
- package/src/presentation/hooks/ai-feature-callbacks-cost.hooks.ts +56 -0
- package/src/presentation/hooks/ai-feature-callbacks-execution.hooks.ts +66 -0
- package/src/presentation/hooks/ai-feature-callbacks.types.ts +69 -0
- package/src/presentation/hooks/generation/use-image-generation.types.ts +39 -0
- package/src/presentation/hooks/generation/useImageGeneration.ts +33 -99
- package/src/presentation/hooks/generation-flow-navigation.ts +58 -0
- package/src/presentation/hooks/generation-flow-updates.ts +67 -0
- package/src/presentation/hooks/generation-flow.types.ts +32 -0
- package/src/presentation/hooks/useAIFeatureCallbacks.ts +48 -138
- package/src/presentation/hooks/useGenerationFlow.ts +40 -136
- package/src/presentation/types/flow-config.types.ts +9 -140
- package/src/presentation/types/flow-generation-config.types.ts +25 -0
- package/src/presentation/types/flow-state.types.ts +16 -0
- package/src/presentation/types/flow-step-configs.types.ts +48 -0
- package/src/presentation/types/flow-step-data.types.ts +24 -0
- package/src/presentation/types/result-actions.types.ts +50 -0
- package/src/presentation/types/result-config.types.ts +22 -171
- package/src/presentation/types/result-header.types.ts +44 -0
- package/src/presentation/types/result-image.types.ts +29 -0
- package/src/presentation/types/result-layout.types.ts +26 -0
- package/src/presentation/types/result-story.types.ts +42 -0
- package/src/domains/prompts/domain/entities/BasePromptStructure.ts +0 -168
- package/src/exports/domains.ts +0 -149
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Feature Callbacks - Cost Management Hooks
|
|
3
|
+
* Credit and cost-related callback hooks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useCallback } from "react";
|
|
7
|
+
|
|
8
|
+
export interface UseCostCallbacksParams {
|
|
9
|
+
creditBalance: number;
|
|
10
|
+
creditCostPerUnit: number;
|
|
11
|
+
openPaywall: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CostCallbacks {
|
|
15
|
+
canAfford: (cost: number) => boolean;
|
|
16
|
+
calculateCost: (multiplier?: number, _model?: string | null) => number;
|
|
17
|
+
onCreditsRequired: (cost?: number) => void;
|
|
18
|
+
onCreditCheck: (cost: number) => boolean;
|
|
19
|
+
onShowPaywall: (cost: number) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Hook for cost and credit management callbacks
|
|
24
|
+
*/
|
|
25
|
+
export function useCostCallbacks(params: UseCostCallbacksParams): CostCallbacks {
|
|
26
|
+
const { creditBalance, creditCostPerUnit, openPaywall } = params;
|
|
27
|
+
|
|
28
|
+
const canAfford = useCallback(
|
|
29
|
+
(cost: number): boolean => creditBalance >= cost,
|
|
30
|
+
[creditBalance],
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const calculateCost = useCallback(
|
|
34
|
+
(multiplier = 1, _model?: string | null): number => creditCostPerUnit * multiplier,
|
|
35
|
+
[creditCostPerUnit],
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const onCreditsRequired = useCallback(
|
|
39
|
+
(_cost?: number) => {
|
|
40
|
+
openPaywall();
|
|
41
|
+
},
|
|
42
|
+
[openPaywall],
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Aliases for different callback interfaces
|
|
46
|
+
const onCreditCheck = canAfford;
|
|
47
|
+
const onShowPaywall = onCreditsRequired;
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
canAfford,
|
|
51
|
+
calculateCost,
|
|
52
|
+
onCreditsRequired,
|
|
53
|
+
onCreditCheck,
|
|
54
|
+
onShowPaywall,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Feature Callbacks - Execution Hooks
|
|
3
|
+
* Generation execution callback hooks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useCallback } from "react";
|
|
7
|
+
import type { AIFeatureGenerationResult } from "./ai-feature-callbacks.types";
|
|
8
|
+
|
|
9
|
+
export interface UseExecutionCallbackParams<TRequest, TResult> {
|
|
10
|
+
executor: (request: TRequest) => Promise<{
|
|
11
|
+
success: boolean;
|
|
12
|
+
data?: TResult;
|
|
13
|
+
error?: string;
|
|
14
|
+
imageUrl?: string;
|
|
15
|
+
imageUrls?: string[];
|
|
16
|
+
}>;
|
|
17
|
+
deductCredits?: (amount: number) => Promise<void>;
|
|
18
|
+
creditCostPerUnit: number;
|
|
19
|
+
onSuccess?: (result: TResult) => void;
|
|
20
|
+
onError?: (error: string) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ExecutionCallbacks<TRequest> {
|
|
24
|
+
executeGeneration: (request: TRequest) => Promise<AIFeatureGenerationResult>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Hook for generation execution callback
|
|
29
|
+
*/
|
|
30
|
+
export function useExecutionCallback<TRequest = unknown, TResult = unknown>(
|
|
31
|
+
params: UseExecutionCallbackParams<TRequest, TResult>,
|
|
32
|
+
): ExecutionCallbacks<TRequest> {
|
|
33
|
+
const { executor, deductCredits, creditCostPerUnit, onSuccess, onError } = params;
|
|
34
|
+
|
|
35
|
+
const executeGeneration = useCallback(
|
|
36
|
+
async (request: TRequest): Promise<AIFeatureGenerationResult> => {
|
|
37
|
+
try {
|
|
38
|
+
const result = await executor(request);
|
|
39
|
+
|
|
40
|
+
if (result.success && deductCredits) {
|
|
41
|
+
await deductCredits(creditCostPerUnit);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (result.success && result.data) {
|
|
45
|
+
onSuccess?.(result.data);
|
|
46
|
+
} else if (!result.success && result.error) {
|
|
47
|
+
onError?.(result.error);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (result.success) {
|
|
51
|
+
return { success: true, imageUrls: result.imageUrls ?? [] };
|
|
52
|
+
}
|
|
53
|
+
return { success: false, error: result.error ?? "Unknown error" };
|
|
54
|
+
} catch (error) {
|
|
55
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
56
|
+
onError?.(message);
|
|
57
|
+
return { success: false, error: message };
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
[executor, deductCredits, creditCostPerUnit, onSuccess, onError],
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
executeGeneration,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Feature Callbacks Type Definitions
|
|
3
|
+
* Type definitions for universal AI feature callbacks adapter
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Configuration for AI feature callbacks hook
|
|
8
|
+
* Generic over TRequest and TResult for type safety
|
|
9
|
+
*/
|
|
10
|
+
export interface AIFeatureCallbacksConfig<TRequest = unknown, TResult = unknown> {
|
|
11
|
+
// App provides reactive state
|
|
12
|
+
userId: string | null;
|
|
13
|
+
isAuthenticated: boolean;
|
|
14
|
+
creditBalance: number;
|
|
15
|
+
|
|
16
|
+
// Cost config
|
|
17
|
+
creditCostPerUnit: number;
|
|
18
|
+
|
|
19
|
+
// Executor - the actual generation function
|
|
20
|
+
executor: (request: TRequest) => Promise<{
|
|
21
|
+
success: boolean;
|
|
22
|
+
data?: TResult;
|
|
23
|
+
error?: string;
|
|
24
|
+
imageUrl?: string;
|
|
25
|
+
imageUrls?: string[];
|
|
26
|
+
}>;
|
|
27
|
+
|
|
28
|
+
// Actions from app - showAuthModal accepts callback for post-auth resume
|
|
29
|
+
showAuthModal: (callback?: () => void) => void;
|
|
30
|
+
openPaywall: () => void;
|
|
31
|
+
deductCredits?: (amount: number) => Promise<void>;
|
|
32
|
+
|
|
33
|
+
// Optional callbacks
|
|
34
|
+
onSuccess?: (result: TResult) => void;
|
|
35
|
+
onError?: (error: string) => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Discriminated union result type for generation
|
|
40
|
+
*/
|
|
41
|
+
export type AIFeatureGenerationResult =
|
|
42
|
+
| { success: true; imageUrls: string[] }
|
|
43
|
+
| { success: false; error: string };
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Universal callbacks interface that maps to all feature-specific ones
|
|
47
|
+
* Compatible with TextToImageCallbacks, ImageToVideoCallbacks, TextToVideoCallbacks
|
|
48
|
+
*/
|
|
49
|
+
export interface AIFeatureCallbacks<TRequest = unknown, TResult = unknown> {
|
|
50
|
+
// User state - needed by orchestrator
|
|
51
|
+
userId: string | null;
|
|
52
|
+
|
|
53
|
+
// TextToImageCallbacks compatible
|
|
54
|
+
executeGeneration: (request: TRequest) => Promise<AIFeatureGenerationResult>;
|
|
55
|
+
calculateCost: (multiplier?: number, _model?: string | null) => number;
|
|
56
|
+
canAfford: (cost: number) => boolean;
|
|
57
|
+
isAuthenticated: () => boolean;
|
|
58
|
+
onAuthRequired: () => void;
|
|
59
|
+
onCreditsRequired: (cost?: number) => void;
|
|
60
|
+
onSuccess?: (result: TResult) => void;
|
|
61
|
+
onError?: (error: string) => void;
|
|
62
|
+
|
|
63
|
+
// ImageToVideoCallbacks compatible
|
|
64
|
+
onCreditCheck: (cost: number) => boolean;
|
|
65
|
+
onShowPaywall: (cost: number) => void;
|
|
66
|
+
|
|
67
|
+
// TextToVideoCallbacks compatible
|
|
68
|
+
onAuthCheck: () => boolean;
|
|
69
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image Generation Types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ImageFeatureType } from "../../../domain/interfaces";
|
|
6
|
+
import type { Creation } from "../../../domains/creations/domain/entities/Creation";
|
|
7
|
+
import type { AlertMessages } from "./types";
|
|
8
|
+
|
|
9
|
+
export interface SingleImageInput {
|
|
10
|
+
imageBase64: string;
|
|
11
|
+
prompt?: string;
|
|
12
|
+
options?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface DualImageInput {
|
|
16
|
+
sourceImageBase64: string;
|
|
17
|
+
targetImageBase64: string;
|
|
18
|
+
options?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type ImageGenerationInput = SingleImageInput | DualImageInput;
|
|
22
|
+
|
|
23
|
+
export interface ImageGenerationConfig<TInput extends ImageGenerationInput, TResult> {
|
|
24
|
+
featureType: ImageFeatureType;
|
|
25
|
+
userId: string | undefined;
|
|
26
|
+
processResult: (imageUrl: string, input: TInput) => TResult;
|
|
27
|
+
buildExecutorInput?: (input: TInput) => {
|
|
28
|
+
imageBase64?: string;
|
|
29
|
+
targetImageBase64?: string;
|
|
30
|
+
prompt?: string;
|
|
31
|
+
options?: Record<string, unknown>;
|
|
32
|
+
};
|
|
33
|
+
buildCreation?: (result: TResult, input: TInput) => Creation | null;
|
|
34
|
+
creditCost: number;
|
|
35
|
+
alertMessages: AlertMessages;
|
|
36
|
+
onCreditsExhausted?: () => void;
|
|
37
|
+
onSuccess?: (result: TResult) => void;
|
|
38
|
+
onError?: (error: string) => void;
|
|
39
|
+
}
|
|
@@ -1,92 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Generic
|
|
4
|
-
* Uses centralized orchestrator for credit/error handling
|
|
2
|
+
* Image Generation Hook
|
|
3
|
+
* Generic hook for image feature execution with orchestration
|
|
5
4
|
*/
|
|
6
5
|
|
|
7
6
|
import { useMemo, useCallback, useRef } from "react";
|
|
8
7
|
import { useGenerationOrchestrator } from "./orchestrator";
|
|
9
|
-
import type { GenerationStrategy
|
|
8
|
+
import type { GenerationStrategy } from "./types";
|
|
10
9
|
import { executeImageFeature } from "../../../infrastructure/services";
|
|
11
|
-
import type { ImageFeatureType } from "../../../domain/interfaces";
|
|
12
10
|
import { createCreationsRepository } from "../../../domains/creations/infrastructure/adapters";
|
|
13
|
-
import type {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
export interface ImageGenerationConfig<TInput extends ImageGenerationInput, TResult> {
|
|
36
|
-
/** Feature type (face-swap, upscale, remove-background, etc.) */
|
|
37
|
-
featureType: ImageFeatureType;
|
|
38
|
-
/** User ID for credit operations */
|
|
39
|
-
userId: string | undefined;
|
|
40
|
-
/** Transform image URL to result type */
|
|
41
|
-
processResult: (imageUrl: string, input: TInput) => TResult;
|
|
42
|
-
/** Build input for executor from generic input */
|
|
43
|
-
buildExecutorInput?: (input: TInput) => {
|
|
44
|
-
imageBase64?: string;
|
|
45
|
-
targetImageBase64?: string;
|
|
46
|
-
prompt?: string;
|
|
47
|
-
options?: Record<string, unknown>;
|
|
11
|
+
import type {
|
|
12
|
+
ImageGenerationConfig,
|
|
13
|
+
ImageGenerationInput,
|
|
14
|
+
SingleImageInput,
|
|
15
|
+
DualImageInput,
|
|
16
|
+
} from "./use-image-generation.types";
|
|
17
|
+
|
|
18
|
+
const isDualImageInput = (input: ImageGenerationInput): input is DualImageInput =>
|
|
19
|
+
"sourceImageBase64" in input && "targetImageBase64" in input;
|
|
20
|
+
|
|
21
|
+
const buildDefaultInput = (input: ImageGenerationInput) => {
|
|
22
|
+
if (isDualImageInput(input)) {
|
|
23
|
+
return {
|
|
24
|
+
imageBase64: input.sourceImageBase64,
|
|
25
|
+
targetImageBase64: input.targetImageBase64,
|
|
26
|
+
options: input.options,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
imageBase64: (input as SingleImageInput).imageBase64,
|
|
31
|
+
prompt: (input as SingleImageInput).prompt,
|
|
32
|
+
options: input.options,
|
|
48
33
|
};
|
|
49
|
-
/** Optional: Build creation for saving */
|
|
50
|
-
buildCreation?: (result: TResult, input: TInput) => Creation | null;
|
|
51
|
-
/** Credit cost for this generation - REQUIRED, determined by the app */
|
|
52
|
-
creditCost: number;
|
|
53
|
-
/** Alert messages for errors */
|
|
54
|
-
alertMessages: AlertMessages;
|
|
55
|
-
/** Callbacks */
|
|
56
|
-
onCreditsExhausted?: () => void;
|
|
57
|
-
onSuccess?: (result: TResult) => void;
|
|
58
|
-
onError?: (error: string) => void;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Default input builder for single image
|
|
63
|
-
*/
|
|
64
|
-
const defaultSingleImageBuilder = (input: SingleImageInput) => ({
|
|
65
|
-
imageBase64: input.imageBase64,
|
|
66
|
-
prompt: input.prompt,
|
|
67
|
-
options: input.options,
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Default input builder for dual image
|
|
72
|
-
*/
|
|
73
|
-
const defaultDualImageBuilder = (input: DualImageInput) => ({
|
|
74
|
-
imageBase64: input.sourceImageBase64,
|
|
75
|
-
targetImageBase64: input.targetImageBase64,
|
|
76
|
-
options: input.options,
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Check if input is dual image type
|
|
81
|
-
*/
|
|
82
|
-
const isDualImageInput = (input: ImageGenerationInput): input is DualImageInput => {
|
|
83
|
-
return "sourceImageBase64" in input && "targetImageBase64" in input;
|
|
84
34
|
};
|
|
85
35
|
|
|
86
|
-
export const useImageGeneration = <
|
|
87
|
-
TInput
|
|
88
|
-
|
|
89
|
-
>(config: ImageGenerationConfig<TInput, TResult>) => {
|
|
36
|
+
export const useImageGeneration = <TInput extends ImageGenerationInput, TResult>(
|
|
37
|
+
config: ImageGenerationConfig<TInput, TResult>,
|
|
38
|
+
) => {
|
|
90
39
|
const {
|
|
91
40
|
featureType,
|
|
92
41
|
userId,
|
|
@@ -100,11 +49,7 @@ export const useImageGeneration = <
|
|
|
100
49
|
onError,
|
|
101
50
|
} = config;
|
|
102
51
|
|
|
103
|
-
const repository = useMemo(
|
|
104
|
-
() => createCreationsRepository("creations"),
|
|
105
|
-
[],
|
|
106
|
-
);
|
|
107
|
-
|
|
52
|
+
const repository = useMemo(() => createCreationsRepository("creations"), []);
|
|
108
53
|
const lastInputRef = useRef<TInput | null>(null);
|
|
109
54
|
|
|
110
55
|
const strategy: GenerationStrategy<TInput, TResult> = useMemo(
|
|
@@ -112,17 +57,11 @@ export const useImageGeneration = <
|
|
|
112
57
|
execute: async (input) => {
|
|
113
58
|
lastInputRef.current = input;
|
|
114
59
|
|
|
115
|
-
// Build executor input
|
|
116
60
|
const executorInput = buildExecutorInput
|
|
117
61
|
? buildExecutorInput(input)
|
|
118
|
-
:
|
|
119
|
-
? defaultDualImageBuilder(input)
|
|
120
|
-
: defaultSingleImageBuilder(input as SingleImageInput);
|
|
62
|
+
: buildDefaultInput(input);
|
|
121
63
|
|
|
122
|
-
const result = await executeImageFeature(
|
|
123
|
-
featureType,
|
|
124
|
-
executorInput,
|
|
125
|
-
);
|
|
64
|
+
const result = await executeImageFeature(featureType, executorInput);
|
|
126
65
|
|
|
127
66
|
if (!result.success || !result.imageUrl) {
|
|
128
67
|
throw new Error(result.error || "Image generation failed");
|
|
@@ -133,7 +72,7 @@ export const useImageGeneration = <
|
|
|
133
72
|
getCreditCost: () => creditCost,
|
|
134
73
|
save: buildCreation
|
|
135
74
|
? async (result, uid) => {
|
|
136
|
-
const creation = buildCreation(result, lastInputRef.current ?? {} as TInput);
|
|
75
|
+
const creation = buildCreation(result, lastInputRef.current ?? ({} as TInput));
|
|
137
76
|
if (creation) {
|
|
138
77
|
await repository.create(uid, creation);
|
|
139
78
|
}
|
|
@@ -143,12 +82,7 @@ export const useImageGeneration = <
|
|
|
143
82
|
[featureType, processResult, buildExecutorInput, buildCreation, repository, creditCost],
|
|
144
83
|
);
|
|
145
84
|
|
|
146
|
-
const handleError = useCallback(
|
|
147
|
-
(error: { message: string }) => {
|
|
148
|
-
onError?.(error.message);
|
|
149
|
-
},
|
|
150
|
-
[onError],
|
|
151
|
-
);
|
|
85
|
+
const handleError = useCallback((error: { message: string }) => onError?.(error.message), [onError]);
|
|
152
86
|
|
|
153
87
|
return useGenerationOrchestrator(strategy, {
|
|
154
88
|
userId,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generation Flow Navigation Functions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { GenerationFlowConfig, GenerationFlowState, PhotoStepConfig } from "../types/flow-config.types";
|
|
6
|
+
|
|
7
|
+
export function createGoNextHandler(
|
|
8
|
+
canGoNext: boolean,
|
|
9
|
+
state: GenerationFlowState,
|
|
10
|
+
config: GenerationFlowConfig,
|
|
11
|
+
setState: (state: GenerationFlowState) => void,
|
|
12
|
+
onComplete?: (state: GenerationFlowState) => void,
|
|
13
|
+
onStepChange?: (stepIndex: number, stepConfig: PhotoStepConfig) => void
|
|
14
|
+
) {
|
|
15
|
+
return () => {
|
|
16
|
+
if (!canGoNext) return;
|
|
17
|
+
|
|
18
|
+
const nextIndex = state.currentStepIndex + 1;
|
|
19
|
+
const isLastStep = nextIndex >= config.photoSteps.length;
|
|
20
|
+
|
|
21
|
+
if (isLastStep) {
|
|
22
|
+
const newState = { ...state, isComplete: true };
|
|
23
|
+
setState(newState);
|
|
24
|
+
onComplete?.(newState);
|
|
25
|
+
} else {
|
|
26
|
+
setState({ ...state, currentStepIndex: nextIndex });
|
|
27
|
+
onStepChange?.(nextIndex, config.photoSteps[nextIndex]);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function createGoBackHandler(
|
|
33
|
+
canGoBack: boolean,
|
|
34
|
+
currentStepIndex: number,
|
|
35
|
+
config: GenerationFlowConfig,
|
|
36
|
+
setState: (updater: (prev: GenerationFlowState) => GenerationFlowState) => void,
|
|
37
|
+
onStepChange?: (stepIndex: number, stepConfig: PhotoStepConfig) => void
|
|
38
|
+
) {
|
|
39
|
+
return () => {
|
|
40
|
+
if (!canGoBack) return;
|
|
41
|
+
|
|
42
|
+
const prevIndex = currentStepIndex - 1;
|
|
43
|
+
setState((prev) => ({ ...prev, currentStepIndex: prevIndex, isComplete: false }));
|
|
44
|
+
onStepChange?.(prevIndex, config.photoSteps[prevIndex]);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function createCompleteHandler(
|
|
49
|
+
state: GenerationFlowState,
|
|
50
|
+
setState: (state: GenerationFlowState) => void,
|
|
51
|
+
onComplete?: (state: GenerationFlowState) => void
|
|
52
|
+
) {
|
|
53
|
+
return () => {
|
|
54
|
+
const newState = { ...state, isComplete: true };
|
|
55
|
+
setState(newState);
|
|
56
|
+
onComplete?.(newState);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generation Flow Update Functions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Dispatch, SetStateAction } from "react";
|
|
6
|
+
import type { GenerationFlowConfig, GenerationFlowState } from "../types/flow-config.types";
|
|
7
|
+
import { updatePhotoStep, isTextInputValid } from "./flow-state.utils";
|
|
8
|
+
|
|
9
|
+
export function createPhotoUpdater(
|
|
10
|
+
setState: Dispatch<SetStateAction<GenerationFlowState>>
|
|
11
|
+
) {
|
|
12
|
+
return (imageUri: string, previewUrl?: string) => {
|
|
13
|
+
setState((prev) =>
|
|
14
|
+
updatePhotoStep(prev, prev.currentStepIndex, {
|
|
15
|
+
imageUri,
|
|
16
|
+
previewUrl,
|
|
17
|
+
validationStatus: "pending",
|
|
18
|
+
}),
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function createNameUpdater(
|
|
24
|
+
setState: Dispatch<SetStateAction<GenerationFlowState>>
|
|
25
|
+
) {
|
|
26
|
+
return (name: string) => {
|
|
27
|
+
setState((prev) =>
|
|
28
|
+
updatePhotoStep(prev, prev.currentStepIndex, { name }),
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function createValidationUpdater(
|
|
34
|
+
setState: Dispatch<SetStateAction<GenerationFlowState>>
|
|
35
|
+
) {
|
|
36
|
+
return (isValid: boolean) => {
|
|
37
|
+
setState((prev) =>
|
|
38
|
+
updatePhotoStep(prev, prev.currentStepIndex, {
|
|
39
|
+
isValid,
|
|
40
|
+
validationStatus: isValid ? "valid" : "invalid",
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function createTextInputUpdater(
|
|
47
|
+
setState: Dispatch<SetStateAction<GenerationFlowState>>,
|
|
48
|
+
config: GenerationFlowConfig
|
|
49
|
+
) {
|
|
50
|
+
return (text: string) => {
|
|
51
|
+
setState((prev) => {
|
|
52
|
+
if (!prev.textInput) return prev;
|
|
53
|
+
|
|
54
|
+
const minLength = config.textInputStep?.minLength ?? 0;
|
|
55
|
+
const maxLength = config.textInputStep?.maxLength ?? Infinity;
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
...prev,
|
|
59
|
+
textInput: {
|
|
60
|
+
...prev.textInput,
|
|
61
|
+
text,
|
|
62
|
+
isValid: isTextInputValid(text, minLength, maxLength),
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generation Flow Hook Types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
GenerationFlowConfig,
|
|
7
|
+
GenerationFlowState,
|
|
8
|
+
PhotoStepData,
|
|
9
|
+
PhotoStepConfig,
|
|
10
|
+
} from "../types/flow-config.types";
|
|
11
|
+
|
|
12
|
+
export interface UseGenerationFlowOptions {
|
|
13
|
+
config: GenerationFlowConfig;
|
|
14
|
+
onComplete?: (state: GenerationFlowState) => void;
|
|
15
|
+
onStepChange?: (stepIndex: number, stepConfig: PhotoStepConfig) => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface UseGenerationFlowReturn {
|
|
19
|
+
state: GenerationFlowState;
|
|
20
|
+
currentStepConfig: PhotoStepConfig | null;
|
|
21
|
+
currentStepData: PhotoStepData | null;
|
|
22
|
+
canGoNext: boolean;
|
|
23
|
+
canGoBack: boolean;
|
|
24
|
+
goNext: () => void;
|
|
25
|
+
goBack: () => void;
|
|
26
|
+
updatePhoto: (imageUri: string, previewUrl?: string) => void;
|
|
27
|
+
updateName: (name: string) => void;
|
|
28
|
+
updateValidation: (isValid: boolean) => void;
|
|
29
|
+
updateTextInput: (text: string) => void;
|
|
30
|
+
reset: () => void;
|
|
31
|
+
complete: () => void;
|
|
32
|
+
}
|