@umituz/react-native-ai-generation-content 1.90.1 → 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.
- package/package.json +1 -4
- package/src/domain/interfaces/app-services-auth.interface.ts +27 -0
- package/src/domain/interfaces/app-services-composite.interface.ts +29 -0
- package/src/domain/interfaces/app-services-optional.interface.ts +42 -0
- package/src/domain/interfaces/app-services.interface.ts +0 -79
- package/src/domains/background/infrastructure/services/job-poller-index.ts +7 -0
- package/src/domains/background/infrastructure/services/job-poller-utils.ts +130 -0
- package/src/domains/background/infrastructure/utils/polling-interval.util.ts +1 -1
- package/src/domains/background/presentation/hooks/use-background-generation.ts +1 -1
- package/src/domains/content-moderation/infrastructure/services/content-moderation.service.ts +1 -1
- package/src/domains/content-moderation/infrastructure/services/moderators/image.moderator.ts +34 -8
- package/src/domains/content-moderation/infrastructure/services/moderators/text.moderator.ts +15 -4
- package/src/domains/content-moderation/infrastructure/services/moderators/video.moderator.ts +34 -8
- package/src/domains/content-moderation/infrastructure/services/moderators/voice.moderator.ts +19 -8
- package/src/domains/creations/domain/types/creation-categories.constants.ts +57 -0
- package/src/domains/creations/domain/types/creation-categories.helpers.ts +67 -0
- package/src/domains/creations/domain/types/creation-categories.ts +5 -111
- package/src/domains/creations/presentation/hooks/creation-validators.ts +31 -29
- package/src/domains/creations/presentation/hooks/job-poller-index.ts +10 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.filters.ts +34 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.logger.ts +76 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.stale-handlers.ts +52 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.ts +8 -0
- package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +1 -1
- package/src/domains/creations/presentation-exports.ts +2 -2
- package/src/domains/face-detection/domain/entities/FaceDetection.ts +4 -3
- package/src/domains/face-detection/presentation/hooks/useFaceDetection.ts +24 -21
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-preparation.ts +58 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-prompt.ts +69 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-resolution.ts +77 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple.ts +54 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-index.ts +8 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-scenario.ts +113 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder.ts +7 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/index.ts +20 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/types.ts +44 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-end-logger.ts +18 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-start-logger.ts +57 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-step-logger.ts +106 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/index.ts +8 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/types.ts +49 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils.ts +8 -0
- package/src/domains/generation/infrastructure/flow/flow-store-actions.ts +105 -0
- package/src/domains/generation/infrastructure/flow/flow-store-initial-state.ts +26 -0
- package/src/domains/generation/infrastructure/flow/useFlowStore.ts +4 -116
- package/src/domains/generation/presentation/useAIGeneration.hook.ts +1 -1
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation-strategy-index.ts +7 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.ts +2 -12
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.types.ts +11 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.utils.ts +12 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +1 -220
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-builder.ts +66 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-extraction.ts +88 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-prompt-builder.ts +75 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-style-enhancements.ts +35 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-strategy-factory.ts +42 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor-index.ts +11 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor.ts +76 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-input-builder.ts +46 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-result-types.ts +17 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-submission.ts +62 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.audio-extractor.ts +27 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.executor.ts +2 -175
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.input-builder.ts +90 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +3 -108
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.types.ts +0 -129
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.validation.ts +136 -0
- package/src/domains/generation/wizard/presentation/hooks/photo-upload/index.ts +39 -0
- package/src/domains/generation/wizard/presentation/hooks/photo-upload/types.ts +37 -0
- package/src/domains/generation/wizard/presentation/hooks/photo-upload/usePhotoUploadStateLogic.ts +142 -0
- package/src/domains/generation/wizard/presentation/hooks/use-video-queue-utils.ts +103 -0
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.handlers.ts +97 -0
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.saver.ts +54 -0
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.ts +22 -87
- package/src/domains/generation/wizard/presentation/hooks/usePhotoUploadState.ts +8 -177
- package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +1 -295
- package/src/domains/generation/wizard/presentation/hooks/useWizardGeneration.ts +1 -1
- package/src/domains/generation/wizard/presentation/hooks/video-queue/index.ts +82 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationCallbacks.ts +120 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationPolling.ts +76 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationRefs.ts +65 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationStart.ts +123 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue-index.ts +9 -0
- package/src/domains/image-to-video/domain/types/image-to-video-state.types.ts +11 -4
- package/src/domains/text-to-image/domain/types/text-to-image.types.ts +44 -22
- package/src/domains/text-to-video/domain/types/request.types.ts +33 -9
- package/src/domains/text-to-video/domain/types/state.types.ts +29 -9
- package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.handlers.ts +44 -0
- package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.ts +5 -51
- package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.types.ts +33 -0
- package/src/infrastructure/services/generation-orchestrator.service.ts +2 -2
- package/src/infrastructure/utils/couple-input-context.ts +13 -0
- package/src/infrastructure/utils/couple-input-index.ts +8 -0
- package/src/infrastructure/utils/couple-input-refiner.ts +101 -0
- package/src/infrastructure/utils/couple-input-resolver.ts +71 -0
- package/src/infrastructure/utils/couple-input-types.ts +14 -0
- package/src/infrastructure/utils/couple-input.util.ts +3 -176
- package/src/infrastructure/utils/photo-generation/photo-preparation.util.ts +1 -1
- package/src/infrastructure/validation/base-validator.ts +1 -27
- package/src/infrastructure/validation/base-validator.types.ts +32 -0
- package/src/presentation/hooks/generation/index.ts +1 -1
- package/src/presentation/hooks/generation/orchestrator-abort-logs.ts +48 -0
- package/src/presentation/hooks/generation/orchestrator-execution-logs.ts +67 -0
- package/src/presentation/hooks/generation/orchestrator-index.ts +14 -0
- package/src/presentation/hooks/generation/orchestrator-start-logs.ts +65 -0
- package/src/presentation/hooks/generation/orchestrator-state-utils.ts +17 -0
- package/src/presentation/hooks/generation/orchestrator-types.ts +55 -0
- package/src/presentation/hooks/generation/orchestrator-utils-index.ts +29 -0
- package/src/presentation/hooks/generation/orchestrator-utils.ts +25 -0
- package/src/presentation/hooks/generation/useDualImageGeneration.ts +1 -1
- package/src/presentation/hooks/generation/useImageGeneration.ts +1 -1
- package/src/presentation/hooks/generation/useVideoGeneration.ts +1 -1
- package/src/shared/hooks/factories/generation-hook-index.ts +12 -0
- package/src/shared/hooks/factories/generation-hook-types.ts +47 -0
- package/src/shared/hooks/factories/generation-hook-utils.ts +94 -0
- package/src/shared/hooks/factories/index.ts +1 -1
- package/src/shared/index.ts +1 -1
- package/src/shared/utils/calculations/aspect-ratio-calculations.ts +30 -0
- package/src/shared/utils/calculations/base64-calculations.ts +26 -0
- package/src/shared/utils/calculations/confidence-calculations.ts +21 -0
- package/src/shared/utils/calculations/cost-calculations-index.ts +43 -0
- package/src/shared/utils/calculations/cost-calculations.ts +25 -0
- package/src/shared/utils/calculations/credit-calculations.ts +37 -0
- package/src/shared/utils/calculations/index.ts +46 -0
- package/src/shared/utils/calculations/math-utilities.ts +32 -0
- package/src/shared/utils/calculations/memory-calculations.ts +33 -0
- package/src/shared/utils/calculations/pagination-calculations.ts +38 -0
- package/src/shared/utils/calculations/percentage-calculations.ts +33 -0
- package/src/shared/utils/calculations/time-calculations.ts +99 -0
- package/src/shared/utils/credit.ts +1 -1
- package/src/shared-kernel/application/hooks/index.ts +8 -0
- package/src/shared-kernel/application/hooks/use-feature-state.ts +107 -0
- package/src/shared-kernel/application/hooks/use-generation-handler.ts +110 -0
- package/src/shared-kernel/base-types/base-callbacks.types.ts +73 -0
- package/src/shared-kernel/base-types/base-feature-state.types.ts +77 -0
- package/src/shared-kernel/base-types/base-generation.types.ts +69 -0
- package/src/shared-kernel/base-types/index.ts +30 -0
- package/src/shared-kernel/domain/base-generation-strategy.ts +146 -0
- package/src/shared-kernel/domain/index.ts +7 -0
- package/src/shared-kernel/index.ts +17 -0
- package/src/shared-kernel/infrastructure/validation/common-validators.ts +126 -0
- package/src/shared-kernel/infrastructure/validation/common-validators.types.ts +33 -0
- package/src/shared-kernel/infrastructure/validation/error-handler.ts +52 -0
- package/src/shared-kernel/infrastructure/validation/error-handler.types.ts +38 -0
- package/src/shared-kernel/infrastructure/validation/error-handler.utils.ts +79 -0
- package/src/shared-kernel/infrastructure/validation/index.ts +28 -0
- package/src/domains/background/infrastructure/services/job-poller.service.ts +0 -234
- package/src/domains/creations/presentation/hooks/useProcessingJobsPoller.ts +0 -256
- package/src/domains/generation/infrastructure/couple-generation-builder.ts +0 -374
- package/src/presentation/hooks/generation/orchestrator.ts +0 -276
- package/src/shared/hooks/factories/createGenerationHook.ts +0 -253
- package/src/shared/utils/calculations.util.ts +0 -366
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creation Categories - Helpers
|
|
3
|
+
* Helper functions for creation type categorization
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { CreationTypeId, CreationCategory } from "./creation-types";
|
|
7
|
+
import { IMAGE_CREATION_TYPES, VIDEO_CREATION_TYPES } from "./creation-categories.constants";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get creation types for a category
|
|
11
|
+
*/
|
|
12
|
+
export function getTypesForCategory(
|
|
13
|
+
category: CreationCategory
|
|
14
|
+
): CreationTypeId[] {
|
|
15
|
+
switch (category) {
|
|
16
|
+
case "image":
|
|
17
|
+
return IMAGE_CREATION_TYPES;
|
|
18
|
+
case "video":
|
|
19
|
+
return VIDEO_CREATION_TYPES;
|
|
20
|
+
case "all":
|
|
21
|
+
return [...IMAGE_CREATION_TYPES, ...VIDEO_CREATION_TYPES];
|
|
22
|
+
default:
|
|
23
|
+
return [...IMAGE_CREATION_TYPES, ...VIDEO_CREATION_TYPES];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get category for a creation type (type-based fallback only)
|
|
29
|
+
*/
|
|
30
|
+
export function getCategoryForType(type: CreationTypeId): CreationCategory {
|
|
31
|
+
if (IMAGE_CREATION_TYPES.includes(type)) {
|
|
32
|
+
return "image";
|
|
33
|
+
}
|
|
34
|
+
if (VIDEO_CREATION_TYPES.includes(type)) {
|
|
35
|
+
return "video";
|
|
36
|
+
}
|
|
37
|
+
return "image"; // Default fallback
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Check if a type belongs to a category
|
|
42
|
+
*/
|
|
43
|
+
export function isTypeInCategory(
|
|
44
|
+
type: CreationTypeId,
|
|
45
|
+
category: CreationCategory
|
|
46
|
+
): boolean {
|
|
47
|
+
if (category === "all") {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return getTypesForCategory(category).includes(type);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Check if creation type is video
|
|
55
|
+
*/
|
|
56
|
+
export function isVideoCreationType(type?: string): boolean {
|
|
57
|
+
if (!type) return false;
|
|
58
|
+
return VIDEO_CREATION_TYPES.includes(type as CreationTypeId);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Check if creation type is image
|
|
63
|
+
*/
|
|
64
|
+
export function isImageCreationType(type?: string): boolean {
|
|
65
|
+
if (!type) return false;
|
|
66
|
+
return IMAGE_CREATION_TYPES.includes(type as CreationTypeId);
|
|
67
|
+
}
|
|
@@ -3,89 +3,8 @@
|
|
|
3
3
|
* Maps creation types to categories for filtering and organization
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Image-related creation types
|
|
10
|
-
*/
|
|
11
|
-
export const IMAGE_CREATION_TYPES: CreationTypeId[] = [
|
|
12
|
-
"text-to-image",
|
|
13
|
-
"imagine",
|
|
14
|
-
"wardrobe",
|
|
15
|
-
"historical-wardrobe",
|
|
16
|
-
"upscale",
|
|
17
|
-
"remove-background",
|
|
18
|
-
"photo-restore",
|
|
19
|
-
"inpainting",
|
|
20
|
-
"style-transfer",
|
|
21
|
-
"colorization",
|
|
22
|
-
"face-swap",
|
|
23
|
-
"object-removal",
|
|
24
|
-
"background-replacement",
|
|
25
|
-
"ai-brush",
|
|
26
|
-
"hd-touch-up",
|
|
27
|
-
"anime-selfie",
|
|
28
|
-
"aging",
|
|
29
|
-
"headshot",
|
|
30
|
-
"retouch",
|
|
31
|
-
"magic-edit",
|
|
32
|
-
"color-grading",
|
|
33
|
-
"art-style",
|
|
34
|
-
"mood-filter",
|
|
35
|
-
"face-expression",
|
|
36
|
-
"scene-composer",
|
|
37
|
-
"ai-background",
|
|
38
|
-
"effects",
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Video-related creation types (core types only)
|
|
43
|
-
* NOTE: All other video types (scenarios, etc.)
|
|
44
|
-
* are dynamically determined by output content via isVideoUrl()
|
|
45
|
-
*/
|
|
46
|
-
export const VIDEO_CREATION_TYPES: CreationTypeId[] = [
|
|
47
|
-
"text-to-video",
|
|
48
|
-
"image-to-video",
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* All creation types
|
|
53
|
-
*/
|
|
54
|
-
export const ALL_CREATION_TYPES: CreationTypeId[] = [
|
|
55
|
-
...IMAGE_CREATION_TYPES,
|
|
56
|
-
...VIDEO_CREATION_TYPES,
|
|
57
|
-
];
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Get creation types for a category
|
|
61
|
-
*/
|
|
62
|
-
export function getTypesForCategory(
|
|
63
|
-
category: CreationCategory
|
|
64
|
-
): CreationTypeId[] {
|
|
65
|
-
switch (category) {
|
|
66
|
-
case "image":
|
|
67
|
-
return IMAGE_CREATION_TYPES;
|
|
68
|
-
case "video":
|
|
69
|
-
return VIDEO_CREATION_TYPES;
|
|
70
|
-
case "all":
|
|
71
|
-
return ALL_CREATION_TYPES;
|
|
72
|
-
default:
|
|
73
|
-
return ALL_CREATION_TYPES;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Get category for a creation type (type-based fallback only)
|
|
79
|
-
*/
|
|
80
|
-
export function getCategoryForType(type: CreationTypeId): CreationCategory {
|
|
81
|
-
if (IMAGE_CREATION_TYPES.includes(type)) {
|
|
82
|
-
return "image";
|
|
83
|
-
}
|
|
84
|
-
if (VIDEO_CREATION_TYPES.includes(type)) {
|
|
85
|
-
return "video";
|
|
86
|
-
}
|
|
87
|
-
return "image"; // Default fallback
|
|
88
|
-
}
|
|
6
|
+
import type { CreationCategory } from "./creation-types";
|
|
7
|
+
import { getCategoryForType } from "./creation-categories.helpers";
|
|
89
8
|
|
|
90
9
|
/**
|
|
91
10
|
* Get category for a creation based on its output content
|
|
@@ -117,38 +36,13 @@ export function getCategoryForCreation(creation: {
|
|
|
117
36
|
|
|
118
37
|
// PRIORITY 2: Fallback to type-based (for known types)
|
|
119
38
|
if (creation.type) {
|
|
120
|
-
return getCategoryForType(creation.type as CreationTypeId);
|
|
39
|
+
return getCategoryForType(creation.type as import("./creation-types").CreationTypeId);
|
|
121
40
|
}
|
|
122
41
|
|
|
123
42
|
// Final fallback
|
|
124
43
|
return "image";
|
|
125
44
|
}
|
|
126
45
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
*/
|
|
130
|
-
export function isTypeInCategory(
|
|
131
|
-
type: CreationTypeId,
|
|
132
|
-
category: CreationCategory
|
|
133
|
-
): boolean {
|
|
134
|
-
if (category === "all") {
|
|
135
|
-
return true;
|
|
136
|
-
}
|
|
137
|
-
return getTypesForCategory(category).includes(type);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Check if creation type is video
|
|
142
|
-
*/
|
|
143
|
-
export function isVideoCreationType(type?: string): boolean {
|
|
144
|
-
if (!type) return false;
|
|
145
|
-
return VIDEO_CREATION_TYPES.includes(type as CreationTypeId);
|
|
146
|
-
}
|
|
46
|
+
export { IMAGE_CREATION_TYPES, VIDEO_CREATION_TYPES, ALL_CREATION_TYPES } from "./creation-categories.constants";
|
|
47
|
+
export { getTypesForCategory, getCategoryForType, isTypeInCategory, isVideoCreationType, isImageCreationType } from "./creation-categories.helpers";
|
|
147
48
|
|
|
148
|
-
/**
|
|
149
|
-
* Check if creation type is image
|
|
150
|
-
*/
|
|
151
|
-
export function isImageCreationType(type?: string): boolean {
|
|
152
|
-
if (!type) return false;
|
|
153
|
-
return IMAGE_CREATION_TYPES.includes(type as CreationTypeId);
|
|
154
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Creation Validation Utilities
|
|
3
3
|
*
|
|
4
|
-
* Centralized validation logic for creation persistence.
|
|
4
|
+
* Centralized validation logic for creation persistence using shared kernel.
|
|
5
5
|
* Keeps validation rules separate from hook logic.
|
|
6
6
|
*
|
|
7
7
|
* @module CreationValidators
|
|
@@ -13,12 +13,7 @@ import {
|
|
|
13
13
|
CREATION_FIELDS,
|
|
14
14
|
} from "../../domain/constants";
|
|
15
15
|
import type { ICreationsRepository } from "../../domain/repositories/ICreationsRepository";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
interface ValidationResult {
|
|
19
|
-
isValid: boolean;
|
|
20
|
-
error?: string;
|
|
21
|
-
}
|
|
16
|
+
import { validateUrl, validateString, combineValidationResults, type ValidationResult } from "../../../../shared-kernel/infrastructure/validation";
|
|
22
17
|
|
|
23
18
|
/**
|
|
24
19
|
* Validates that at least one URL is present
|
|
@@ -30,10 +25,10 @@ function validateHasUrl(
|
|
|
30
25
|
if (!imageUrl && !videoUrl) {
|
|
31
26
|
return {
|
|
32
27
|
isValid: false,
|
|
33
|
-
|
|
28
|
+
errors: { urls: "No output URL provided" },
|
|
34
29
|
};
|
|
35
30
|
}
|
|
36
|
-
return { isValid: true };
|
|
31
|
+
return { isValid: true, errors: {} };
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
/**
|
|
@@ -47,42 +42,49 @@ function validateUriProtocol(uri: string): ValidationResult {
|
|
|
47
42
|
if (!hasValidProtocol) {
|
|
48
43
|
return {
|
|
49
44
|
isValid: false,
|
|
50
|
-
|
|
45
|
+
errors: {
|
|
46
|
+
protocol: `Invalid URI protocol. Expected one of: ${CREATION_VALIDATION.VALID_URI_PROTOCOLS.join(", ")}`
|
|
47
|
+
},
|
|
51
48
|
};
|
|
52
49
|
}
|
|
53
50
|
|
|
54
|
-
return { isValid: true };
|
|
51
|
+
return { isValid: true, errors: {} };
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
/**
|
|
58
|
-
*
|
|
59
|
-
*/
|
|
60
|
-
function validateUriLength(uri: string): ValidationResult {
|
|
61
|
-
if (uri.length > CREATION_VALIDATION.MAX_URI_LENGTH) {
|
|
62
|
-
return {
|
|
63
|
-
isValid: false,
|
|
64
|
-
error: `URI length (${uri.length}) exceeds maximum (${CREATION_VALIDATION.MAX_URI_LENGTH})`,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return { isValid: true };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Runs all validations and returns first error
|
|
55
|
+
* Runs all validations using shared kernel utilities
|
|
73
56
|
*/
|
|
74
57
|
export function runAllValidations(
|
|
75
58
|
imageUrl?: string,
|
|
76
59
|
videoUrl?: string
|
|
77
60
|
): ValidationResult {
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
// Check that at least one URL is present
|
|
62
|
+
const hasUrlCheck = validateHasUrl(imageUrl, videoUrl);
|
|
63
|
+
if (!hasUrlCheck.isValid) return hasUrlCheck;
|
|
80
64
|
|
|
81
65
|
const uri = imageUrl || videoUrl || "";
|
|
66
|
+
|
|
67
|
+
// Use shared URL validation
|
|
68
|
+
const urlValidation = validateUrl(uri);
|
|
69
|
+
if (!urlValidation.isValid) return urlValidation;
|
|
70
|
+
|
|
71
|
+
// Use shared string validation for length
|
|
72
|
+
const lengthValidation = validateString(uri, {
|
|
73
|
+
maxLength: CREATION_VALIDATION.MAX_URI_LENGTH,
|
|
74
|
+
});
|
|
75
|
+
if (!lengthValidation.isValid) return lengthValidation;
|
|
76
|
+
|
|
77
|
+
// Validate protocol
|
|
82
78
|
const protocolCheck = validateUriProtocol(uri);
|
|
83
79
|
if (!protocolCheck.isValid) return protocolCheck;
|
|
84
80
|
|
|
85
|
-
|
|
81
|
+
// Combine all results
|
|
82
|
+
return combineValidationResults(
|
|
83
|
+
hasUrlCheck,
|
|
84
|
+
urlValidation,
|
|
85
|
+
lengthValidation,
|
|
86
|
+
protocolCheck
|
|
87
|
+
);
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
/**
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Processing Jobs Poller Hook
|
|
3
|
+
* Polls queue status for "processing" creations and updates Firestore when complete
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { useProcessingJobsPoller } from "./useProcessingJobsPoller";
|
|
7
|
+
export type {
|
|
8
|
+
UseProcessingJobsPollerConfig,
|
|
9
|
+
UseProcessingJobsPollerReturn,
|
|
10
|
+
} from "./useProcessingJobsPoller";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Processing Jobs Poller - Filters
|
|
3
|
+
* Filter functions for processing jobs
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Creation } from "../../domain/entities/Creation";
|
|
7
|
+
import { CREATION_STATUS } from "../../../../domain/constants/queue-status.constants";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Filter processing jobs with valid IDs
|
|
11
|
+
*/
|
|
12
|
+
export function getProcessingJobIds(creations: Creation[]): string[] {
|
|
13
|
+
return creations
|
|
14
|
+
.filter((c) => c.status === CREATION_STATUS.PROCESSING && c.requestId && c.model)
|
|
15
|
+
.map((c) => c.id);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Filter processing jobs with valid IDs
|
|
20
|
+
*/
|
|
21
|
+
export function getProcessingJobs(creations: Creation[]): Creation[] {
|
|
22
|
+
return creations.filter(
|
|
23
|
+
(c) => c.status === CREATION_STATUS.PROCESSING && c.requestId && c.model,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Filter orphan jobs (processing but no requestId/model)
|
|
29
|
+
*/
|
|
30
|
+
export function getOrphanJobs(creations: Creation[]): Creation[] {
|
|
31
|
+
return creations.filter(
|
|
32
|
+
(c) => c.status === CREATION_STATUS.PROCESSING && !c.requestId && !c.model,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Processing Jobs Poller - Logger
|
|
3
|
+
* Logging utilities for job polling
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Log status check
|
|
8
|
+
*/
|
|
9
|
+
export function logStatusCheck(creationId: string): void {
|
|
10
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
11
|
+
console.log("[ProcessingJobsPoller] Checking status:", creationId);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Log status result
|
|
17
|
+
*/
|
|
18
|
+
export function logStatusResult(creationId: string, status: string): void {
|
|
19
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
20
|
+
console.log("[ProcessingJobsPoller] Status:", creationId, status);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Log completed job
|
|
26
|
+
*/
|
|
27
|
+
export function logJobCompleted(creationId: string, urls: unknown): void {
|
|
28
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
29
|
+
console.log("[ProcessingJobsPoller] Completed:", creationId, urls);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Log no valid URI error
|
|
35
|
+
*/
|
|
36
|
+
export function logNoValidUri(creationId: string): void {
|
|
37
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
38
|
+
console.error("[ProcessingJobsPoller] No valid URI in result:", creationId);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Log failed job
|
|
44
|
+
*/
|
|
45
|
+
export function logJobFailed(creationId: string): void {
|
|
46
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
47
|
+
console.log("[ProcessingJobsPoller] Failed:", creationId);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Log poll error
|
|
53
|
+
*/
|
|
54
|
+
export function logPollError(creationId: string, error: unknown): void {
|
|
55
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
56
|
+
console.error("[ProcessingJobsPoller] Poll error:", creationId, error);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Log orphan job timeout
|
|
62
|
+
*/
|
|
63
|
+
export function logOrphanTimeout(creationId: string): void {
|
|
64
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
65
|
+
console.log("[ProcessingJobsPoller] Orphan job timed out, marking as failed:", creationId);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Log failed to clean up orphans
|
|
71
|
+
*/
|
|
72
|
+
export function logCleanupOrphansFailed(error: unknown): void {
|
|
73
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
74
|
+
console.error("[ProcessingJobsPoller] Failed to clean up orphan jobs:", error);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Processing Jobs Poller - Stale Job Handlers
|
|
3
|
+
* Functions for handling stale jobs
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Creation } from "../../domain/entities/Creation";
|
|
7
|
+
import type { ICreationsRepository } from "../../domain/repositories/ICreationsRepository";
|
|
8
|
+
import { CREATION_STATUS } from "../../../../domain/constants/queue-status.constants";
|
|
9
|
+
import { DEFAULT_MAX_POLL_TIME_MS } from "../../../../infrastructure/constants/polling.constants";
|
|
10
|
+
import { isOlderThan, calculateAgeMs } from "../../../../shared/utils/calculations";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Check if job is stale (older than max poll time)
|
|
14
|
+
*/
|
|
15
|
+
export function isJobStale(creation: Creation): boolean {
|
|
16
|
+
return isOlderThan(creation.createdAt, DEFAULT_MAX_POLL_TIME_MS);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Log stale job detection
|
|
21
|
+
*/
|
|
22
|
+
export function logStaleJob(creationId: string): void {
|
|
23
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
24
|
+
console.log("[ProcessingJobsPoller] Stale job detected, marking as failed:", creationId, {
|
|
25
|
+
ageMs: calculateAgeMs(creationId ? new Date() : new Date()),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Log failed to mark stale job
|
|
32
|
+
*/
|
|
33
|
+
export function logMarkStaleFailed(error: unknown): void {
|
|
34
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
35
|
+
console.error("[ProcessingJobsPoller] Failed to mark stale job:", error);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Mark stale job as failed
|
|
41
|
+
*/
|
|
42
|
+
export async function markJobAsFailed(
|
|
43
|
+
repository: ICreationsRepository,
|
|
44
|
+
userId: string,
|
|
45
|
+
creation: Creation
|
|
46
|
+
): Promise<void> {
|
|
47
|
+
await repository.update(userId, creation.id, {
|
|
48
|
+
status: CREATION_STATUS.FAILED,
|
|
49
|
+
metadata: { ...creation.metadata, error: "Generation timed out" },
|
|
50
|
+
completedAt: new Date(),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Processing Jobs Poller - Utility Functions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { getProcessingJobIds, getProcessingJobs, getOrphanJobs } from "./job-poller-utils.filters";
|
|
6
|
+
export { isJobStale, logStaleJob, logMarkStaleFailed, markJobAsFailed } from "./job-poller-utils.stale-handlers";
|
|
7
|
+
export { logStatusCheck, logStatusResult, logJobCompleted, logNoValidUri, logJobFailed, logPollError, logOrphanTimeout, logCleanupOrphansFailed } from "./job-poller-utils.logger";
|
|
8
|
+
|
|
@@ -14,7 +14,7 @@ import { GalleryResultPreview } from "../components/GalleryResultPreview";
|
|
|
14
14
|
import { GalleryScreenHeader } from "../components/GalleryScreenHeader";
|
|
15
15
|
import { MEDIA_FILTER_OPTIONS, STATUS_FILTER_OPTIONS } from "../../domain/types/creation-filter";
|
|
16
16
|
import { createFilterButtons, createItemTitle } from "../utils/filter-buttons.util";
|
|
17
|
-
import { calculatePaginationSlice, calculateHasMore } from "../../../../shared/utils/calculations
|
|
17
|
+
import { calculatePaginationSlice, calculateHasMore } from "../../../../shared/utils/calculations";
|
|
18
18
|
import type { Creation } from "../../domain/entities/Creation";
|
|
19
19
|
import type { CreationsGalleryScreenProps } from "./creations-gallery.types";
|
|
20
20
|
import { creationsGalleryStyles as styles } from "./creations-gallery.styles";
|
|
@@ -14,11 +14,11 @@ export type {
|
|
|
14
14
|
BaseProcessingStartData,
|
|
15
15
|
BaseProcessingResult,
|
|
16
16
|
} from "./presentation/hooks/useCreationPersistence";
|
|
17
|
-
export { useProcessingJobsPoller } from "./presentation/hooks/
|
|
17
|
+
export { useProcessingJobsPoller } from "./presentation/hooks/job-poller-index";
|
|
18
18
|
export type {
|
|
19
19
|
UseProcessingJobsPollerConfig,
|
|
20
20
|
UseProcessingJobsPollerReturn,
|
|
21
|
-
} from "./presentation/hooks/
|
|
21
|
+
} from "./presentation/hooks/job-poller-index";
|
|
22
22
|
|
|
23
23
|
// Core Components
|
|
24
24
|
export { CreationPreview } from "./presentation/components/CreationPreview";
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Face Detection Types
|
|
3
|
+
* Uses shared kernel base types
|
|
3
4
|
*/
|
|
4
5
|
|
|
6
|
+
import type { BaseFeatureState } from '../../../../shared-kernel/base-types';
|
|
7
|
+
|
|
5
8
|
export interface FaceDetectionResult {
|
|
6
9
|
hasFace: boolean;
|
|
7
10
|
confidence: number;
|
|
8
11
|
message: string;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
|
-
export interface FaceValidationState {
|
|
14
|
+
export interface FaceValidationState extends BaseFeatureState<FaceDetectionResult> {
|
|
12
15
|
isValidating: boolean;
|
|
13
|
-
result: FaceDetectionResult | null;
|
|
14
|
-
error: string | null;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export interface FaceDetectionConfig {
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* useFaceDetection Hook
|
|
3
3
|
*
|
|
4
|
-
* React hook for face detection functionality.
|
|
4
|
+
* React hook for face detection functionality using shared kernel.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { useCallback } from "react";
|
|
8
8
|
import type {
|
|
9
9
|
FaceValidationState,
|
|
10
10
|
FaceDetectionResult,
|
|
11
11
|
} from "../../domain/entities/FaceDetection";
|
|
12
12
|
import { analyzeImageForFace, type AIAnalyzerFunction } from "../../infrastructure/analyzers/faceAnalyzer";
|
|
13
13
|
import { isValidFace } from "../../infrastructure/validators/faceValidator";
|
|
14
|
+
import { useFeatureState } from "../../../../shared-kernel/application/hooks";
|
|
15
|
+
import { handleError, ErrorType } from "../../../../shared-kernel/infrastructure/validation";
|
|
14
16
|
|
|
15
17
|
interface UseFaceDetectionProps {
|
|
16
18
|
aiAnalyzer: AIAnalyzerFunction;
|
|
@@ -24,38 +26,39 @@ interface UseFaceDetectionReturn {
|
|
|
24
26
|
reset: () => void;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
const initialState: FaceValidationState = {
|
|
28
|
-
isValidating: false,
|
|
29
|
-
result: null,
|
|
30
|
-
error: null,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
29
|
export const useFaceDetection = ({ aiAnalyzer, model }: UseFaceDetectionProps): UseFaceDetectionReturn => {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
const validateImage = useCallback(async (base64Image: string) => {
|
|
37
|
-
setState({ isValidating: true, result: null, error: null });
|
|
30
|
+
const { state, actions } = useFeatureState<FaceDetectionResult>();
|
|
38
31
|
|
|
32
|
+
const validateImage = useCallback(async (base64Image: string): Promise<FaceDetectionResult> => {
|
|
39
33
|
try {
|
|
34
|
+
actions.startProcessing();
|
|
35
|
+
|
|
40
36
|
const result = await analyzeImageForFace(base64Image, aiAnalyzer, model);
|
|
41
|
-
|
|
37
|
+
|
|
38
|
+
actions.setSuccess(result);
|
|
42
39
|
return result;
|
|
43
40
|
} catch (error) {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
const appError = handleError(error, {
|
|
42
|
+
logErrors: true,
|
|
43
|
+
showUserMessage: true,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
actions.setError(appError.message);
|
|
47
47
|
throw error;
|
|
48
48
|
}
|
|
49
|
-
}, [aiAnalyzer, model]);
|
|
49
|
+
}, [aiAnalyzer, model, actions]);
|
|
50
50
|
|
|
51
51
|
const reset = useCallback(() => {
|
|
52
|
-
|
|
53
|
-
}, []);
|
|
52
|
+
actions.reset();
|
|
53
|
+
}, [actions]);
|
|
54
54
|
|
|
55
|
-
const isValid = state.
|
|
55
|
+
const isValid = state.output !== null ? isValidFace(state.output) : false;
|
|
56
56
|
|
|
57
57
|
return {
|
|
58
|
-
state
|
|
58
|
+
state: {
|
|
59
|
+
...state,
|
|
60
|
+
isValidating: state.isProcessing,
|
|
61
|
+
},
|
|
59
62
|
validateImage,
|
|
60
63
|
isValid,
|
|
61
64
|
reset,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Couple Image Generation Builder - Preparation Phase
|
|
3
|
+
*
|
|
4
|
+
* Handles photo URI extraction and appearance analysis
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { getAppearanceContext } from "./appearance-analysis";
|
|
8
|
+
import { logBuilderStep } from "./utils";
|
|
9
|
+
import type { CoupleGenerationInputParams } from "./types";
|
|
10
|
+
|
|
11
|
+
export interface CouplePreparationResult {
|
|
12
|
+
photoUris: string[];
|
|
13
|
+
appearanceContext: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Prepare photo URIs and analyze appearance
|
|
18
|
+
*/
|
|
19
|
+
export async function prepareCoupleGeneration(
|
|
20
|
+
params: CoupleGenerationInputParams,
|
|
21
|
+
prefix: string = "[CoupleBuilder]",
|
|
22
|
+
): Promise<CouplePreparationResult> {
|
|
23
|
+
const {
|
|
24
|
+
partner1PhotoUri,
|
|
25
|
+
partner2PhotoUri,
|
|
26
|
+
isCoupleMode,
|
|
27
|
+
} = params;
|
|
28
|
+
|
|
29
|
+
// 1. GET PHOTO URIs - Couple mode kontrolü
|
|
30
|
+
const photoUris =
|
|
31
|
+
isCoupleMode && partner2PhotoUri
|
|
32
|
+
? [partner1PhotoUri, partner2PhotoUri]
|
|
33
|
+
: [partner1PhotoUri];
|
|
34
|
+
|
|
35
|
+
logBuilderStep(prefix, "STEP 1: PHOTO URIs", {
|
|
36
|
+
photoUrisCount: photoUris.length,
|
|
37
|
+
photo1: photoUris[0],
|
|
38
|
+
photo2: photoUris[1],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// 2. ANALYZE APPEARANCE - Wardrobe'daki gibi
|
|
42
|
+
logBuilderStep(prefix, "STEP 2: APPEARANCE ANALYSIS", {
|
|
43
|
+
photoCount: photoUris.length,
|
|
44
|
+
isCoupleMode
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const appearanceContext = await getAppearanceContext(
|
|
48
|
+
photoUris,
|
|
49
|
+
isCoupleMode,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
logBuilderStep(prefix, "Appearance Analysis Result", {
|
|
53
|
+
contextLength: appearanceContext.length,
|
|
54
|
+
contextPreview: appearanceContext.substring(0, 150),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return { photoUris, appearanceContext };
|
|
58
|
+
}
|