@umituz/react-native-ai-generation-content 1.17.0 → 1.17.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 +13 -14
  2. package/src/domains/creations/domain/entities/Creation.ts +33 -2
  3. package/src/domains/creations/domain/entities/index.ts +1 -1
  4. package/src/domains/creations/domain/types/creation-categories.ts +133 -0
  5. package/src/domains/creations/domain/types/creation-filter.ts +131 -0
  6. package/src/domains/creations/domain/types/creation-types.ts +63 -0
  7. package/src/domains/creations/domain/types/index.ts +44 -0
  8. package/src/domains/creations/domain/utils/creation-helpers.ts +134 -0
  9. package/src/domains/creations/domain/utils/index.ts +8 -0
  10. package/src/domains/creations/domain/utils/preview-helpers.ts +84 -0
  11. package/src/domains/creations/domain/utils/status-helpers.ts +90 -0
  12. package/src/domains/creations/index.ts +95 -21
  13. package/src/domains/creations/infrastructure/repositories/CreationsRepository.ts +14 -1
  14. package/src/domains/creations/presentation/components/CreationActions.tsx +120 -0
  15. package/src/domains/creations/presentation/components/CreationBadges.tsx +111 -0
  16. package/src/domains/creations/presentation/components/CreationCard.tsx +201 -102
  17. package/src/domains/creations/presentation/components/CreationPreview.tsx +117 -0
  18. package/src/domains/creations/presentation/components/CreationsFilterBar.tsx +254 -0
  19. package/src/domains/creations/presentation/components/CreationsGrid.tsx +121 -68
  20. package/src/domains/creations/presentation/components/CreationsHomeCard.tsx +1 -1
  21. package/src/domains/creations/presentation/components/index.ts +23 -3
  22. package/src/domains/creations/presentation/hooks/index.ts +1 -0
  23. package/src/domains/creations/presentation/hooks/useAdvancedFilter.ts +261 -0
  24. package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +8 -6
  25. package/src/domains/face-detection/infrastructure/validators/faceValidator.ts +1 -1
  26. package/src/domains/prompts/infrastructure/services/PromptGenerationService.ts +1 -1
  27. package/src/domains/prompts/presentation/hooks/useFaceSwap.ts +2 -2
  28. package/src/domains/prompts/presentation/hooks/usePromptGeneration.ts +4 -4
  29. package/src/features/ai-hug/domain/index.ts +5 -0
  30. package/src/features/ai-hug/domain/types/ai-hug.types.ts +72 -0
  31. package/src/features/ai-hug/domain/types/index.ts +14 -0
  32. package/src/features/ai-hug/index.ts +27 -0
  33. package/src/features/ai-hug/infrastructure/index.ts +5 -0
  34. package/src/features/ai-hug/infrastructure/services/ai-hug-executor.ts +96 -0
  35. package/src/features/ai-hug/infrastructure/services/index.ts +6 -0
  36. package/src/features/ai-hug/presentation/hooks/index.ts +9 -0
  37. package/src/features/ai-hug/presentation/hooks/useAIHugFeature.ts +157 -0
  38. package/src/features/ai-hug/presentation/index.ts +5 -0
  39. package/src/features/ai-kiss/domain/index.ts +5 -0
  40. package/src/features/ai-kiss/domain/types/ai-kiss.types.ts +72 -0
  41. package/src/features/ai-kiss/domain/types/index.ts +14 -0
  42. package/src/features/ai-kiss/index.ts +27 -0
  43. package/src/features/ai-kiss/infrastructure/index.ts +5 -0
  44. package/src/features/ai-kiss/infrastructure/services/ai-kiss-executor.ts +96 -0
  45. package/src/features/ai-kiss/infrastructure/services/index.ts +6 -0
  46. package/src/features/ai-kiss/presentation/hooks/index.ts +9 -0
  47. package/src/features/ai-kiss/presentation/hooks/useAIKissFeature.ts +157 -0
  48. package/src/features/ai-kiss/presentation/index.ts +5 -0
  49. package/src/features/anime-selfie/domain/index.ts +5 -0
  50. package/src/features/anime-selfie/domain/types/anime-selfie.types.ts +72 -0
  51. package/src/features/anime-selfie/domain/types/index.ts +15 -0
  52. package/src/features/anime-selfie/index.ts +28 -0
  53. package/src/features/anime-selfie/infrastructure/index.ts +5 -0
  54. package/src/features/anime-selfie/infrastructure/services/anime-selfie-executor.ts +95 -0
  55. package/src/features/anime-selfie/infrastructure/services/index.ts +6 -0
  56. package/src/features/anime-selfie/presentation/hooks/index.ts +9 -0
  57. package/src/features/anime-selfie/presentation/hooks/useAnimeSelfieFeature.ts +138 -0
  58. package/src/features/anime-selfie/presentation/index.ts +5 -0
  59. package/src/features/background/domain/types/index.ts +15 -0
  60. package/src/features/background/domain/types/replace-background.types.ts +82 -0
  61. package/src/features/background/index.ts +31 -3
  62. package/src/features/background/infrastructure/index.ts +5 -0
  63. package/src/features/background/infrastructure/services/index.ts +6 -0
  64. package/src/features/background/infrastructure/services/replace-background-executor.ts +95 -0
  65. package/src/features/background/presentation/hooks/index.ts +6 -1
  66. package/src/features/background/presentation/hooks/useReplaceBackgroundFeature.ts +160 -0
  67. package/src/features/face-swap/domain/index.ts +5 -0
  68. package/src/features/face-swap/domain/types/face-swap.types.ts +72 -0
  69. package/src/features/face-swap/domain/types/index.ts +14 -0
  70. package/src/features/face-swap/index.ts +27 -1
  71. package/src/features/face-swap/infrastructure/index.ts +5 -0
  72. package/src/features/face-swap/infrastructure/services/face-swap-executor.ts +96 -0
  73. package/src/features/face-swap/infrastructure/services/index.ts +6 -0
  74. package/src/features/face-swap/presentation/hooks/index.ts +9 -0
  75. package/src/features/face-swap/presentation/hooks/useFaceSwapFeature.ts +157 -0
  76. package/src/features/face-swap/presentation/index.ts +5 -0
  77. package/src/features/image-to-video/domain/index.ts +1 -0
  78. package/src/features/image-to-video/domain/types/image-to-video.types.ts +71 -0
  79. package/src/features/image-to-video/domain/types/index.ts +10 -0
  80. package/src/features/image-to-video/index.ts +27 -0
  81. package/src/features/image-to-video/infrastructure/index.ts +1 -0
  82. package/src/features/image-to-video/infrastructure/services/image-to-video-executor.ts +112 -0
  83. package/src/features/image-to-video/infrastructure/services/index.ts +5 -0
  84. package/src/features/image-to-video/presentation/hooks/index.ts +5 -0
  85. package/src/features/image-to-video/presentation/hooks/useImageToVideoFeature.ts +121 -0
  86. package/src/features/image-to-video/presentation/index.ts +1 -0
  87. package/src/features/photo-restoration/domain/types/index.ts +2 -5
  88. package/src/features/photo-restoration/domain/types/photo-restore.types.ts +14 -0
  89. package/src/features/photo-restoration/index.ts +3 -8
  90. package/src/features/photo-restoration/infrastructure/services/index.ts +1 -6
  91. package/src/features/photo-restoration/infrastructure/services/photo-restore-executor.ts +64 -30
  92. package/src/features/photo-restoration/presentation/hooks/usePhotoRestoreFeature.ts +11 -6
  93. package/src/features/remove-background/domain/index.ts +5 -0
  94. package/src/features/remove-background/domain/types/index.ts +14 -0
  95. package/src/features/remove-background/domain/types/remove-background.types.ts +69 -0
  96. package/src/features/remove-background/index.ts +27 -0
  97. package/src/features/remove-background/infrastructure/index.ts +5 -0
  98. package/src/features/remove-background/infrastructure/services/index.ts +6 -0
  99. package/src/features/remove-background/infrastructure/services/remove-background-executor.ts +95 -0
  100. package/src/features/remove-background/presentation/hooks/index.ts +9 -0
  101. package/src/features/remove-background/presentation/hooks/useRemoveBackgroundFeature.ts +137 -0
  102. package/src/features/remove-background/presentation/index.ts +5 -0
  103. package/src/features/remove-object/domain/index.ts +5 -0
  104. package/src/features/remove-object/domain/types/index.ts +14 -0
  105. package/src/features/remove-object/domain/types/remove-object.types.ts +77 -0
  106. package/src/features/remove-object/index.ts +27 -0
  107. package/src/features/remove-object/infrastructure/index.ts +5 -0
  108. package/src/features/remove-object/infrastructure/services/index.ts +6 -0
  109. package/src/features/remove-object/infrastructure/services/remove-object-executor.ts +99 -0
  110. package/src/features/remove-object/presentation/hooks/index.ts +9 -0
  111. package/src/features/remove-object/presentation/hooks/useRemoveObjectFeature.ts +168 -0
  112. package/src/features/remove-object/presentation/index.ts +5 -0
  113. package/src/features/text-to-image/domain/index.ts +1 -0
  114. package/src/features/text-to-image/domain/types/index.ts +10 -0
  115. package/src/features/text-to-image/domain/types/text-to-image.types.ts +66 -0
  116. package/src/features/text-to-image/index.ts +27 -1
  117. package/src/features/text-to-image/infrastructure/index.ts +1 -0
  118. package/src/features/text-to-image/infrastructure/services/index.ts +5 -0
  119. package/src/features/text-to-image/infrastructure/services/text-to-image-executor.ts +113 -0
  120. package/src/features/text-to-image/presentation/hooks/index.ts +5 -0
  121. package/src/features/text-to-image/presentation/hooks/useTextToImageFeature.ts +111 -0
  122. package/src/features/text-to-image/presentation/index.ts +1 -0
  123. package/src/features/text-to-video/domain/index.ts +1 -0
  124. package/src/features/text-to-video/domain/types/index.ts +10 -0
  125. package/src/features/text-to-video/domain/types/text-to-video.types.ts +65 -0
  126. package/src/features/text-to-video/index.ts +27 -1
  127. package/src/features/text-to-video/infrastructure/index.ts +1 -0
  128. package/src/features/text-to-video/infrastructure/services/index.ts +5 -0
  129. package/src/features/text-to-video/infrastructure/services/text-to-video-executor.ts +108 -0
  130. package/src/features/text-to-video/presentation/hooks/index.ts +5 -0
  131. package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +111 -0
  132. package/src/features/text-to-video/presentation/index.ts +1 -0
  133. package/src/features/text-to-voice/domain/index.ts +1 -0
  134. package/src/features/text-to-voice/domain/types/index.ts +10 -0
  135. package/src/features/text-to-voice/domain/types/text-to-voice.types.ts +65 -0
  136. package/src/features/text-to-voice/index.ts +27 -0
  137. package/src/features/text-to-voice/infrastructure/index.ts +1 -0
  138. package/src/features/text-to-voice/infrastructure/services/index.ts +5 -0
  139. package/src/features/text-to-voice/infrastructure/services/text-to-voice-executor.ts +111 -0
  140. package/src/features/text-to-voice/presentation/hooks/index.ts +5 -0
  141. package/src/features/text-to-voice/presentation/hooks/useTextToVoiceFeature.ts +105 -0
  142. package/src/features/text-to-voice/presentation/index.ts +1 -0
  143. package/src/features/upscaling/domain/types/index.ts +0 -1
  144. package/src/features/upscaling/domain/types/upscale.types.ts +14 -0
  145. package/src/features/upscaling/index.ts +3 -11
  146. package/src/features/upscaling/infrastructure/services/index.ts +1 -6
  147. package/src/features/upscaling/infrastructure/services/upscale-executor.ts +64 -30
  148. package/src/features/upscaling/presentation/hooks/useUpscaleFeature.ts +12 -7
  149. package/src/index.ts +63 -0
  150. package/src/features/face-swap/domain/entities.ts +0 -48
  151. package/src/features/photo-restoration/domain/types/provider.types.ts +0 -23
  152. package/src/features/photo-restoration/infrastructure/services/photo-restore-provider-registry.ts +0 -77
  153. package/src/features/text-to-image/domain/entities.ts +0 -58
  154. package/src/features/text-to-video/domain/entities.ts +0 -52
  155. package/src/features/upscaling/domain/types/provider.types.ts +0 -23
  156. package/src/features/upscaling/infrastructure/services/upscale-provider-registry.ts +0 -77
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Remove Background Executor
3
+ * Provider-agnostic background removal execution using active AI provider
4
+ * Model and input format are provided via options from app level
5
+ */
6
+
7
+ import { providerRegistry } from "../../../../infrastructure/services";
8
+ import { cleanBase64 } from "../../../../infrastructure/utils";
9
+ import type {
10
+ RemoveBackgroundRequest,
11
+ RemoveBackgroundResult,
12
+ RemoveBackgroundInputBuilder,
13
+ RemoveBackgroundResultExtractor,
14
+ } from "../../domain/types";
15
+
16
+ declare const __DEV__: boolean;
17
+
18
+ export interface ExecuteRemoveBackgroundOptions {
19
+ model: string;
20
+ buildInput: RemoveBackgroundInputBuilder;
21
+ extractResult?: RemoveBackgroundResultExtractor;
22
+ onProgress?: (progress: number) => void;
23
+ }
24
+
25
+ function defaultExtractResult(result: unknown): string | undefined {
26
+ if (typeof result !== "object" || result === null) return undefined;
27
+
28
+ const r = result as Record<string, unknown>;
29
+
30
+ if (typeof r.image === "string") return r.image;
31
+ if (Array.isArray(r.images) && r.images[0]?.url) return r.images[0].url;
32
+
33
+ return undefined;
34
+ }
35
+
36
+ export async function executeRemoveBackground(
37
+ request: RemoveBackgroundRequest,
38
+ options: ExecuteRemoveBackgroundOptions,
39
+ ): Promise<RemoveBackgroundResult> {
40
+ const provider = providerRegistry.getActiveProvider();
41
+
42
+ if (!provider) {
43
+ return { success: false, error: "No AI provider configured" };
44
+ }
45
+
46
+ if (!provider.isInitialized()) {
47
+ return { success: false, error: "AI provider not initialized" };
48
+ }
49
+
50
+ if (!request.imageBase64) {
51
+ return { success: false, error: "Image base64 is required" };
52
+ }
53
+
54
+ const { model, buildInput, extractResult, onProgress } = options;
55
+
56
+ if (__DEV__) {
57
+ // eslint-disable-next-line no-console
58
+ console.log(`[RemoveBackground] Provider: ${provider.providerId}, Model: ${model}`);
59
+ }
60
+
61
+ try {
62
+ onProgress?.(10);
63
+
64
+ const base64 = cleanBase64(request.imageBase64);
65
+ onProgress?.(30);
66
+
67
+ const input = buildInput(base64, request.options);
68
+ onProgress?.(40);
69
+
70
+ const result = await provider.run(model, input);
71
+ onProgress?.(90);
72
+
73
+ const extractor = extractResult || defaultExtractResult;
74
+ const imageUrl = extractor(result);
75
+ onProgress?.(100);
76
+
77
+ if (!imageUrl) {
78
+ return { success: false, error: "No image in response" };
79
+ }
80
+
81
+ return { success: true, imageUrl };
82
+ } catch (error) {
83
+ const message = error instanceof Error ? error.message : String(error);
84
+ if (__DEV__) {
85
+ // eslint-disable-next-line no-console
86
+ console.error("[RemoveBackground] Error:", message);
87
+ }
88
+ return { success: false, error: message };
89
+ }
90
+ }
91
+
92
+ export function hasRemoveBackgroundSupport(): boolean {
93
+ const provider = providerRegistry.getActiveProvider();
94
+ return provider !== null && provider.isInitialized();
95
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Remove Background Presentation Hooks Index
3
+ */
4
+
5
+ export { useRemoveBackgroundFeature } from "./useRemoveBackgroundFeature";
6
+ export type {
7
+ UseRemoveBackgroundFeatureProps,
8
+ UseRemoveBackgroundFeatureReturn,
9
+ } from "./useRemoveBackgroundFeature";
@@ -0,0 +1,137 @@
1
+ /**
2
+ * useRemoveBackgroundFeature Hook
3
+ * Manages remove background feature state and actions
4
+ */
5
+
6
+ import { useState, useCallback } from "react";
7
+ import { executeRemoveBackground } from "../../infrastructure/services";
8
+ import type {
9
+ RemoveBackgroundFeatureState,
10
+ RemoveBackgroundFeatureConfig,
11
+ RemoveBackgroundResult,
12
+ } from "../../domain/types";
13
+
14
+ declare const __DEV__: boolean;
15
+
16
+ export interface UseRemoveBackgroundFeatureProps {
17
+ config: RemoveBackgroundFeatureConfig;
18
+ userId: string;
19
+ onSelectImage: () => Promise<string | null>;
20
+ onSaveImage: (imageUrl: string) => Promise<void>;
21
+ }
22
+
23
+ export interface UseRemoveBackgroundFeatureReturn extends RemoveBackgroundFeatureState {
24
+ selectImage: () => Promise<void>;
25
+ process: () => Promise<void>;
26
+ save: () => Promise<void>;
27
+ reset: () => void;
28
+ }
29
+
30
+ const initialState: RemoveBackgroundFeatureState = {
31
+ imageUri: null,
32
+ processedUrl: null,
33
+ isProcessing: false,
34
+ progress: 0,
35
+ error: null,
36
+ };
37
+
38
+ export function useRemoveBackgroundFeature(
39
+ props: UseRemoveBackgroundFeatureProps,
40
+ ): UseRemoveBackgroundFeatureReturn {
41
+ const { config, userId, onSelectImage, onSaveImage } = props;
42
+ const [state, setState] = useState<RemoveBackgroundFeatureState>(initialState);
43
+
44
+ const selectImage = useCallback(async () => {
45
+ try {
46
+ const uri = await onSelectImage();
47
+ if (uri) {
48
+ setState((prev) => ({ ...prev, imageUri: uri, error: null }));
49
+ config.onImageSelect?.(uri);
50
+ }
51
+ } catch (error) {
52
+ const message = error instanceof Error ? error.message : String(error);
53
+ setState((prev) => ({ ...prev, error: message }));
54
+ }
55
+ }, [onSelectImage, config]);
56
+
57
+ const handleProgress = useCallback((progress: number) => {
58
+ setState((prev) => ({ ...prev, progress }));
59
+ }, []);
60
+
61
+ const process = useCallback(async () => {
62
+ if (!state.imageUri) return;
63
+
64
+ setState((prev) => ({
65
+ ...prev,
66
+ isProcessing: true,
67
+ progress: 0,
68
+ error: null,
69
+ }));
70
+
71
+ config.onProcessingStart?.();
72
+
73
+ if (__DEV__) {
74
+ // eslint-disable-next-line no-console
75
+ console.log("[useRemoveBackgroundFeature] Starting background removal process");
76
+ }
77
+
78
+ const imageBase64 = await config.prepareImage(state.imageUri);
79
+
80
+ const result: RemoveBackgroundResult = await executeRemoveBackground(
81
+ {
82
+ imageUri: state.imageUri,
83
+ imageBase64,
84
+ userId,
85
+ },
86
+ {
87
+ model: config.model,
88
+ buildInput: config.buildInput,
89
+ extractResult: config.extractResult,
90
+ onProgress: handleProgress,
91
+ },
92
+ );
93
+
94
+ if (result.success && result.imageUrl) {
95
+ const url = result.imageUrl;
96
+ setState((prev) => ({
97
+ ...prev,
98
+ isProcessing: false,
99
+ processedUrl: url,
100
+ progress: 100,
101
+ }));
102
+ config.onProcessingComplete?.(result);
103
+ } else {
104
+ const errorMessage = result.error || "Processing failed";
105
+ setState((prev) => ({
106
+ ...prev,
107
+ isProcessing: false,
108
+ error: errorMessage,
109
+ progress: 0,
110
+ }));
111
+ config.onError?.(errorMessage);
112
+ }
113
+ }, [state.imageUri, userId, config, handleProgress]);
114
+
115
+ const save = useCallback(async () => {
116
+ if (!state.processedUrl) return;
117
+
118
+ try {
119
+ await onSaveImage(state.processedUrl);
120
+ } catch (error) {
121
+ const message = error instanceof Error ? error.message : String(error);
122
+ setState((prev) => ({ ...prev, error: message }));
123
+ }
124
+ }, [state.processedUrl, onSaveImage]);
125
+
126
+ const reset = useCallback(() => {
127
+ setState(initialState);
128
+ }, []);
129
+
130
+ return {
131
+ ...state,
132
+ selectImage,
133
+ process,
134
+ save,
135
+ reset,
136
+ };
137
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Remove Background Presentation Index
3
+ */
4
+
5
+ export * from "./hooks";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Remove Object Domain Index
3
+ */
4
+
5
+ export * from "./types";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Remove Object Domain Types Index
3
+ */
4
+
5
+ export type {
6
+ RemoveObjectOptions,
7
+ RemoveObjectRequest,
8
+ RemoveObjectResult,
9
+ RemoveObjectFeatureState,
10
+ RemoveObjectTranslations,
11
+ RemoveObjectInputBuilder,
12
+ RemoveObjectResultExtractor,
13
+ RemoveObjectFeatureConfig,
14
+ } from "./remove-object.types";
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Remove Object Feature Types
3
+ * Request, Result, Config types for object removal (inpainting)
4
+ */
5
+
6
+ export interface RemoveObjectOptions {
7
+ prompt?: string;
8
+ maskBase64?: string;
9
+ fillBackground?: boolean;
10
+ }
11
+
12
+ export interface RemoveObjectRequest {
13
+ imageUri: string;
14
+ imageBase64?: string;
15
+ maskBase64?: string;
16
+ prompt?: string;
17
+ userId: string;
18
+ options?: RemoveObjectOptions;
19
+ }
20
+
21
+ export interface RemoveObjectResult {
22
+ success: boolean;
23
+ imageUrl?: string;
24
+ imageBase64?: string;
25
+ error?: string;
26
+ requestId?: string;
27
+ }
28
+
29
+ export interface RemoveObjectFeatureState {
30
+ imageUri: string | null;
31
+ maskUri: string | null;
32
+ prompt: string;
33
+ processedUrl: string | null;
34
+ isProcessing: boolean;
35
+ progress: number;
36
+ error: string | null;
37
+ }
38
+
39
+ export interface RemoveObjectTranslations {
40
+ uploadTitle: string;
41
+ uploadSubtitle: string;
42
+ uploadChange: string;
43
+ uploadAnalyzing: string;
44
+ maskTitle: string;
45
+ maskSubtitle: string;
46
+ promptPlaceholder: string;
47
+ description: string;
48
+ processingText: string;
49
+ processButtonText: string;
50
+ successText: string;
51
+ saveButtonText: string;
52
+ tryAnotherText: string;
53
+ beforeLabel?: string;
54
+ afterLabel?: string;
55
+ compareHint?: string;
56
+ }
57
+
58
+ export type RemoveObjectInputBuilder = (
59
+ base64: string,
60
+ options?: RemoveObjectOptions,
61
+ ) => Record<string, unknown>;
62
+
63
+ export type RemoveObjectResultExtractor = (result: unknown) => string | undefined;
64
+
65
+ export interface RemoveObjectFeatureConfig {
66
+ providerId?: string;
67
+ creditCost?: number;
68
+ model: string;
69
+ buildInput: RemoveObjectInputBuilder;
70
+ extractResult?: RemoveObjectResultExtractor;
71
+ prepareImage: (imageUri: string) => Promise<string>;
72
+ onImageSelect?: (uri: string) => void;
73
+ onMaskSelect?: (uri: string) => void;
74
+ onProcessingStart?: () => void;
75
+ onProcessingComplete?: (result: RemoveObjectResult) => void;
76
+ onError?: (error: string) => void;
77
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Remove Object Feature
3
+ * Provider-agnostic object removal (inpainting) feature
4
+ */
5
+
6
+ // Domain Types
7
+ export type {
8
+ RemoveObjectOptions,
9
+ RemoveObjectRequest,
10
+ RemoveObjectResult,
11
+ RemoveObjectFeatureState,
12
+ RemoveObjectTranslations,
13
+ RemoveObjectFeatureConfig,
14
+ RemoveObjectInputBuilder,
15
+ RemoveObjectResultExtractor,
16
+ } from "./domain";
17
+
18
+ // Infrastructure Services
19
+ export { executeRemoveObject, hasRemoveObjectSupport } from "./infrastructure";
20
+ export type { ExecuteRemoveObjectOptions } from "./infrastructure";
21
+
22
+ // Presentation Hooks
23
+ export { useRemoveObjectFeature } from "./presentation";
24
+ export type {
25
+ UseRemoveObjectFeatureProps,
26
+ UseRemoveObjectFeatureReturn,
27
+ } from "./presentation";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Remove Object Infrastructure Index
3
+ */
4
+
5
+ export * from "./services";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Remove Object Infrastructure Services Index
3
+ */
4
+
5
+ export { executeRemoveObject, hasRemoveObjectSupport } from "./remove-object-executor";
6
+ export type { ExecuteRemoveObjectOptions } from "./remove-object-executor";
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Remove Object Executor
3
+ * Provider-agnostic object removal execution using active AI provider
4
+ * Model and input format are provided via options from app level
5
+ */
6
+
7
+ import { providerRegistry } from "../../../../infrastructure/services";
8
+ import { cleanBase64 } from "../../../../infrastructure/utils";
9
+ import type {
10
+ RemoveObjectRequest,
11
+ RemoveObjectResult,
12
+ RemoveObjectInputBuilder,
13
+ RemoveObjectResultExtractor,
14
+ } from "../../domain/types";
15
+
16
+ declare const __DEV__: boolean;
17
+
18
+ export interface ExecuteRemoveObjectOptions {
19
+ model: string;
20
+ buildInput: RemoveObjectInputBuilder;
21
+ extractResult?: RemoveObjectResultExtractor;
22
+ onProgress?: (progress: number) => void;
23
+ }
24
+
25
+ function defaultExtractResult(result: unknown): string | undefined {
26
+ if (typeof result !== "object" || result === null) return undefined;
27
+
28
+ const r = result as Record<string, unknown>;
29
+
30
+ if (typeof r.image === "string") return r.image;
31
+ if (Array.isArray(r.images) && r.images[0]?.url) return r.images[0].url;
32
+
33
+ return undefined;
34
+ }
35
+
36
+ export async function executeRemoveObject(
37
+ request: RemoveObjectRequest,
38
+ options: ExecuteRemoveObjectOptions,
39
+ ): Promise<RemoveObjectResult> {
40
+ const provider = providerRegistry.getActiveProvider();
41
+
42
+ if (!provider) {
43
+ return { success: false, error: "No AI provider configured" };
44
+ }
45
+
46
+ if (!provider.isInitialized()) {
47
+ return { success: false, error: "AI provider not initialized" };
48
+ }
49
+
50
+ if (!request.imageBase64) {
51
+ return { success: false, error: "Image base64 is required" };
52
+ }
53
+
54
+ const { model, buildInput, extractResult, onProgress } = options;
55
+
56
+ if (__DEV__) {
57
+ // eslint-disable-next-line no-console
58
+ console.log(`[RemoveObject] Provider: ${provider.providerId}, Model: ${model}`);
59
+ }
60
+
61
+ try {
62
+ onProgress?.(10);
63
+
64
+ const base64 = cleanBase64(request.imageBase64);
65
+ onProgress?.(30);
66
+
67
+ const input = buildInput(base64, {
68
+ maskBase64: request.maskBase64,
69
+ prompt: request.prompt,
70
+ ...request.options,
71
+ });
72
+ onProgress?.(40);
73
+
74
+ const result = await provider.run(model, input);
75
+ onProgress?.(90);
76
+
77
+ const extractor = extractResult || defaultExtractResult;
78
+ const imageUrl = extractor(result);
79
+ onProgress?.(100);
80
+
81
+ if (!imageUrl) {
82
+ return { success: false, error: "No image in response" };
83
+ }
84
+
85
+ return { success: true, imageUrl };
86
+ } catch (error) {
87
+ const message = error instanceof Error ? error.message : String(error);
88
+ if (__DEV__) {
89
+ // eslint-disable-next-line no-console
90
+ console.error("[RemoveObject] Error:", message);
91
+ }
92
+ return { success: false, error: message };
93
+ }
94
+ }
95
+
96
+ export function hasRemoveObjectSupport(): boolean {
97
+ const provider = providerRegistry.getActiveProvider();
98
+ return provider !== null && provider.isInitialized();
99
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Remove Object Presentation Hooks Index
3
+ */
4
+
5
+ export { useRemoveObjectFeature } from "./useRemoveObjectFeature";
6
+ export type {
7
+ UseRemoveObjectFeatureProps,
8
+ UseRemoveObjectFeatureReturn,
9
+ } from "./useRemoveObjectFeature";
@@ -0,0 +1,168 @@
1
+ /**
2
+ * useRemoveObjectFeature Hook
3
+ * Manages remove object feature state and actions
4
+ */
5
+
6
+ import { useState, useCallback } from "react";
7
+ import { executeRemoveObject } from "../../infrastructure/services";
8
+ import type {
9
+ RemoveObjectFeatureState,
10
+ RemoveObjectFeatureConfig,
11
+ RemoveObjectResult,
12
+ } from "../../domain/types";
13
+
14
+ declare const __DEV__: boolean;
15
+
16
+ export interface UseRemoveObjectFeatureProps {
17
+ config: RemoveObjectFeatureConfig;
18
+ userId: string;
19
+ onSelectImage: () => Promise<string | null>;
20
+ onSelectMask?: () => Promise<string | null>;
21
+ onSaveImage: (imageUrl: string) => Promise<void>;
22
+ }
23
+
24
+ export interface UseRemoveObjectFeatureReturn extends RemoveObjectFeatureState {
25
+ selectImage: () => Promise<void>;
26
+ selectMask: () => Promise<void>;
27
+ setPrompt: (prompt: string) => void;
28
+ process: () => Promise<void>;
29
+ save: () => Promise<void>;
30
+ reset: () => void;
31
+ }
32
+
33
+ const initialState: RemoveObjectFeatureState = {
34
+ imageUri: null,
35
+ maskUri: null,
36
+ prompt: "",
37
+ processedUrl: null,
38
+ isProcessing: false,
39
+ progress: 0,
40
+ error: null,
41
+ };
42
+
43
+ export function useRemoveObjectFeature(
44
+ props: UseRemoveObjectFeatureProps,
45
+ ): UseRemoveObjectFeatureReturn {
46
+ const { config, userId, onSelectImage, onSelectMask, onSaveImage } = props;
47
+ const [state, setState] = useState<RemoveObjectFeatureState>(initialState);
48
+
49
+ const selectImage = useCallback(async () => {
50
+ try {
51
+ const uri = await onSelectImage();
52
+ if (uri) {
53
+ setState((prev) => ({ ...prev, imageUri: uri, error: null }));
54
+ config.onImageSelect?.(uri);
55
+ }
56
+ } catch (error) {
57
+ const message = error instanceof Error ? error.message : String(error);
58
+ setState((prev) => ({ ...prev, error: message }));
59
+ }
60
+ }, [onSelectImage, config]);
61
+
62
+ const selectMask = useCallback(async () => {
63
+ if (!onSelectMask) return;
64
+
65
+ try {
66
+ const uri = await onSelectMask();
67
+ if (uri) {
68
+ setState((prev) => ({ ...prev, maskUri: uri, error: null }));
69
+ config.onMaskSelect?.(uri);
70
+ }
71
+ } catch (error) {
72
+ const message = error instanceof Error ? error.message : String(error);
73
+ setState((prev) => ({ ...prev, error: message }));
74
+ }
75
+ }, [onSelectMask, config]);
76
+
77
+ const setPrompt = useCallback((prompt: string) => {
78
+ setState((prev) => ({ ...prev, prompt }));
79
+ }, []);
80
+
81
+ const handleProgress = useCallback((progress: number) => {
82
+ setState((prev) => ({ ...prev, progress }));
83
+ }, []);
84
+
85
+ const process = useCallback(async () => {
86
+ if (!state.imageUri) return;
87
+
88
+ setState((prev) => ({
89
+ ...prev,
90
+ isProcessing: true,
91
+ progress: 0,
92
+ error: null,
93
+ }));
94
+
95
+ config.onProcessingStart?.();
96
+
97
+ if (__DEV__) {
98
+ // eslint-disable-next-line no-console
99
+ console.log("[useRemoveObjectFeature] Starting object removal process");
100
+ }
101
+
102
+ const imageBase64 = await config.prepareImage(state.imageUri);
103
+ const maskBase64 = state.maskUri
104
+ ? await config.prepareImage(state.maskUri)
105
+ : undefined;
106
+
107
+ const result: RemoveObjectResult = await executeRemoveObject(
108
+ {
109
+ imageUri: state.imageUri,
110
+ imageBase64,
111
+ maskBase64,
112
+ prompt: state.prompt || undefined,
113
+ userId,
114
+ },
115
+ {
116
+ model: config.model,
117
+ buildInput: config.buildInput,
118
+ extractResult: config.extractResult,
119
+ onProgress: handleProgress,
120
+ },
121
+ );
122
+
123
+ if (result.success && result.imageUrl) {
124
+ const url = result.imageUrl;
125
+ setState((prev) => ({
126
+ ...prev,
127
+ isProcessing: false,
128
+ processedUrl: url,
129
+ progress: 100,
130
+ }));
131
+ config.onProcessingComplete?.(result);
132
+ } else {
133
+ const errorMessage = result.error || "Processing failed";
134
+ setState((prev) => ({
135
+ ...prev,
136
+ isProcessing: false,
137
+ error: errorMessage,
138
+ progress: 0,
139
+ }));
140
+ config.onError?.(errorMessage);
141
+ }
142
+ }, [state.imageUri, state.maskUri, state.prompt, userId, config, handleProgress]);
143
+
144
+ const save = useCallback(async () => {
145
+ if (!state.processedUrl) return;
146
+
147
+ try {
148
+ await onSaveImage(state.processedUrl);
149
+ } catch (error) {
150
+ const message = error instanceof Error ? error.message : String(error);
151
+ setState((prev) => ({ ...prev, error: message }));
152
+ }
153
+ }, [state.processedUrl, onSaveImage]);
154
+
155
+ const reset = useCallback(() => {
156
+ setState(initialState);
157
+ }, []);
158
+
159
+ return {
160
+ ...state,
161
+ selectImage,
162
+ selectMask,
163
+ setPrompt,
164
+ process,
165
+ save,
166
+ reset,
167
+ };
168
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Remove Object Presentation Index
3
+ */
4
+
5
+ export * from "./hooks";
@@ -0,0 +1 @@
1
+ export * from "./types";
@@ -0,0 +1,10 @@
1
+ export type {
2
+ TextToImageOptions,
3
+ TextToImageRequest,
4
+ TextToImageResult,
5
+ TextToImageFeatureState,
6
+ TextToImageTranslations,
7
+ TextToImageInputBuilder,
8
+ TextToImageResultExtractor,
9
+ TextToImageFeatureConfig,
10
+ } from "./text-to-image.types";