@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.
Files changed (156) hide show
  1. package/package.json +1 -1
  2. package/src/domain/constants/processing-modes-catalog.constants.ts +97 -0
  3. package/src/domain/constants/processing-modes-filters.ts +34 -0
  4. package/src/domain/constants/processing-modes-getters.ts +20 -0
  5. package/src/domain/constants/processing-modes.constants.ts +8 -134
  6. package/src/domain/entities/feature-flow-config.types.ts +17 -0
  7. package/src/domain/entities/flow-actions.types.ts +26 -0
  8. package/src/domain/entities/flow-config-data.types.ts +41 -0
  9. package/src/domain/entities/flow-config.types.ts +17 -169
  10. package/src/domain/entities/flow-configuration.types.ts +44 -0
  11. package/src/domain/entities/flow-state.types.ts +30 -0
  12. package/src/domain/entities/flow-step.types.ts +56 -0
  13. package/src/domain/entities/scenario-step-config.types.ts +32 -0
  14. package/src/domain/entities/step-config.types.ts +14 -129
  15. package/src/domain/entities/step-definition.types.ts +50 -0
  16. package/src/domain/entities/step-input-config.types.ts +36 -0
  17. package/src/domain/entities/step-upload-config.types.ts +17 -0
  18. package/src/domain/interfaces/ai-provider-capabilities.types.ts +27 -0
  19. package/src/domain/interfaces/ai-provider-config.types.ts +30 -0
  20. package/src/domain/interfaces/ai-provider-feature-types.ts +22 -0
  21. package/src/domain/interfaces/ai-provider-input.types.ts +28 -0
  22. package/src/domain/interfaces/ai-provider-progress.types.ts +37 -0
  23. package/src/domain/interfaces/ai-provider-status.types.ts +41 -0
  24. package/src/domain/interfaces/ai-provider.interface.ts +32 -142
  25. package/src/domain/types/result-constructors.ts +20 -0
  26. package/src/domain/types/result-guards.ts +20 -0
  27. package/src/domain/types/result-transformers.ts +36 -0
  28. package/src/domain/types/result-type-definitions.ts +27 -0
  29. package/src/domain/types/result-unwrappers.ts +28 -0
  30. package/src/domain/types/result.types.ts +11 -100
  31. package/src/domains/background/infrastructure/utils/polling-interval.util.ts +3 -8
  32. package/src/domains/background/infrastructure/utils/result-validation-logic.ts +88 -0
  33. package/src/domains/background/infrastructure/utils/result-validator-constants.ts +18 -0
  34. package/src/domains/background/infrastructure/utils/result-validator.types.ts +16 -0
  35. package/src/domains/background/infrastructure/utils/result-validator.util.ts +8 -109
  36. package/src/domains/background/infrastructure/utils/status-checker.types.ts +11 -0
  37. package/src/domains/background/infrastructure/utils/status-checker.util.ts +9 -119
  38. package/src/domains/background/infrastructure/utils/status-error-detector.ts +61 -0
  39. package/src/domains/background/infrastructure/utils/status-extraction-helpers.ts +25 -0
  40. package/src/domains/background/infrastructure/utils/status-predicates.ts +37 -0
  41. package/src/domains/creations/domain-exports.ts +79 -0
  42. package/src/domains/creations/index.ts +9 -169
  43. package/src/domains/creations/infrastructure/repositories/creation-create.operations.ts +40 -0
  44. package/src/domains/creations/infrastructure/repositories/creation-delete.operations.ts +63 -0
  45. package/src/domains/creations/infrastructure/repositories/creation-update.operations.ts +77 -0
  46. package/src/domains/creations/infrastructure/repositories/creations-operations.ts +9 -210
  47. package/src/domains/creations/infrastructure-exports.ts +9 -0
  48. package/src/domains/creations/presentation-exports.ts +59 -0
  49. package/src/domains/generation/infrastructure/executors/text-to-image-executor.helpers.ts +81 -0
  50. package/src/domains/generation/infrastructure/executors/text-to-image-executor.ts +4 -100
  51. package/src/domains/generation/infrastructure/executors/text-to-image-executor.types.ts +19 -0
  52. package/src/domains/generation/infrastructure/flow/use-flow-store.types.ts +19 -0
  53. package/src/domains/generation/infrastructure/flow/useFlowStore.ts +33 -65
  54. package/src/domains/generation/wizard/domain/entities/wizard-config-builder.ts +75 -0
  55. package/src/domains/generation/wizard/domain/entities/wizard-feature-config.types.ts +29 -0
  56. package/src/domains/generation/wizard/domain/entities/wizard-feature.types.ts +9 -114
  57. package/src/domains/generation/wizard/domain/entities/wizard-presets.constants.ts +23 -0
  58. package/src/domains/generation/wizard/infrastructure/strategies/shared/unified-prompt-builder.ts +1 -1
  59. package/src/domains/generation/wizard/infrastructure/utils/creation-persistence-factory.ts +33 -0
  60. package/src/domains/generation/wizard/infrastructure/utils/creation-persistence.types.ts +22 -0
  61. package/src/domains/generation/wizard/infrastructure/utils/creation-persistence.util.ts +11 -135
  62. package/src/domains/generation/wizard/infrastructure/utils/creation-save-operations.ts +48 -0
  63. package/src/domains/generation/wizard/infrastructure/utils/creation-update-operations.ts +72 -0
  64. package/src/domains/generation/wizard/presentation/hooks/use-video-queue-generation.types.ts +21 -0
  65. package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +14 -35
  66. package/src/domains/image-to-video/domain/types/image-to-video-callbacks.types.ts +33 -0
  67. package/src/domains/image-to-video/domain/types/image-to-video-config.types.ts +29 -0
  68. package/src/domains/image-to-video/domain/types/image-to-video-request.types.ts +31 -0
  69. package/src/domains/image-to-video/domain/types/image-to-video-result.types.ts +17 -0
  70. package/src/domains/image-to-video/domain/types/image-to-video-state.types.ts +24 -0
  71. package/src/domains/image-to-video/domain/types/image-to-video.types.ts +24 -114
  72. package/src/domains/image-to-video/infrastructure/services/image-to-video-executor.ts +26 -99
  73. package/src/domains/image-to-video/infrastructure/services/image-to-video-executor.types.ts +15 -0
  74. package/src/domains/prompts/domain/base/constants.ts +47 -0
  75. package/src/domains/prompts/domain/base/creators.ts +76 -0
  76. package/src/domains/prompts/domain/base/types.ts +10 -0
  77. package/src/domains/prompts/domain/entities/MultiPersonPromptStructure.ts +1 -1
  78. package/src/domains/prompts/index.ts +4 -2
  79. package/src/domains/prompts/infrastructure/services/ImagePromptBuilder.ts +2 -72
  80. package/src/domains/prompts/infrastructure/services/image-prompt-builder.types.ts +17 -0
  81. package/src/domains/result-preview/presentation/types/result-components.types.ts +47 -0
  82. package/src/domains/result-preview/presentation/types/result-creation.types.ts +14 -0
  83. package/src/domains/result-preview/presentation/types/result-data.types.ts +35 -0
  84. package/src/domains/result-preview/presentation/types/result-hooks.types.ts +35 -0
  85. package/src/domains/result-preview/presentation/types/result-preview.types.ts +19 -182
  86. package/src/domains/result-preview/presentation/types/result-screen.types.ts +69 -0
  87. package/src/domains/text-to-image/domain-exports.ts +50 -0
  88. package/src/domains/text-to-image/index.ts +11 -102
  89. package/src/domains/text-to-image/infrastructure-exports.ts +6 -0
  90. package/src/domains/text-to-image/presentation/hooks/useFormState.ts +39 -24
  91. package/src/domains/text-to-image/presentation/hooks/useGeneration.ts +5 -3
  92. package/src/domains/text-to-image/presentation-exports.ts +41 -0
  93. package/src/domains/text-to-video/domain/types/action-component.types.ts +15 -0
  94. package/src/domains/text-to-video/domain/types/component.types.ts +16 -103
  95. package/src/domains/text-to-video/domain/types/content-component.types.ts +30 -0
  96. package/src/domains/text-to-video/domain/types/panel-component.types.ts +24 -0
  97. package/src/domains/text-to-video/domain/types/selector-component.types.ts +31 -0
  98. package/src/domains/text-to-video/domain/types/tab-component.types.ts +26 -0
  99. package/src/index.ts +0 -10
  100. package/src/infrastructure/executors/base-executor.ts +40 -112
  101. package/src/infrastructure/executors/base-executor.types.ts +10 -0
  102. package/src/infrastructure/http/http-client-methods.ts +73 -0
  103. package/src/infrastructure/http/http-client.util.ts +8 -163
  104. package/src/infrastructure/http/http-fetch-handler.ts +53 -0
  105. package/src/infrastructure/http/http-methods.constants.ts +23 -0
  106. package/src/infrastructure/http/http-request-executor.ts +49 -0
  107. package/src/infrastructure/http/http-response-parser.ts +53 -0
  108. package/src/infrastructure/orchestration/GenerationOrchestrator.ts +8 -43
  109. package/src/infrastructure/utils/classifier-helpers.ts +36 -0
  110. package/src/infrastructure/utils/content-validators.ts +92 -0
  111. package/src/infrastructure/utils/domain-guards.ts +22 -0
  112. package/src/infrastructure/utils/error-classification.ts +122 -0
  113. package/src/infrastructure/utils/error-classifier.util.ts +8 -181
  114. package/src/infrastructure/utils/error-classifiers.ts +49 -0
  115. package/src/infrastructure/utils/error-extractors.ts +42 -0
  116. package/src/infrastructure/utils/error-factory.ts +25 -0
  117. package/src/infrastructure/utils/error-handlers.ts +51 -0
  118. package/src/infrastructure/utils/error-handling.util.ts +7 -186
  119. package/src/infrastructure/utils/error-message-extractor.util.ts +10 -172
  120. package/src/infrastructure/utils/error-retry.ts +44 -0
  121. package/src/infrastructure/utils/error-types.ts +23 -0
  122. package/src/infrastructure/utils/extraction-types.ts +37 -0
  123. package/src/infrastructure/utils/fal-error-checker.ts +44 -0
  124. package/src/infrastructure/utils/general-validators.ts +64 -0
  125. package/src/infrastructure/utils/id-validators.ts +39 -0
  126. package/src/infrastructure/utils/message-extractor.ts +89 -0
  127. package/src/infrastructure/utils/primitive-guards.ts +66 -0
  128. package/src/infrastructure/utils/result-polling.ts +39 -0
  129. package/src/infrastructure/utils/structure-guards.ts +75 -0
  130. package/src/infrastructure/utils/type-guards.util.ts +22 -149
  131. package/src/infrastructure/utils/validation-types.ts +8 -0
  132. package/src/infrastructure/utils/validation.util.ts +14 -184
  133. package/src/presentation/hooks/ai-feature-callbacks-auth.hooks.ts +43 -0
  134. package/src/presentation/hooks/ai-feature-callbacks-cost.hooks.ts +56 -0
  135. package/src/presentation/hooks/ai-feature-callbacks-execution.hooks.ts +66 -0
  136. package/src/presentation/hooks/ai-feature-callbacks.types.ts +69 -0
  137. package/src/presentation/hooks/generation/use-image-generation.types.ts +39 -0
  138. package/src/presentation/hooks/generation/useImageGeneration.ts +33 -99
  139. package/src/presentation/hooks/generation-flow-navigation.ts +58 -0
  140. package/src/presentation/hooks/generation-flow-updates.ts +67 -0
  141. package/src/presentation/hooks/generation-flow.types.ts +32 -0
  142. package/src/presentation/hooks/useAIFeatureCallbacks.ts +48 -138
  143. package/src/presentation/hooks/useGenerationFlow.ts +40 -136
  144. package/src/presentation/types/flow-config.types.ts +9 -140
  145. package/src/presentation/types/flow-generation-config.types.ts +25 -0
  146. package/src/presentation/types/flow-state.types.ts +16 -0
  147. package/src/presentation/types/flow-step-configs.types.ts +48 -0
  148. package/src/presentation/types/flow-step-data.types.ts +24 -0
  149. package/src/presentation/types/result-actions.types.ts +50 -0
  150. package/src/presentation/types/result-config.types.ts +22 -171
  151. package/src/presentation/types/result-header.types.ts +44 -0
  152. package/src/presentation/types/result-image.types.ts +29 -0
  153. package/src/presentation/types/result-layout.types.ts +26 -0
  154. package/src/presentation/types/result-story.types.ts +42 -0
  155. package/src/domains/prompts/domain/entities/BasePromptStructure.ts +0 -168
  156. 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
- * useImageGeneration Hook
3
- * Generic image generation hook for ANY image feature
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, AlertMessages } from "./types";
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 { Creation } from "../../../domains/creations/domain/entities/Creation";
14
-
15
- /**
16
- * Generic input for single image features
17
- */
18
- export interface SingleImageInput {
19
- imageBase64: string;
20
- prompt?: string;
21
- options?: Record<string, unknown>;
22
- }
23
-
24
- /**
25
- * Generic input for dual image features (face-swap, etc.)
26
- */
27
- export interface DualImageInput {
28
- sourceImageBase64: string;
29
- targetImageBase64: string;
30
- options?: Record<string, unknown>;
31
- }
32
-
33
- export type ImageGenerationInput = SingleImageInput | DualImageInput;
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 extends ImageGenerationInput,
88
- TResult,
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
- : isDualImageInput(input)
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
+ }