@umituz/react-native-ai-generation-content 1.90.2 → 1.90.3

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 (152) hide show
  1. package/package.json +1 -1
  2. package/src/domain/interfaces/app-services-auth.interface.ts +27 -0
  3. package/src/domain/interfaces/app-services-composite.interface.ts +29 -0
  4. package/src/domain/interfaces/app-services-optional.interface.ts +42 -0
  5. package/src/domain/interfaces/app-services.interface.ts +0 -79
  6. package/src/domains/background/infrastructure/services/job-poller-index.ts +7 -0
  7. package/src/domains/background/infrastructure/services/job-poller-utils.ts +130 -0
  8. package/src/domains/background/infrastructure/utils/polling-interval.util.ts +1 -1
  9. package/src/domains/background/presentation/hooks/use-background-generation.ts +1 -1
  10. package/src/domains/content-moderation/infrastructure/services/content-moderation.service.ts +1 -1
  11. package/src/domains/content-moderation/infrastructure/services/moderators/image.moderator.ts +34 -8
  12. package/src/domains/content-moderation/infrastructure/services/moderators/text.moderator.ts +15 -4
  13. package/src/domains/content-moderation/infrastructure/services/moderators/video.moderator.ts +34 -8
  14. package/src/domains/content-moderation/infrastructure/services/moderators/voice.moderator.ts +19 -8
  15. package/src/domains/creations/domain/types/creation-categories.constants.ts +57 -0
  16. package/src/domains/creations/domain/types/creation-categories.helpers.ts +67 -0
  17. package/src/domains/creations/domain/types/creation-categories.ts +5 -111
  18. package/src/domains/creations/presentation/hooks/creation-validators.ts +31 -29
  19. package/src/domains/creations/presentation/hooks/job-poller-index.ts +10 -0
  20. package/src/domains/creations/presentation/hooks/job-poller-utils.filters.ts +34 -0
  21. package/src/domains/creations/presentation/hooks/job-poller-utils.logger.ts +76 -0
  22. package/src/domains/creations/presentation/hooks/job-poller-utils.stale-handlers.ts +52 -0
  23. package/src/domains/creations/presentation/hooks/job-poller-utils.ts +8 -0
  24. package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +1 -1
  25. package/src/domains/creations/presentation-exports.ts +2 -2
  26. package/src/domains/face-detection/domain/entities/FaceDetection.ts +4 -3
  27. package/src/domains/face-detection/presentation/hooks/useFaceDetection.ts +24 -21
  28. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-preparation.ts +58 -0
  29. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-prompt.ts +69 -0
  30. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-resolution.ts +77 -0
  31. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple.ts +54 -0
  32. package/src/domains/generation/infrastructure/couple-generation-builder/builder-index.ts +8 -0
  33. package/src/domains/generation/infrastructure/couple-generation-builder/builder-scenario.ts +113 -0
  34. package/src/domains/generation/infrastructure/couple-generation-builder/builder.ts +7 -0
  35. package/src/domains/generation/infrastructure/couple-generation-builder/index.ts +20 -0
  36. package/src/domains/generation/infrastructure/couple-generation-builder/types.ts +44 -0
  37. package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-end-logger.ts +18 -0
  38. package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-start-logger.ts +57 -0
  39. package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-step-logger.ts +106 -0
  40. package/src/domains/generation/infrastructure/couple-generation-builder/utils/index.ts +8 -0
  41. package/src/domains/generation/infrastructure/couple-generation-builder/utils/types.ts +49 -0
  42. package/src/domains/generation/infrastructure/couple-generation-builder/utils.ts +8 -0
  43. package/src/domains/generation/infrastructure/flow/flow-store-actions.ts +105 -0
  44. package/src/domains/generation/infrastructure/flow/flow-store-initial-state.ts +26 -0
  45. package/src/domains/generation/infrastructure/flow/useFlowStore.ts +4 -116
  46. package/src/domains/generation/presentation/useAIGeneration.hook.ts +1 -1
  47. package/src/domains/generation/wizard/infrastructure/strategies/image-generation-strategy-index.ts +7 -0
  48. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.ts +2 -12
  49. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.types.ts +11 -0
  50. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.utils.ts +12 -0
  51. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +1 -220
  52. package/src/domains/generation/wizard/infrastructure/strategies/image-input-builder.ts +66 -0
  53. package/src/domains/generation/wizard/infrastructure/strategies/image-input-extraction.ts +88 -0
  54. package/src/domains/generation/wizard/infrastructure/strategies/image-input-prompt-builder.ts +75 -0
  55. package/src/domains/generation/wizard/infrastructure/strategies/image-input-style-enhancements.ts +35 -0
  56. package/src/domains/generation/wizard/infrastructure/strategies/image-strategy-factory.ts +42 -0
  57. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor-index.ts +11 -0
  58. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor.ts +76 -0
  59. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-input-builder.ts +46 -0
  60. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-result-types.ts +17 -0
  61. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-submission.ts +62 -0
  62. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.audio-extractor.ts +27 -0
  63. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.executor.ts +2 -175
  64. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.input-builder.ts +90 -0
  65. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +3 -108
  66. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.types.ts +0 -129
  67. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.validation.ts +136 -0
  68. package/src/domains/generation/wizard/presentation/hooks/photo-upload/index.ts +39 -0
  69. package/src/domains/generation/wizard/presentation/hooks/photo-upload/types.ts +37 -0
  70. package/src/domains/generation/wizard/presentation/hooks/photo-upload/usePhotoUploadStateLogic.ts +142 -0
  71. package/src/domains/generation/wizard/presentation/hooks/use-video-queue-utils.ts +103 -0
  72. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.handlers.ts +97 -0
  73. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.saver.ts +54 -0
  74. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.ts +22 -87
  75. package/src/domains/generation/wizard/presentation/hooks/usePhotoUploadState.ts +8 -177
  76. package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +1 -295
  77. package/src/domains/generation/wizard/presentation/hooks/useWizardGeneration.ts +1 -1
  78. package/src/domains/generation/wizard/presentation/hooks/video-queue/index.ts +82 -0
  79. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationCallbacks.ts +120 -0
  80. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationPolling.ts +76 -0
  81. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationRefs.ts +65 -0
  82. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationStart.ts +123 -0
  83. package/src/domains/generation/wizard/presentation/hooks/video-queue-index.ts +9 -0
  84. package/src/domains/image-to-video/domain/types/image-to-video-state.types.ts +11 -4
  85. package/src/domains/text-to-image/domain/types/text-to-image.types.ts +44 -22
  86. package/src/domains/text-to-video/domain/types/request.types.ts +33 -9
  87. package/src/domains/text-to-video/domain/types/state.types.ts +29 -9
  88. package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.handlers.ts +44 -0
  89. package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.ts +5 -51
  90. package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.types.ts +33 -0
  91. package/src/infrastructure/services/generation-orchestrator.service.ts +2 -2
  92. package/src/infrastructure/utils/couple-input-context.ts +13 -0
  93. package/src/infrastructure/utils/couple-input-index.ts +8 -0
  94. package/src/infrastructure/utils/couple-input-refiner.ts +101 -0
  95. package/src/infrastructure/utils/couple-input-resolver.ts +71 -0
  96. package/src/infrastructure/utils/couple-input-types.ts +14 -0
  97. package/src/infrastructure/utils/couple-input.util.ts +3 -176
  98. package/src/infrastructure/utils/photo-generation/photo-preparation.util.ts +1 -1
  99. package/src/infrastructure/validation/base-validator.ts +1 -27
  100. package/src/infrastructure/validation/base-validator.types.ts +32 -0
  101. package/src/presentation/hooks/generation/index.ts +1 -1
  102. package/src/presentation/hooks/generation/orchestrator-abort-logs.ts +48 -0
  103. package/src/presentation/hooks/generation/orchestrator-execution-logs.ts +67 -0
  104. package/src/presentation/hooks/generation/orchestrator-index.ts +14 -0
  105. package/src/presentation/hooks/generation/orchestrator-start-logs.ts +65 -0
  106. package/src/presentation/hooks/generation/orchestrator-state-utils.ts +17 -0
  107. package/src/presentation/hooks/generation/orchestrator-types.ts +55 -0
  108. package/src/presentation/hooks/generation/orchestrator-utils-index.ts +29 -0
  109. package/src/presentation/hooks/generation/orchestrator-utils.ts +25 -0
  110. package/src/presentation/hooks/generation/useDualImageGeneration.ts +1 -1
  111. package/src/presentation/hooks/generation/useImageGeneration.ts +1 -1
  112. package/src/presentation/hooks/generation/useVideoGeneration.ts +1 -1
  113. package/src/shared/hooks/factories/generation-hook-index.ts +12 -0
  114. package/src/shared/hooks/factories/generation-hook-types.ts +47 -0
  115. package/src/shared/hooks/factories/generation-hook-utils.ts +94 -0
  116. package/src/shared/hooks/factories/index.ts +1 -1
  117. package/src/shared/index.ts +1 -1
  118. package/src/shared/utils/calculations/aspect-ratio-calculations.ts +30 -0
  119. package/src/shared/utils/calculations/base64-calculations.ts +26 -0
  120. package/src/shared/utils/calculations/confidence-calculations.ts +21 -0
  121. package/src/shared/utils/calculations/cost-calculations-index.ts +43 -0
  122. package/src/shared/utils/calculations/cost-calculations.ts +25 -0
  123. package/src/shared/utils/calculations/credit-calculations.ts +37 -0
  124. package/src/shared/utils/calculations/index.ts +46 -0
  125. package/src/shared/utils/calculations/math-utilities.ts +32 -0
  126. package/src/shared/utils/calculations/memory-calculations.ts +33 -0
  127. package/src/shared/utils/calculations/pagination-calculations.ts +38 -0
  128. package/src/shared/utils/calculations/percentage-calculations.ts +33 -0
  129. package/src/shared/utils/calculations/time-calculations.ts +99 -0
  130. package/src/shared/utils/credit.ts +1 -1
  131. package/src/shared-kernel/application/hooks/index.ts +8 -0
  132. package/src/shared-kernel/application/hooks/use-feature-state.ts +107 -0
  133. package/src/shared-kernel/application/hooks/use-generation-handler.ts +110 -0
  134. package/src/shared-kernel/base-types/base-callbacks.types.ts +73 -0
  135. package/src/shared-kernel/base-types/base-feature-state.types.ts +77 -0
  136. package/src/shared-kernel/base-types/base-generation.types.ts +69 -0
  137. package/src/shared-kernel/base-types/index.ts +30 -0
  138. package/src/shared-kernel/domain/base-generation-strategy.ts +146 -0
  139. package/src/shared-kernel/domain/index.ts +7 -0
  140. package/src/shared-kernel/index.ts +17 -0
  141. package/src/shared-kernel/infrastructure/validation/common-validators.ts +126 -0
  142. package/src/shared-kernel/infrastructure/validation/common-validators.types.ts +33 -0
  143. package/src/shared-kernel/infrastructure/validation/error-handler.ts +52 -0
  144. package/src/shared-kernel/infrastructure/validation/error-handler.types.ts +38 -0
  145. package/src/shared-kernel/infrastructure/validation/error-handler.utils.ts +79 -0
  146. package/src/shared-kernel/infrastructure/validation/index.ts +28 -0
  147. package/src/domains/background/infrastructure/services/job-poller.service.ts +0 -234
  148. package/src/domains/creations/presentation/hooks/useProcessingJobsPoller.ts +0 -256
  149. package/src/domains/generation/infrastructure/couple-generation-builder.ts +0 -374
  150. package/src/presentation/hooks/generation/orchestrator.ts +0 -276
  151. package/src/shared/hooks/factories/createGenerationHook.ts +0 -253
  152. package/src/shared/utils/calculations.util.ts +0 -366
@@ -1,374 +0,0 @@
1
- /**
2
- * Couple Image Generation Builder
3
- *
4
- * Wardrobe'da kusursuz çalışan mantığı tüm couple generation için paylaştırır.
5
- * Bu utility'yi tüm çift görüntü oluşturma işlemleri kullanır.
6
- *
7
- * Kullanım alanları:
8
- * - Senaryo generation (Home couple images)
9
- * - Wardrobe generation
10
- * - Background generation
11
- * - Art style generation
12
- * - Mood filter generation
13
- */
14
-
15
- import {
16
- resolveCoupleInput,
17
- prependContext,
18
- refinePromptForCouple,
19
- } from "../../../infrastructure/utils/couple-input.util";
20
- import type { GenerationTargetLike } from "../../../infrastructure/utils/couple-input.util";
21
- import { createPhotorealisticPrompt } from "../../prompts";
22
- import { getAppearanceContext } from "./appearance-analysis";
23
-
24
- /**
25
- * Couple generation input parameters
26
- */
27
- export interface CoupleGenerationInputParams {
28
- // Required params
29
- partner1PhotoUri: string;
30
- partner2PhotoUri: string | null;
31
- isCoupleMode: boolean;
32
- basePrompt: string; // Scenario prompt, wardrobe prompt, background prompt, etc.
33
-
34
- // Optional params
35
- customInstructions?: string;
36
- aspectRatio?: string; // Default: "3:4"
37
- strength?: number; // Optional strength for some operations
38
- }
39
-
40
- /**
41
- * Couple generation result
42
- */
43
- export interface CoupleGenerationInput {
44
- target: GenerationTargetLike;
45
- prompt: string;
46
- params: Record<string, unknown>;
47
- }
48
-
49
- /**
50
- * Scenario generation input parameters
51
- */
52
- export interface ScenarioGenerationInputParams {
53
- partner1PhotoUri: string;
54
- partner2PhotoUri: string | null;
55
- isCoupleMode: boolean;
56
- scenarioPrompt: string; // Senaryo prompt'u (aiPrompt)
57
- customInstructions?: string;
58
- }
59
-
60
- /**
61
- * Merkezi couple generation input builder
62
- *
63
- * Wardrobe mantığını tüm couple generation için paylaştırır:
64
- * 1. Appearance analysis (fotoğrafları analiz et)
65
- * 2. Couple refinement (çift modu için iyileştir)
66
- * 3. Context prepending (context'i prompt'a ekle)
67
- * 4. Photorealistic prompt creation
68
- * 5. Couple input resolution (doğru target ve image'lar)
69
- *
70
- * @param params - Generation parameters
71
- * @returns Generation input with target, prompt, and params
72
- */
73
- export async function buildCoupleGenerationInput(
74
- params: CoupleGenerationInputParams,
75
- ): Promise<CoupleGenerationInput> {
76
- const DEV = typeof __DEV__ !== "undefined" && __DEV__;
77
-
78
- const {
79
- partner1PhotoUri,
80
- partner2PhotoUri,
81
- isCoupleMode,
82
- basePrompt,
83
- customInstructions,
84
- aspectRatio = "3:4", // Standard portrait ratio like Wardrobe
85
- strength,
86
- } = params;
87
-
88
- if (DEV) {
89
- console.log("[CoupleBuilder] ========================================");
90
- console.log("[CoupleBuilder] ===== BUILD COUPLE GENERATION START =====");
91
- console.log("[CoupleBuilder] ========================================");
92
- console.log("[CoupleBuilder] ===== INPUT PARAMS =====");
93
- console.log("[CoupleBuilder] Is couple mode:", isCoupleMode);
94
- console.log("[CoupleBuilder] Base prompt length:", basePrompt.length);
95
- console.log("[CoupleBuilder] Base prompt preview:", basePrompt.substring(0, 200) + "...");
96
- console.log("[CoupleBuilder] Aspect ratio:", aspectRatio);
97
- console.log("[CoupleBuilder] Has partner 2:", !!partner2PhotoUri);
98
- console.log("[CoupleBuilder] Has custom instructions:", !!customInstructions);
99
- console.log("[CoupleBuilder] Has strength:", strength !== undefined);
100
- if (strength !== undefined) {
101
- console.log("[CoupleBuilder] Strength value:", strength);
102
- }
103
- console.log("[CoupleBuilder] Partner 1 URI:", partner1PhotoUri.substring(0, 80) + "...");
104
- if (partner2PhotoUri) {
105
- console.log("[CoupleBuilder] Partner 2 URI:", partner2PhotoUri.substring(0, 80) + "...");
106
- }
107
- }
108
-
109
- // 1. GET PHOTO URIs - Couple mode kontrolü
110
- const photoUris =
111
- isCoupleMode && partner2PhotoUri
112
- ? [partner1PhotoUri, partner2PhotoUri]
113
- : [partner1PhotoUri];
114
-
115
- if (DEV) {
116
- console.log("[CoupleBuilder] ===== STEP 1: PHOTO URIs =====");
117
- console.log("[CoupleBuilder] Photo URIs count:", photoUris.length);
118
- console.log("[CoupleBuilder] Photo 1:", photoUris[0].substring(0, 60) + "...");
119
- if (photoUris.length > 1) {
120
- console.log("[CoupleBuilder] Photo 2:", photoUris[1].substring(0, 60) + "...");
121
- }
122
- }
123
-
124
- // 2. ANALYZE APPEARANCE - Wardrobe'daki gibi
125
- // Fotoğrafları analiz et ve context çıkar
126
- if (DEV) {
127
- console.log("[CoupleBuilder] ===== STEP 2: APPEARANCE ANALYSIS =====");
128
- console.log("[CoupleBuilder] Calling getAppearanceContext with:", {
129
- photoCount: photoUris.length,
130
- isCoupleMode
131
- });
132
- }
133
-
134
- const appearanceContext = await getAppearanceContext(
135
- photoUris,
136
- isCoupleMode,
137
- );
138
-
139
- if (DEV) {
140
- console.log("[CoupleBuilder] Appearance context length:", appearanceContext.length);
141
- if (appearanceContext.length > 0) {
142
- console.log("[CoupleBuilder] Appearance context preview:", appearanceContext.substring(0, 150) + "...");
143
- } else {
144
- console.log("[CoupleBuilder] ℹ️ No appearance context returned (vision disabled)");
145
- }
146
- }
147
-
148
- // 3. REFINE FOR COUPLE + PREPEND CONTEXT - Wardrobe mantığı
149
- // Coupler modu için prompt'u iyileştir ve context'i ekle
150
- if (DEV) {
151
- console.log("[CoupleBuilder] ===== STEP 3: REFINE & PREPEND CONTEXT =====");
152
- console.log("[CoupleBuilder] Calling refinePromptForCouple with:", {
153
- basePromptLength: basePrompt.length,
154
- isCoupleMode
155
- });
156
- }
157
-
158
- const refinedPrompt = prependContext(
159
- refinePromptForCouple(basePrompt, isCoupleMode),
160
- appearanceContext,
161
- );
162
-
163
- if (DEV) {
164
- console.log("[CoupleBuilder] After refinePromptForCouple + prependContext:");
165
- console.log("[CoupleBuilder] Refined prompt length:", refinedPrompt.length);
166
- console.log("[CoupleBuilder] Refined prompt preview:", refinedPrompt.substring(0, 300) + "...");
167
- }
168
-
169
- // 4. CREATE FINAL PROMPT - Photorealistic
170
- if (DEV) {
171
- console.log("[CoupleBuilder] ===== STEP 4: CREATE PHOTOREALISTIC PROMPT =====");
172
- console.log("[CoupleBuilder] Calling createPhotorealisticPrompt with:", {
173
- isCouple: isCoupleMode,
174
- hasCustomInstructions: !!customInstructions
175
- });
176
- }
177
-
178
- const prompt = createPhotorealisticPrompt(refinedPrompt, {
179
- isCouple: isCoupleMode,
180
- customInstructions,
181
- });
182
-
183
- if (DEV) {
184
- console.log("[CoupleBuilder] Final prompt length:", prompt.length);
185
- console.log("[CoupleBuilder] Final prompt preview:", prompt.substring(0, 500) + "...");
186
- console.log("[CoupleBuilder] Has custom instructions:", !!customInstructions);
187
- if (customInstructions) {
188
- console.log("[CoupleBuilder] Custom instructions:", customInstructions);
189
- }
190
- }
191
-
192
- // 5. RESOLVE COUPLE INPUT - Doğru target ve image'lar
193
- if (DEV) {
194
- console.log("[CoupleBuilder] ===== STEP 5: RESOLVE COUPLE INPUT =====");
195
- console.log("[CoupleBuilder] Calling resolveCoupleInput with:", {
196
- partner1PhotoUri: partner1PhotoUri.substring(0, 50) + "...",
197
- partner2PhotoUri: partner2PhotoUri ? partner2PhotoUri.substring(0, 50) + "..." : null,
198
- isCoupleMode,
199
- singleTarget: "p-image-edit/pruna",
200
- coupleTarget: "p-image-edit/pruna"
201
- });
202
- }
203
-
204
- const { target, imageUrls } = resolveCoupleInput(
205
- partner1PhotoUri,
206
- partner2PhotoUri,
207
- isCoupleMode,
208
- { model: "p-image-edit", providerId: "pruna" }, // Single target
209
- { model: "p-image-edit", providerId: "pruna" }, // Couple target
210
- );
211
-
212
- if (DEV) {
213
- console.log("[CoupleBuilder] Target resolution result:");
214
- console.log("[CoupleBuilder] Target model:", target.model);
215
- console.log("[CoupleBuilder] Target provider:", target.providerId);
216
- console.log("[CoupleBuilder] Image URLs count:", imageUrls.length);
217
- console.log("[CoupleBuilder] Image 1:", imageUrls[0]?.substring(0, 80) + "...");
218
- if (imageUrls.length > 1) {
219
- console.log("[CoupleBuilder] Image 2:", imageUrls[1]?.substring(0, 80) + "...");
220
- }
221
- }
222
-
223
- // 6. BUILD PARAMS - Wardrobe formatında
224
- if (DEV) {
225
- console.log("[CoupleBuilder] ===== STEP 6: BUILD PARAMS =====");
226
- }
227
-
228
- const genParams: Record<string, unknown> = {
229
- prompt,
230
- image_urls: imageUrls,
231
- aspect_ratio: aspectRatio,
232
- };
233
-
234
- // Optional strength parameter
235
- if (strength !== undefined) {
236
- genParams.strength = strength;
237
- }
238
-
239
- if (DEV) {
240
- console.log("[CoupleBuilder] Final params structure:");
241
- console.log("[CoupleBuilder] Keys:", Object.keys(genParams).join(", "));
242
- console.log("[CoupleBuilder] 'image_urls' count:", Array.isArray(genParams.image_urls) ? genParams.image_urls.length : "N/A");
243
- console.log("[CoupleBuilder] 'aspect_ratio':", genParams.aspect_ratio);
244
- console.log("[CoupleBuilder] 'strength':", genParams.strength ?? "not set");
245
- console.log("[CoupleBuilder] ========================================");
246
- console.log("[CoupleBuilder] ===== BUILD COUPLE GENERATION END =====");
247
- console.log("[CoupleBuilder] ========================================");
248
- console.log("[CoupleBuilder] Returning: { target, prompt, params }");
249
- console.log("");
250
- }
251
-
252
- return {
253
- target,
254
- prompt,
255
- params: genParams,
256
- };
257
- }
258
-
259
- /**
260
- * Scenario generation için özel wrapper
261
- *
262
- * Senaryo aiPrompt'larını (zaten createPhotorealisticPrompt ile oluşturulmuş)
263
- * Wardrobe mantığı ile birleştirir.
264
- */
265
- export async function buildScenarioGenerationInput(
266
- params: ScenarioGenerationInputParams,
267
- ): Promise<CoupleGenerationInput> {
268
- const DEV = typeof __DEV__ !== "undefined" && __DEV__;
269
-
270
- const {
271
- partner1PhotoUri,
272
- partner2PhotoUri,
273
- isCoupleMode,
274
- scenarioPrompt,
275
- } = params;
276
-
277
- if (DEV) {
278
- console.log("[ScenarioBuilder] ========================================");
279
- console.log("[ScenarioBuilder] ===== BUILD SCENARIO GENERATION START =====");
280
- console.log("[ScenarioBuilder] ========================================");
281
- console.log("[ScenarioBuilder] ===== INPUT PARAMS =====");
282
- console.log("[ScenarioBuilder] Is couple mode:", isCoupleMode);
283
- console.log("[ScenarioBuilder] Scenario prompt length:", scenarioPrompt.length);
284
- console.log("[ScenarioBuilder] Scenario prompt preview:", scenarioPrompt.substring(0, 200) + "...");
285
- console.log("[ScenarioBuilder] Partner 1 URI:", partner1PhotoUri.substring(0, 80) + "...");
286
- if (partner2PhotoUri) {
287
- console.log("[ScenarioBuilder] Partner 2 URI:", partner2PhotoUri.substring(0, 80) + "...");
288
- }
289
- }
290
-
291
- // 1. GET PHOTO URIs
292
- const photoUris =
293
- isCoupleMode && partner2PhotoUri
294
- ? [partner1PhotoUri, partner2PhotoUri]
295
- : [partner1PhotoUri];
296
-
297
- if (DEV) {
298
- console.log("[ScenarioBuilder] ===== STEP 1: PHOTO URIs =====");
299
- console.log("[ScenarioBuilder] Photo URIs count:", photoUris.length);
300
- }
301
-
302
- // 2. ANALYZE APPEARANCE
303
- if (DEV) {
304
- console.log("[ScenarioBuilder] ===== STEP 2: APPEARANCE ANALYSIS =====");
305
- }
306
-
307
- const appearanceContext = await getAppearanceContext(
308
- photoUris,
309
- isCoupleMode,
310
- );
311
-
312
- if (DEV) {
313
- console.log("[ScenarioBuilder] Appearance context length:", appearanceContext.length);
314
- if (appearanceContext.length > 0) {
315
- console.log("[ScenarioBuilder] Appearance context preview:", appearanceContext.substring(0, 150) + "...");
316
- } else {
317
- console.log("[ScenarioBuilder] ℹ️ No appearance context (vision disabled)");
318
- }
319
- }
320
-
321
- // 3. REFINE FOR COUPLE + PREPEND CONTEXT
322
- // Senaryo prompt'unu (zaten photorealistic) dynamic context ile birleştir
323
- if (DEV) {
324
- console.log("[ScenarioBuilder] ===== STEP 3: REFINE & PREPEND CONTEXT =====");
325
- console.log("[ScenarioBuilder] Calling refinePromptForCouple...");
326
- }
327
-
328
- const refinedPrompt = refinePromptForCouple(scenarioPrompt, isCoupleMode);
329
- const finalPrompt = prependContext(refinedPrompt, appearanceContext);
330
-
331
- if (DEV) {
332
- console.log("[ScenarioBuilder] After refinePromptForCouple length:", refinedPrompt.length);
333
- console.log("[ScenarioBuilder] After prependContext length:", finalPrompt.length);
334
- console.log("[ScenarioBuilder] Final prompt preview:", finalPrompt.substring(0, 300) + "...");
335
- }
336
-
337
- // 4. RESOLVE COUPLE INPUT
338
- if (DEV) {
339
- console.log("[ScenarioBuilder] ===== STEP 4: RESOLVE COUPLE INPUT =====");
340
- }
341
-
342
- const { target, imageUrls } = resolveCoupleInput(
343
- partner1PhotoUri,
344
- partner2PhotoUri,
345
- isCoupleMode,
346
- { model: "p-image-edit", providerId: "pruna" }, // Single target
347
- { model: "p-image-edit", providerId: "pruna" }, // Couple target
348
- );
349
-
350
- if (DEV) {
351
- console.log("[ScenarioBuilder] Target:", target.model, "/", target.providerId);
352
- console.log("[ScenarioBuilder] Image URLs count:", imageUrls.length);
353
- }
354
-
355
- // 5. BUILD PARAMS - Scenario formatında
356
- if (DEV) {
357
- console.log("[ScenarioBuilder] ===== STEP 5: BUILD PARAMS =====");
358
- console.log("[ScenarioBuilder] Aspect ratio: 3:4");
359
- console.log("[ScenarioBuilder] ========================================");
360
- console.log("[ScenarioBuilder] ===== BUILD SCENARIO GENERATION END =====");
361
- console.log("[ScenarioBuilder] ========================================");
362
- console.log("");
363
- }
364
-
365
- return {
366
- target,
367
- prompt: finalPrompt,
368
- params: {
369
- prompt: finalPrompt,
370
- image_urls: imageUrls,
371
- aspect_ratio: "3:4",
372
- },
373
- };
374
- }
@@ -1,276 +0,0 @@
1
- /**
2
- * Generation Orchestrator
3
- * Handles AI generation execution with network check, moderation, credit deduction, and error handling
4
- */
5
-
6
- import { useState, useCallback, useRef, useEffect } from "react";
7
- import { useAlert } from "@umituz/react-native-design-system/molecules";
8
- import { useOfflineStore } from "@umituz/react-native-design-system/offline";
9
- import { createGenerationError, getAlertMessage, parseError } from "./errors";
10
- import { handleModeration } from "./moderation-handler";
11
- import type {
12
- GenerationStrategy,
13
- GenerationConfig,
14
- GenerationState,
15
- GenerationError,
16
- UseGenerationOrchestratorReturn,
17
- } from "./types";
18
-
19
- const getInitialState = <T>(): GenerationState<T> => ({
20
- status: "idle",
21
- isGenerating: false,
22
- result: null,
23
- error: null,
24
- });
25
-
26
- export const useGenerationOrchestrator = <TInput, TResult>(
27
- strategy: GenerationStrategy<TInput, TResult>,
28
- config: GenerationConfig,
29
- ): UseGenerationOrchestratorReturn<TInput, TResult> => {
30
- const { userId, alertMessages, onSuccess, onError, moderation, lifecycle } = config;
31
-
32
- const [state, setState] = useState<GenerationState<TResult>>(getInitialState<TResult>());
33
- const isGeneratingRef = useRef(false);
34
- const isMountedRef = useRef(true);
35
- const abortControllerRef = useRef<AbortController | null>(null);
36
- const cleanupTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
37
-
38
- // Stable refs for callbacks — prevents useCallback deps from thrashing when
39
- // callers pass inline functions (which create new references every render).
40
- const onSuccessRef = useRef(onSuccess);
41
- const onErrorRef = useRef(onError);
42
- // Update refs in render body (not useEffect) so they're always in sync — no 1-frame delay
43
- onSuccessRef.current = onSuccess;
44
- onErrorRef.current = onError;
45
-
46
- const offlineStore = useOfflineStore();
47
- const { showError, showSuccess } = useAlert();
48
-
49
- useEffect(() => {
50
- isMountedRef.current = true;
51
- return () => {
52
- isMountedRef.current = false;
53
- abortControllerRef.current?.abort();
54
- // Clear any pending lifecycle complete timeout
55
- if (cleanupTimeoutRef.current) {
56
- clearTimeout(cleanupTimeoutRef.current);
57
- cleanupTimeoutRef.current = null;
58
- }
59
- };
60
- }, []);
61
-
62
- const handleLifecycleComplete = useCallback(
63
- (status: "success" | "error", result?: TResult, error?: GenerationError) => {
64
- if (!lifecycle?.onComplete) return;
65
-
66
- // Clear any existing timeout first
67
- if (cleanupTimeoutRef.current) {
68
- clearTimeout(cleanupTimeoutRef.current);
69
- cleanupTimeoutRef.current = null;
70
- }
71
-
72
- const delay = lifecycle.completeDelay ?? 500;
73
- cleanupTimeoutRef.current = setTimeout(() => {
74
- if (isMountedRef.current) {
75
- lifecycle.onComplete?.(status, result, error);
76
- }
77
- cleanupTimeoutRef.current = null;
78
- }, delay);
79
- },
80
- [lifecycle],
81
- );
82
-
83
- const executeGeneration = useCallback(
84
- async (input: TInput) => {
85
- if (typeof __DEV__ !== "undefined" && __DEV__) {
86
- console.log("[Orchestrator] ----------------------------------------");
87
- console.log("[Orchestrator] executeGeneration() called");
88
- }
89
-
90
- // Check abort signal before starting
91
- if (abortControllerRef.current?.signal.aborted) {
92
- if (typeof __DEV__ !== "undefined" && __DEV__) {
93
- console.log("[Orchestrator] Aborted before generation started");
94
- }
95
- throw new Error("Generation aborted");
96
- }
97
-
98
- setState((prev) => ({ ...prev, status: "generating" }));
99
- if (typeof __DEV__ !== "undefined" && __DEV__) {
100
- console.log("[Orchestrator] State: generating - calling strategy.execute()");
101
- }
102
-
103
- const result = await strategy.execute(input);
104
-
105
- // Check abort signal after execution
106
- if (abortControllerRef.current?.signal.aborted) {
107
- if (typeof __DEV__ !== "undefined" && __DEV__) {
108
- console.log("[Orchestrator] Aborted after generation completed");
109
- }
110
- throw new Error("Generation aborted");
111
- }
112
-
113
- if (typeof __DEV__ !== "undefined" && __DEV__) {
114
- console.log("[Orchestrator] strategy.execute() completed");
115
- }
116
-
117
- if (strategy.save && userId) {
118
- // Check abort signal before save
119
- if (abortControllerRef.current?.signal.aborted) {
120
- if (typeof __DEV__ !== "undefined" && __DEV__) {
121
- console.log("[Orchestrator] Aborted before save");
122
- }
123
- throw new Error("Generation aborted");
124
- }
125
-
126
- if (isMountedRef.current) setState((prev) => ({ ...prev, status: "saving" }));
127
- if (typeof __DEV__ !== "undefined" && __DEV__) {
128
- console.log("[Orchestrator] Saving result to Firestore");
129
- }
130
- try {
131
- await strategy.save(result, userId);
132
- if (typeof __DEV__ !== "undefined" && __DEV__) {
133
- console.log("[Orchestrator] Result saved successfully");
134
- }
135
- } catch (saveErr) {
136
- if (typeof __DEV__ !== "undefined" && __DEV__) {
137
- console.log("[Orchestrator] ERROR: Save failed:", saveErr);
138
- }
139
- // Update state to error on save failure
140
- if (isMountedRef.current) {
141
- setState((prev) => ({ ...prev, status: "error", isGenerating: false }));
142
- }
143
- throw createGenerationError("save", alertMessages.saveFailed, saveErr instanceof Error ? saveErr : undefined);
144
- }
145
- }
146
-
147
- // Final abort check before success
148
- if (abortControllerRef.current?.signal.aborted) {
149
- if (typeof __DEV__ !== "undefined" && __DEV__) {
150
- console.log("[Orchestrator] Aborted before success callback");
151
- }
152
- throw new Error("Generation aborted");
153
- }
154
-
155
- if (isMountedRef.current) setState({ status: "success", isGenerating: false, result, error: null });
156
- if (typeof __DEV__ !== "undefined" && __DEV__) {
157
- console.log("[Orchestrator] ✅ Generation SUCCESS");
158
- console.log("[Orchestrator] ========================================");
159
- }
160
-
161
- if (alertMessages.success) showSuccess("Success", alertMessages.success);
162
- await onSuccessRef.current?.(result);
163
- handleLifecycleComplete("success", result);
164
- return result;
165
- },
166
- [strategy, userId, alertMessages, showSuccess, handleLifecycleComplete],
167
- );
168
-
169
- const generate = useCallback(
170
- async (input: TInput): Promise<TResult | void> => {
171
- if (typeof __DEV__ !== "undefined" && __DEV__) {
172
- console.log("[Orchestrator] ========================================");
173
- console.log("[Orchestrator] generate() called with input:", JSON.stringify(input).substring(0, 200));
174
- console.log("[Orchestrator] isGenerating:", isGeneratingRef.current);
175
- console.log("[Orchestrator] userId:", userId);
176
- }
177
-
178
- if (isGeneratingRef.current) {
179
- if (typeof __DEV__ !== "undefined" && __DEV__) {
180
- console.log("[Orchestrator] BLOCKED: Already generating");
181
- }
182
- return;
183
- }
184
-
185
- // Create new AbortController for this generation
186
- abortControllerRef.current = new AbortController();
187
- isGeneratingRef.current = true;
188
- let moderationPending = false;
189
- setState({ ...getInitialState<TResult>(), status: "checking", isGenerating: true });
190
-
191
- if (typeof __DEV__ !== "undefined" && __DEV__) {
192
- console.log("[Orchestrator] State set to 'checking', isGenerating: true");
193
- }
194
-
195
- try {
196
- // Check online status inside the try block to avoid dependency on offlineStore.isOnline
197
- if (!offlineStore.isOnline) {
198
- if (typeof __DEV__ !== "undefined" && __DEV__) {
199
- console.log("[Orchestrator] ERROR: User is offline");
200
- }
201
- throw createGenerationError("network", alertMessages.networkError);
202
- }
203
-
204
- if (typeof __DEV__ !== "undefined" && __DEV__) {
205
- console.log("[Orchestrator] Online check passed");
206
- }
207
-
208
- // Check if aborted before moderation
209
- if (abortControllerRef.current.signal.aborted) {
210
- if (typeof __DEV__ !== "undefined" && __DEV__) {
211
- console.log("[Orchestrator] ERROR: Generation aborted (2)");
212
- }
213
- throw new Error("Generation aborted");
214
- }
215
-
216
- if (typeof __DEV__ !== "undefined" && __DEV__) {
217
- console.log("[Orchestrator] Starting moderation check");
218
- }
219
-
220
- const result = await handleModeration({
221
- input,
222
- moderation,
223
- alertMessages,
224
- isMountedRef,
225
- isGeneratingRef,
226
- setState: (s) => setState(s as GenerationState<TResult>),
227
- resetState: () => setState(getInitialState<TResult>()),
228
- executeGeneration,
229
- showError,
230
- onError,
231
- handleLifecycleComplete,
232
- });
233
-
234
- // If handleModeration returned undefined, the warning dialog was shown.
235
- // The dialog's proceed/cancel callbacks now own isGeneratingRef — don't reset in finally.
236
- if (result === undefined && moderation) {
237
- moderationPending = true;
238
- }
239
-
240
- return result;
241
- } catch (err) {
242
- // Don't show error if aborted
243
- if (abortControllerRef.current?.signal.aborted) {
244
- if (typeof __DEV__ !== "undefined" && __DEV__) {
245
- console.log("[Orchestrator] Generation aborted");
246
- }
247
- return;
248
- }
249
-
250
- const error = parseError(err);
251
- if (typeof __DEV__ !== "undefined" && __DEV__) console.log("[Orchestrator] Error:", error);
252
- if (isMountedRef.current) setState({ status: "error", isGenerating: false, result: null, error });
253
- showError("Error", getAlertMessage(error, alertMessages));
254
- await onErrorRef.current?.(error);
255
- handleLifecycleComplete("error", undefined, error);
256
- throw error;
257
- } finally {
258
- // Only reset if moderation dialog did not take ownership
259
- if (!moderationPending) {
260
- isGeneratingRef.current = false;
261
- }
262
- abortControllerRef.current = null;
263
- }
264
- },
265
- [offlineStore, moderation, alertMessages, strategy, executeGeneration, showError, handleLifecycleComplete],
266
- );
267
-
268
- const reset = useCallback(() => {
269
- abortControllerRef.current?.abort();
270
- abortControllerRef.current = null;
271
- setState(getInitialState<TResult>());
272
- isGeneratingRef.current = false;
273
- }, []);
274
-
275
- return { generate, reset, status: state.status, isGenerating: state.isGenerating, result: state.result, error: state.error };
276
- };