@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.
Files changed (35) hide show
  1. package/package.json +1 -1
  2. package/src/core/types/error.types.ts +3 -30
  3. package/src/core/types/provider.types.ts +35 -188
  4. package/src/core/types/result.types.ts +12 -96
  5. package/src/domain/entities/flow-config.types.ts +2 -2
  6. package/src/domains/generation/domain/generation.types.ts +4 -7
  7. package/src/domains/generation/index.ts +1 -1
  8. package/src/domains/generation/presentation/useAIGeneration.hook.ts +3 -15
  9. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.ts +1 -1
  10. package/src/features/image-to-video/infrastructure/services/image-to-video-executor.ts +10 -37
  11. package/src/features/image-to-video/presentation/hooks/image-to-video-feature.types.ts +2 -12
  12. package/src/features/image-to-video/presentation/hooks/useImageToVideoFeature.ts +24 -13
  13. package/src/features/text-to-video/infrastructure/services/text-to-video-executor.ts +5 -37
  14. package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +26 -26
  15. package/src/infrastructure/orchestration/GenerationOrchestrator.ts +17 -14
  16. package/src/infrastructure/orchestration/orchestrator.types.ts +2 -5
  17. package/src/infrastructure/services/generation-orchestrator.service.ts +6 -6
  18. package/src/infrastructure/utils/README.md +7 -7
  19. package/src/infrastructure/utils/base64.util.ts +15 -0
  20. package/src/infrastructure/utils/error-classifier.util.ts +27 -10
  21. package/src/infrastructure/utils/error-message-extractor.util.ts +3 -3
  22. package/src/infrastructure/utils/error-patterns.constants.ts +21 -8
  23. package/src/infrastructure/utils/id-generator.util.ts +11 -0
  24. package/src/infrastructure/utils/index.ts +3 -0
  25. package/src/infrastructure/utils/provider-validator.util.ts +2 -2
  26. package/src/infrastructure/utils/video-result-extractor.util.ts +38 -0
  27. package/src/presentation/constants/alert-messages.ts +14 -0
  28. package/src/presentation/hooks/generation/errors.ts +5 -1
  29. package/src/presentation/hooks/generation/useImageGeneration.ts +6 -2
  30. package/src/presentation/hooks/generation/useVideoGeneration.ts +6 -2
  31. package/src/presentation/hooks/useGenerationFlow.ts +18 -23
  32. package/src/presentation/layouts/DualImageFeatureLayout.tsx +0 -1
  33. package/src/presentation/layouts/DualImageVideoFeatureLayout.tsx +1 -1
  34. package/src/presentation/layouts/SingleImageFeatureLayout.tsx +1 -1
  35. package/src/presentation/layouts/SingleImageWithPromptFeatureLayout.tsx +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.61.25",
3
+ "version": "1.61.26",
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",
@@ -1,36 +1,9 @@
1
1
  /**
2
2
  * AI Generation Error Types
3
- * Provider-agnostic error classification
3
+ * Re-exports from canonical domain source
4
4
  *
5
5
  * @module @umituz/react-native-ai-generation-content/core
6
6
  */
7
7
 
8
- export enum AIErrorType {
9
- NETWORK = "NETWORK",
10
- RATE_LIMIT = "RATE_LIMIT",
11
- AUTHENTICATION = "AUTHENTICATION",
12
- VALIDATION = "VALIDATION",
13
- CONTENT_POLICY = "CONTENT_POLICY",
14
- SERVER = "SERVER",
15
- TIMEOUT = "TIMEOUT",
16
- UNKNOWN = "UNKNOWN",
17
- }
18
-
19
- export interface AIErrorInfo {
20
- type: AIErrorType;
21
- messageKey: string;
22
- retryable: boolean;
23
- originalError?: unknown;
24
- statusCode?: number;
25
- }
26
-
27
- export interface AIErrorMessages {
28
- [AIErrorType.NETWORK]: string;
29
- [AIErrorType.RATE_LIMIT]: string;
30
- [AIErrorType.AUTHENTICATION]: string;
31
- [AIErrorType.VALIDATION]: string;
32
- [AIErrorType.CONTENT_POLICY]: string;
33
- [AIErrorType.SERVER]: string;
34
- [AIErrorType.TIMEOUT]: string;
35
- [AIErrorType.UNKNOWN]: string;
36
- }
8
+ export { AIErrorType } from "../../domain/entities/error.types";
9
+ export type { AIErrorInfo, AIErrorMessages } from "../../domain/entities/error.types";
@@ -1,192 +1,39 @@
1
1
  /**
2
2
  * AI Provider Types - Core interfaces for AI generation providers
3
+ * Re-exports from canonical domain sources
4
+ *
5
+ * @module @umituz/react-native-ai-generation-content/core
3
6
  */
4
7
 
5
- // Feature Types
6
- export type ImageFeatureType =
7
- | "upscale"
8
- | "photo-restore"
9
- | "face-swap"
10
- | "anime-selfie"
11
- | "remove-background"
12
- | "remove-object"
13
- | "hd-touch-up"
14
- | "replace-background";
15
-
16
- /**
17
- * Feature types for video generation (output: video)
18
- */
19
- export type VideoFeatureType = "image-to-video" | "text-to-video";
20
-
21
- // =============================================================================
22
- // Provider Configuration
23
- // =============================================================================
24
-
25
- export interface AIProviderConfig {
26
- apiKey: string;
27
- maxRetries?: number;
28
- baseDelay?: number;
29
- maxDelay?: number;
30
- defaultTimeoutMs?: number;
31
- textModel?: string;
32
- textToImageModel?: string;
33
- imageEditModel?: string;
34
- videoGenerationModel?: string;
35
- videoFeatureModels?: Partial<Record<VideoFeatureType, string>>;
36
- imageFeatureModels?: Partial<Record<ImageFeatureType, string>>;
37
- }
38
-
39
- // =============================================================================
40
- // Status Types
41
- // =============================================================================
42
-
43
- export type AIJobStatusType =
44
- | "IN_QUEUE"
45
- | "IN_PROGRESS"
46
- | "COMPLETED"
47
- | "FAILED";
48
-
49
- export interface AILogEntry {
50
- message: string;
51
- level: "info" | "warn" | "error";
52
- timestamp?: string;
53
- }
54
-
55
- export interface JobSubmission {
56
- requestId: string;
57
- statusUrl?: string;
58
- responseUrl?: string;
59
- }
60
-
61
- export interface JobStatus {
62
- status: AIJobStatusType;
63
- logs?: AILogEntry[];
64
- queuePosition?: number;
65
- eta?: number;
66
- }
67
-
68
- // =============================================================================
69
- // Progress & Options
70
- // =============================================================================
71
-
72
- export interface ProviderProgressInfo {
73
- progress: number;
74
- status?: AIJobStatusType;
75
- message?: string;
76
- estimatedTimeRemaining?: number;
77
- }
78
-
79
- export interface SubscribeOptions<T = unknown> {
80
- timeoutMs?: number;
81
- onQueueUpdate?: (status: JobStatus) => void;
82
- onProgress?: (progress: ProviderProgressInfo) => void;
83
- onResult?: (result: T) => void;
84
- }
85
-
86
- export interface RunOptions {
87
- onProgress?: (progress: ProviderProgressInfo) => void;
88
- }
89
-
90
- // =============================================================================
91
- // Capabilities
92
- // =============================================================================
93
-
94
- export interface ProviderCapabilities {
95
- imageFeatures: readonly ImageFeatureType[];
96
- videoFeatures: readonly VideoFeatureType[];
97
- textToImage: boolean;
98
- textToVideo: boolean;
99
- imageToVideo: boolean;
100
- textToVoice: boolean;
101
- textToText: boolean;
102
- }
103
-
104
- // =============================================================================
105
- // Feature Input Data
106
- // =============================================================================
107
-
108
- export interface ImageFeatureInputData {
109
- imageBase64: string;
110
- targetImageBase64?: string;
111
- prompt?: string;
112
- options?: Record<string, unknown>;
113
- }
114
-
115
- export interface VideoFeatureInputData {
116
- sourceImageBase64?: string;
117
- targetImageBase64?: string;
118
- prompt?: string;
119
- options?: Record<string, unknown>;
120
- }
121
-
122
- // =============================================================================
123
- // Provider Sub-Interfaces (Interface Segregation Principle)
124
- // =============================================================================
125
-
126
- export interface IAIProviderLifecycle {
127
- initialize(config: AIProviderConfig): void;
128
- isInitialized(): boolean;
129
- reset(): void;
130
- }
131
-
132
- export interface IAIProviderCapabilities {
133
- getCapabilities(): ProviderCapabilities;
134
- isFeatureSupported(feature: ImageFeatureType | VideoFeatureType): boolean;
135
- }
136
-
137
- export interface IAIProviderJobManager {
138
- submitJob(
139
- model: string,
140
- input: Record<string, unknown>,
141
- ): Promise<JobSubmission>;
142
- getJobStatus(model: string, requestId: string): Promise<JobStatus>;
143
- getJobResult<T = unknown>(model: string, requestId: string): Promise<T>;
144
- }
145
-
146
- export interface IAIProviderExecutor {
147
- subscribe<T = unknown>(
148
- model: string,
149
- input: Record<string, unknown>,
150
- options?: SubscribeOptions<T>,
151
- ): Promise<T>;
152
- run<T = unknown>(
153
- model: string,
154
- input: Record<string, unknown>,
155
- options?: RunOptions,
156
- ): Promise<T>;
157
- }
158
-
159
- export interface IAIProviderImageFeatures {
160
- getImageFeatureModel(feature: ImageFeatureType): string;
161
- buildImageFeatureInput(
162
- feature: ImageFeatureType,
163
- data: ImageFeatureInputData,
164
- ): Record<string, unknown>;
165
- }
166
-
167
- export interface IAIProviderVideoFeatures {
168
- getVideoFeatureModel(feature: VideoFeatureType): string;
169
- buildVideoFeatureInput(
170
- feature: VideoFeatureType,
171
- data: VideoFeatureInputData,
172
- ): Record<string, unknown>;
173
- }
174
-
175
- // =============================================================================
176
- // Main Provider Interface
177
- // =============================================================================
178
-
179
- /**
180
- * Main AI Provider Interface
181
- * Composition of segregated interfaces following SOLID principles
182
- */
183
- export interface IAIProvider
184
- extends IAIProviderLifecycle,
185
- IAIProviderCapabilities,
186
- IAIProviderJobManager,
187
- IAIProviderExecutor,
188
- IAIProviderImageFeatures,
189
- IAIProviderVideoFeatures {
190
- readonly providerId: string;
191
- readonly providerName: string;
192
- }
8
+ // Main provider types from ai-provider.interface
9
+ export type {
10
+ // Feature Types
11
+ ImageFeatureType,
12
+ VideoFeatureType,
13
+ // Config
14
+ AIProviderConfig,
15
+ // Status
16
+ AIJobStatusType,
17
+ AILogEntry,
18
+ JobSubmission,
19
+ JobStatus,
20
+ // Progress
21
+ ProviderProgressInfo,
22
+ SubscribeOptions,
23
+ RunOptions,
24
+ // Capabilities
25
+ ProviderCapabilities,
26
+ // Input Data
27
+ ImageFeatureInputData,
28
+ VideoFeatureInputData,
29
+ // Main Provider Interface
30
+ IAIProvider,
31
+ } from "../../domain/interfaces/ai-provider.interface";
32
+
33
+ // Segregated provider sub-interfaces
34
+ export type { IAIProviderLifecycle } from "../../domain/interfaces/provider-lifecycle.interface";
35
+ export type { IAIProviderCapabilities } from "../../domain/interfaces/provider-capabilities.interface";
36
+ export type { IAIProviderJobManager } from "../../domain/interfaces/provider-job-manager.interface";
37
+ export type { IAIProviderExecutor } from "../../domain/interfaces/provider-executor.interface";
38
+ export type { IAIProviderImageFeatures } from "../../domain/interfaces/provider-image-features.interface";
39
+ export type { IAIProviderVideoFeatures } from "../../domain/interfaces/provider-video-features.interface";
@@ -1,102 +1,18 @@
1
1
  /**
2
2
  * Result Type Pattern for Functional Error Handling
3
- * Inspired by Rust's Result<T, E> type
3
+ * Re-exports from canonical domain source
4
4
  *
5
5
  * @module @umituz/react-native-ai-generation-content/core
6
6
  */
7
7
 
8
- /**
9
- * Success result containing a value of type T
10
- */
11
- export interface Success<T> {
12
- success: true;
13
- value: T;
14
- }
15
-
16
- /**
17
- * Failure result containing an error of type E
18
- */
19
- export interface Failure<E> {
20
- success: false;
21
- error: E;
22
- }
23
-
24
- /**
25
- * Result type that can be either Success or Failure
26
- * Forces explicit error handling at compile time
27
- */
28
- export type Result<T, E = string> = Success<T> | Failure<E>;
29
-
30
- /**
31
- * Create a successful result
32
- */
33
- export function success<T>(value: T): Success<T> {
34
- return { success: true, value };
35
- }
36
-
37
- /**
38
- * Create a failed result
39
- */
40
- export function failure<E>(error: E): Failure<E> {
41
- return { success: false, error };
42
- }
43
-
44
- /**
45
- * Type guard to check if result is successful
46
- */
47
- export function isSuccess<T, E>(result: Result<T, E>): result is Success<T> {
48
- return result.success === true;
49
- }
50
-
51
- /**
52
- * Type guard to check if result is a failure
53
- */
54
- export function isFailure<T, E>(result: Result<T, E>): result is Failure<E> {
55
- return result.success === false;
56
- }
57
-
58
- /**
59
- * Map a successful result to a new value
60
- */
61
- export function mapResult<T, U, E>(
62
- result: Result<T, E>,
63
- fn: (value: T) => U,
64
- ): Result<U, E> {
65
- if (isSuccess(result)) {
66
- return success(fn(result.value));
67
- }
68
- return result;
69
- }
70
-
71
- /**
72
- * Chain async operations on Result types
73
- */
74
- export async function andThen<T, U, E>(
75
- result: Result<T, E>,
76
- fn: (value: T) => Promise<Result<U, E>>,
77
- ): Promise<Result<U, E>> {
78
- if (isSuccess(result)) {
79
- return fn(result.value);
80
- }
81
- return result;
82
- }
83
-
84
- /**
85
- * Unwrap a result, throwing if it's a failure
86
- */
87
- export function unwrap<T, E>(result: Result<T, E>): T {
88
- if (isSuccess(result)) {
89
- return result.value;
90
- }
91
- throw new Error(`Called unwrap on a failure: ${String(result.error)}`);
92
- }
93
-
94
- /**
95
- * Unwrap a result or return a default value
96
- */
97
- export function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T {
98
- if (isSuccess(result)) {
99
- return result.value;
100
- }
101
- return defaultValue;
102
- }
8
+ export type { Result, Success, Failure } from "../../domain/types/result.types";
9
+ export {
10
+ success,
11
+ failure,
12
+ isSuccess,
13
+ isFailure,
14
+ mapResult,
15
+ andThen,
16
+ unwrap,
17
+ unwrapOr,
18
+ } from "../../domain/types/result.types";
@@ -79,8 +79,8 @@ export interface StepDefinition<TConfig = unknown> {
79
79
  readonly component?: React.ComponentType<StepComponentProps>;
80
80
  }
81
81
 
82
- /** Flow Generation Status */
83
- export type FlowGenerationStatus = "idle" | "preparing" | "generating" | "completed" | "failed";
82
+ /** Flow Generation Status - subset of GenerationStatus */
83
+ export type FlowGenerationStatus = Extract<import("./generation.types").GenerationStatus, "idle" | "preparing" | "generating" | "completed" | "failed">;
84
84
 
85
85
  /** Flow State */
86
86
  export interface FlowState {
@@ -13,14 +13,11 @@ export interface GenerationOptions {
13
13
  }
14
14
 
15
15
  // ============================================================================
16
- // Generation Result
16
+ // Generation Result (re-exported from canonical source)
17
17
  // ============================================================================
18
18
 
19
- export interface GenerationResult<T> {
20
- success: boolean;
21
- data?: T;
22
- error?: string;
23
- }
19
+ import type { GenerationResult as _GenerationResult } from "../../../domain/entities/generation.types";
20
+ export type { GenerationResult } from "../../../domain/entities/generation.types";
24
21
 
25
22
  // ============================================================================
26
23
  // Input Types (by generation type)
@@ -86,5 +83,5 @@ export interface GenerationExecutor<TInput, TOutput> {
86
83
  model: string,
87
84
  input: TInput,
88
85
  options?: GenerationOptions,
89
- ): Promise<GenerationResult<TOutput>>;
86
+ ): Promise<_GenerationResult<TOutput>>;
90
87
  }
@@ -2,8 +2,8 @@ export {
2
2
  useAIGeneration,
3
3
  type UseAIGenerationProps,
4
4
  type UseAIGenerationReturn,
5
- type AlertMessages,
6
5
  } from "./presentation/useAIGeneration.hook";
6
+ export type { AlertMessages } from "../../presentation/hooks/generation/types";
7
7
 
8
8
  export { featureRegistry } from "./application/feature-registry";
9
9
  export { createGenerationStrategy } from "./application/generation-strategy.factory";
@@ -5,6 +5,8 @@
5
5
  */
6
6
 
7
7
  import { useGenerationOrchestrator } from "../../../presentation/hooks/generation/orchestrator";
8
+ import type { AlertMessages } from "../../../presentation/hooks/generation/types";
9
+ import { DEFAULT_ALERT_MESSAGES } from "../../../presentation/constants/alert-messages";
8
10
  import { createGenerationStrategy } from "../application/generation-strategy.factory";
9
11
 
10
12
  declare const __DEV__: boolean;
@@ -13,14 +15,6 @@ declare const __DEV__: boolean;
13
15
  // Types
14
16
  // ============================================================================
15
17
 
16
- export interface AlertMessages {
17
- networkError: string;
18
- policyViolation: string;
19
- saveFailed: string;
20
- creditFailed: string;
21
- unknown: string;
22
- }
23
-
24
18
  export interface UseAIGenerationProps {
25
19
  /** Feature ID from feature registry */
26
20
  featureId: string;
@@ -89,13 +83,7 @@ export function useAIGeneration(
89
83
  // Use orchestrator for lifecycle management
90
84
  const orchestrator = useGenerationOrchestrator(strategy, {
91
85
  userId,
92
- alertMessages: alertMessages || {
93
- networkError: "No internet connection",
94
- policyViolation: "Content policy violation",
95
- saveFailed: "Failed to save",
96
- creditFailed: "Failed to deduct credits",
97
- unknown: "An error occurred",
98
- },
86
+ alertMessages: alertMessages || DEFAULT_ALERT_MESSAGES,
99
87
  onSuccess,
100
88
  onError: onError ? (error) => onError(error.message) : undefined,
101
89
  onCreditsExhausted,
@@ -123,7 +123,7 @@ export function usePhotoBlockingGeneration(
123
123
  }
124
124
 
125
125
  // Start blocking generation
126
- generate(input);
126
+ await generate(input);
127
127
  },
128
128
  [userId, scenario, persistence, generate],
129
129
  );
@@ -5,6 +5,11 @@
5
5
 
6
6
  import { BaseExecutor } from "../../../../infrastructure/executors/base-executor";
7
7
  import { isSuccess, type Result } from "../../../../domain/types/result.types";
8
+ import { checkFalApiError } from "../../../../infrastructure/utils";
9
+ import {
10
+ defaultExtractVideoResult,
11
+ type ExtractedVideoResult,
12
+ } from "../../../../infrastructure/utils/video-result-extractor.util";
8
13
  import type { IAIProvider } from "../../../../domain/interfaces";
9
14
  import type {
10
15
  ImageToVideoRequest,
@@ -23,14 +28,6 @@ export interface ExecuteImageToVideoOptions {
23
28
  onProgress?: (progress: number) => void;
24
29
  }
25
30
 
26
- /**
27
- * Extracted result structure from provider response
28
- */
29
- interface ExtractedVideoResult {
30
- videoUrl?: string;
31
- thumbnailUrl?: string;
32
- }
33
-
34
31
  /**
35
32
  * Map job status to progress percentage
36
33
  */
@@ -51,34 +48,6 @@ const getProgressFromJobStatus = (status: string): number => {
51
48
  }
52
49
  };
53
50
 
54
- /**
55
- * Default extractor for image-to-video results
56
- */
57
- function defaultExtractResult(
58
- result: unknown,
59
- ): ExtractedVideoResult | undefined {
60
- if (typeof result !== "object" || result === null) return undefined;
61
-
62
- const r = result as Record<string, unknown>;
63
-
64
- if (typeof r.video === "string") {
65
- return { videoUrl: r.video };
66
- }
67
-
68
- if (r.video && typeof r.video === "object") {
69
- const video = r.video as Record<string, unknown>;
70
- if (typeof video.url === "string") {
71
- return {
72
- videoUrl: video.url,
73
- thumbnailUrl:
74
- typeof r.thumbnail === "string" ? r.thumbnail : undefined,
75
- };
76
- }
77
- }
78
-
79
- return undefined;
80
- }
81
-
82
51
  /**
83
52
  * Image-to-Video Executor using Template Method pattern
84
53
  * Eliminates code duplication through BaseExecutor
@@ -126,6 +95,10 @@ class ImageToVideoExecutor extends BaseExecutor<
126
95
  this.logInfo(
127
96
  `Subscribe resolved, result keys: ${result ? Object.keys(result as object) : "null"}`,
128
97
  );
98
+
99
+ // FAL can return errors with COMPLETED status - check for this
100
+ checkFalApiError(result);
101
+
129
102
  return result;
130
103
  }
131
104
 
@@ -151,7 +124,7 @@ class ImageToVideoExecutor extends BaseExecutor<
151
124
  protected getDefaultExtractor(): (
152
125
  result: unknown,
153
126
  ) => ExtractedVideoResult | undefined {
154
- return defaultExtractResult;
127
+ return defaultExtractVideoResult;
155
128
  }
156
129
  }
157
130
 
@@ -10,7 +10,8 @@ import type {
10
10
  ImageToVideoFeatureCallbacks,
11
11
  ImageToVideoGenerateParams,
12
12
  } from "../../domain/types";
13
- import type { AlertMessages } from "../../../../presentation/hooks/generation";
13
+ export { DEFAULT_ALERT_MESSAGES } from "../../../../presentation/constants/alert-messages";
14
+ export { generateCreationId } from "../../../../infrastructure/utils/id-generator.util";
14
15
 
15
16
  export const INITIAL_STATE: ImageToVideoFeatureState = {
16
17
  imageUri: null,
@@ -22,14 +23,6 @@ export const INITIAL_STATE: ImageToVideoFeatureState = {
22
23
  error: null,
23
24
  };
24
25
 
25
- export const DEFAULT_ALERT_MESSAGES: AlertMessages = {
26
- networkError: "No internet connection. Please check your network.",
27
- policyViolation: "Content not allowed. Please try again.",
28
- saveFailed: "Failed to save. Please try again.",
29
- creditFailed: "Credit operation failed. Please try again.",
30
- unknown: "An error occurred. Please try again.",
31
- };
32
-
33
26
  export interface UseImageToVideoFeatureProps {
34
27
  config: ImageToVideoFeatureConfig;
35
28
  callbacks?: ImageToVideoFeatureCallbacks;
@@ -54,6 +47,3 @@ export interface VideoGenerationInput {
54
47
  creationId: string;
55
48
  }
56
49
 
57
- export function generateCreationId(): string {
58
- return `image-to-video_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
59
- }