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

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 (171) hide show
  1. package/package.json +3 -3
  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/domain/interfaces/index.ts +3 -0
  7. package/src/domains/background/infrastructure/services/job-poller-index.ts +7 -0
  8. package/src/domains/background/infrastructure/services/job-poller-utils.ts +127 -0
  9. package/src/domains/background/infrastructure/services/job-poller.service.ts +85 -140
  10. package/src/domains/background/infrastructure/utils/polling-interval.util.ts +1 -1
  11. package/src/domains/background/presentation/hooks/use-background-generation.ts +1 -1
  12. package/src/domains/content-moderation/index.ts +7 -13
  13. package/src/domains/content-moderation/infrastructure/services/content-moderation.service.ts +1 -1
  14. package/src/domains/content-moderation/infrastructure/services/moderators/image.moderator.ts +34 -8
  15. package/src/domains/content-moderation/infrastructure/services/moderators/text.moderator.ts +15 -4
  16. package/src/domains/content-moderation/infrastructure/services/moderators/video.moderator.ts +34 -8
  17. package/src/domains/content-moderation/infrastructure/services/moderators/voice.moderator.ts +19 -8
  18. package/src/domains/content-moderation/infrastructure/services/pattern-matcher.service.ts +1 -2
  19. package/src/domains/creations/domain/types/creation-categories.constants.ts +57 -0
  20. package/src/domains/creations/domain/types/creation-categories.helpers.ts +67 -0
  21. package/src/domains/creations/domain/types/creation-categories.ts +7 -114
  22. package/src/domains/creations/domain/utils/creation-display.util.ts +1 -1
  23. package/src/domains/creations/domain/utils/status-helpers.ts +1 -1
  24. package/src/domains/creations/presentation/hooks/creation-validators.ts +31 -29
  25. package/src/domains/creations/presentation/hooks/job-poller-index.ts +10 -0
  26. package/src/domains/creations/presentation/hooks/job-poller-utils.filters.ts +34 -0
  27. package/src/domains/creations/presentation/hooks/job-poller-utils.logger.ts +76 -0
  28. package/src/domains/creations/presentation/hooks/job-poller-utils.stale-handlers.ts +52 -0
  29. package/src/domains/creations/presentation/hooks/job-poller-utils.ts +8 -0
  30. package/src/domains/creations/presentation/hooks/useCreations.ts +1 -1
  31. package/src/domains/creations/presentation/hooks/useProcessingJobsPoller.ts +18 -235
  32. package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +1 -2
  33. package/src/domains/creations/presentation-exports.ts +2 -2
  34. package/src/domains/face-detection/domain/entities/FaceDetection.ts +4 -3
  35. package/src/domains/face-detection/presentation/hooks/useFaceDetection.ts +24 -21
  36. package/src/domains/generation/infrastructure/appearance-analysis/index.ts +5 -0
  37. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-preparation.ts +58 -0
  38. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-prompt.ts +69 -0
  39. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-resolution.ts +77 -0
  40. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple.ts +54 -0
  41. package/src/domains/generation/infrastructure/couple-generation-builder/builder-index.ts +8 -0
  42. package/src/domains/generation/infrastructure/couple-generation-builder/builder-scenario.ts +112 -0
  43. package/src/domains/generation/infrastructure/couple-generation-builder/builder.ts +7 -0
  44. package/src/domains/generation/infrastructure/couple-generation-builder/index.ts +20 -0
  45. package/src/domains/generation/infrastructure/couple-generation-builder/types.ts +44 -0
  46. package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-end-logger.ts +18 -0
  47. package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-start-logger.ts +57 -0
  48. package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-step-logger.ts +106 -0
  49. package/src/domains/generation/infrastructure/couple-generation-builder/utils/index.ts +8 -0
  50. package/src/domains/generation/infrastructure/couple-generation-builder/utils/types.ts +49 -0
  51. package/src/domains/generation/infrastructure/couple-generation-builder/utils.ts +8 -0
  52. package/src/domains/generation/infrastructure/flow/flow-store-actions.ts +105 -0
  53. package/src/domains/generation/infrastructure/flow/flow-store-initial-state.ts +26 -0
  54. package/src/domains/generation/infrastructure/flow/useFlowStore.ts +4 -116
  55. package/src/domains/generation/presentation/useAIGeneration.hook.ts +1 -1
  56. package/src/domains/generation/wizard/infrastructure/strategies/image-generation-strategy-index.ts +7 -0
  57. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.ts +2 -12
  58. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.types.ts +11 -0
  59. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.utils.ts +12 -0
  60. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +1 -220
  61. package/src/domains/generation/wizard/infrastructure/strategies/image-input-builder.ts +66 -0
  62. package/src/domains/generation/wizard/infrastructure/strategies/image-input-extraction.ts +88 -0
  63. package/src/domains/generation/wizard/infrastructure/strategies/image-input-prompt-builder.ts +74 -0
  64. package/src/domains/generation/wizard/infrastructure/strategies/image-input-style-enhancements.ts +35 -0
  65. package/src/domains/generation/wizard/infrastructure/strategies/image-strategy-factory.ts +41 -0
  66. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor-index.ts +10 -0
  67. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor.ts +76 -0
  68. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-input-builder.ts +46 -0
  69. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-result-types.ts +17 -0
  70. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-submission.ts +61 -0
  71. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.audio-extractor.ts +27 -0
  72. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.executor.ts +2 -176
  73. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.input-builder.ts +90 -0
  74. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +3 -108
  75. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.types.ts +0 -130
  76. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.validation.ts +136 -0
  77. package/src/domains/generation/wizard/presentation/hooks/photo-upload/index.ts +40 -0
  78. package/src/domains/generation/wizard/presentation/hooks/photo-upload/types.ts +37 -0
  79. package/src/domains/generation/wizard/presentation/hooks/photo-upload/usePhotoUploadStateLogic.ts +142 -0
  80. package/src/domains/generation/wizard/presentation/hooks/use-video-queue-utils.ts +102 -0
  81. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.handlers.ts +97 -0
  82. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.saver.ts +54 -0
  83. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.ts +22 -87
  84. package/src/domains/generation/wizard/presentation/hooks/usePhotoUploadState.ts +8 -177
  85. package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +1 -295
  86. package/src/domains/generation/wizard/presentation/hooks/useWizardGeneration.ts +1 -1
  87. package/src/domains/generation/wizard/presentation/hooks/video-queue/index.ts +77 -0
  88. package/src/domains/generation/wizard/presentation/hooks/video-queue/use-video-queue-utils.ts +123 -0
  89. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationCallbacks.ts +119 -0
  90. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationPolling.ts +75 -0
  91. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationRefs.ts +65 -0
  92. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationStart.ts +123 -0
  93. package/src/domains/generation/wizard/presentation/hooks/video-queue-index.ts +9 -0
  94. package/src/domains/image-to-video/domain/types/image-to-video-state.types.ts +11 -4
  95. package/src/domains/text-to-image/domain/constants/index.ts +5 -6
  96. package/src/domains/text-to-image/domain/types/text-to-image.types.ts +43 -22
  97. package/src/domains/text-to-video/domain/types/request.types.ts +32 -9
  98. package/src/domains/text-to-video/domain/types/state.types.ts +22 -22
  99. package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.handlers.ts +44 -0
  100. package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.ts +5 -51
  101. package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.types.ts +33 -0
  102. package/src/exports/features.ts +1 -1
  103. package/src/infrastructure/services/generation-orchestrator.service.ts +2 -2
  104. package/src/infrastructure/utils/couple-input-context.ts +13 -0
  105. package/src/infrastructure/utils/couple-input-index.ts +9 -0
  106. package/src/infrastructure/utils/couple-input-photorealistic.ts +40 -0
  107. package/src/infrastructure/utils/couple-input-refiner.ts +101 -0
  108. package/src/infrastructure/utils/couple-input-resolver.ts +71 -0
  109. package/src/infrastructure/utils/couple-input-types.ts +11 -0
  110. package/src/infrastructure/utils/couple-input.util.ts +3 -176
  111. package/src/infrastructure/utils/photo-generation/photo-preparation.util.ts +1 -1
  112. package/src/infrastructure/validation/base-validator.ts +3 -26
  113. package/src/infrastructure/validation/base-validator.types.ts +32 -0
  114. package/src/presentation/hooks/generation/index.ts +1 -1
  115. package/src/presentation/hooks/generation/orchestrator-abort-logs.ts +48 -0
  116. package/src/presentation/hooks/generation/orchestrator-execution-logs.ts +67 -0
  117. package/src/presentation/hooks/generation/orchestrator-index.ts +14 -0
  118. package/src/presentation/hooks/generation/orchestrator-start-logs.ts +65 -0
  119. package/src/presentation/hooks/generation/orchestrator-state-utils.ts +17 -0
  120. package/src/presentation/hooks/generation/orchestrator-types.ts +55 -0
  121. package/src/presentation/hooks/generation/orchestrator-utils-index.ts +29 -0
  122. package/src/presentation/hooks/generation/orchestrator-utils.ts +25 -0
  123. package/src/presentation/hooks/generation/useDualImageGeneration.ts +1 -1
  124. package/src/presentation/hooks/generation/useImageGeneration.ts +1 -1
  125. package/src/presentation/hooks/generation/useVideoGeneration.ts +1 -1
  126. package/src/shared/hooks/factories/generation-hook-index.ts +12 -0
  127. package/src/shared/hooks/factories/generation-hook-types.ts +47 -0
  128. package/src/shared/hooks/factories/generation-hook-utils.ts +94 -0
  129. package/src/shared/hooks/factories/index.ts +1 -1
  130. package/src/shared/index.ts +1 -1
  131. package/src/shared/utils/calculations/aspect-ratio-calculations.ts +30 -0
  132. package/src/shared/utils/calculations/base64-calculations.ts +26 -0
  133. package/src/shared/utils/calculations/confidence-calculations.ts +21 -0
  134. package/src/shared/utils/calculations/cost-calculations-index.ts +43 -0
  135. package/src/shared/utils/calculations/cost-calculations.ts +25 -0
  136. package/src/shared/utils/calculations/credit-calculations.ts +37 -0
  137. package/src/shared/utils/calculations/index.ts +46 -0
  138. package/src/shared/utils/calculations/math-utilities.ts +32 -0
  139. package/src/shared/utils/calculations/memory-calculations.ts +33 -0
  140. package/src/shared/utils/calculations/pagination-calculations.ts +38 -0
  141. package/src/shared/utils/calculations/percentage-calculations.ts +33 -0
  142. package/src/shared/utils/calculations/time-calculations.ts +99 -0
  143. package/src/shared/utils/credit.ts +1 -1
  144. package/src/shared-kernel/application/hooks/index.ts +8 -0
  145. package/src/shared-kernel/application/hooks/use-feature-state.ts +106 -0
  146. package/src/shared-kernel/application/hooks/use-generation-handler.ts +110 -0
  147. package/src/shared-kernel/base-types/base-callbacks.types.ts +73 -0
  148. package/src/shared-kernel/base-types/base-feature-state.types.ts +77 -0
  149. package/src/shared-kernel/base-types/base-generation.types.ts +69 -0
  150. package/src/shared-kernel/base-types/index.ts +30 -0
  151. package/src/shared-kernel/domain/base-generation-strategy.ts +146 -0
  152. package/src/shared-kernel/domain/index.ts +7 -0
  153. package/src/shared-kernel/index.ts +17 -0
  154. package/src/shared-kernel/infrastructure/validation/common-validators.ts +126 -0
  155. package/src/shared-kernel/infrastructure/validation/common-validators.types.ts +33 -0
  156. package/src/shared-kernel/infrastructure/validation/error-handler.ts +52 -0
  157. package/src/shared-kernel/infrastructure/validation/error-handler.types.ts +38 -0
  158. package/src/shared-kernel/infrastructure/validation/error-handler.utils.ts +79 -0
  159. package/src/shared-kernel/infrastructure/validation/index.ts +70 -0
  160. package/src/domains/content-moderation/infrastructure/services/index.ts +0 -8
  161. package/src/domains/creations/domain/constants/index.ts +0 -12
  162. package/src/domains/creations/domain/utils/index.ts +0 -12
  163. package/src/domains/generation/infrastructure/couple-generation-builder.ts +0 -374
  164. package/src/domains/image-to-video/domain/index.ts +0 -2
  165. package/src/domains/image-to-video/infrastructure/index.ts +0 -1
  166. package/src/domains/image-to-video/presentation/index.ts +0 -5
  167. package/src/domains/text-to-video/domain/index.ts +0 -1
  168. package/src/domains/text-to-video/presentation/index.ts +0 -7
  169. package/src/presentation/hooks/generation/orchestrator.ts +0 -276
  170. package/src/shared/hooks/factories/createGenerationHook.ts +0 -253
  171. package/src/shared/utils/calculations.util.ts +0 -366
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Video Queue Generation Hook - Completion and Error Handlers
3
+ */
4
+
5
+ import { useCallback } from "react";
6
+ import type { GenerationUrls } from "../../generation-result.utils";
7
+ import type {
8
+ UseVideoQueueGenerationProps,
9
+ } from "../use-video-queue-generation.types";
10
+ import {
11
+ logCompletion,
12
+ logError,
13
+ validateCompletionData,
14
+ } from "./use-video-queue-utils";
15
+ import type { VideoQueueRefs, VideoQueueState } from "./useVideoQueueGenerationRefs";
16
+
17
+ /**
18
+ * Create completion handler callback
19
+ */
20
+ export function useCompletionHandler(
21
+ props: UseVideoQueueGenerationProps,
22
+ refs: VideoQueueRefs,
23
+ state: VideoQueueState,
24
+ clearPolling: () => void,
25
+ resetRefs: () => void,
26
+ ) {
27
+ const { userId, persistence, creditCost, deductCredits, onSuccess, onError } = props;
28
+
29
+ return useCallback(
30
+ async (urls: GenerationUrls) => {
31
+ clearPolling();
32
+
33
+ const creationId = refs.creationIdRef.current;
34
+ const uri = (urls.videoUrl || urls.imageUrl) ?? "";
35
+
36
+ logCompletion(creationId, userId, urls, !!onSuccess);
37
+
38
+ if (!validateCompletionData(creationId, userId, uri)) {
39
+ logError("Invalid completion data:", { creationId, userId, uri });
40
+ resetRefs();
41
+ onError?.("Invalid completion data - no valid URL received");
42
+ return;
43
+ }
44
+
45
+ let persistenceSucceeded = true;
46
+ if (creationId && userId) {
47
+ try {
48
+ await persistence.updateToCompleted(userId, creationId, {
49
+ uri,
50
+ imageUrl: urls.imageUrl,
51
+ videoUrl: urls.videoUrl,
52
+ thumbnailUrl: urls.thumbnailUrl,
53
+ generationStartedAt: refs.pollStartTimeRef.current ?? undefined,
54
+ });
55
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
56
+ console.log("[VideoQueue] ✅ Updated completion status in Firestore");
57
+ }
58
+ } catch (error) {
59
+ persistenceSucceeded = false;
60
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
61
+ console.error("[VideoQueue] ❌ Failed to update completion status:", error);
62
+ }
63
+ }
64
+ }
65
+
66
+ resetRefs();
67
+
68
+ // Deduct credits after successful generation
69
+ if (deductCredits && creditCost) {
70
+ await deductCredits(creditCost).catch((err) => {
71
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
72
+ console.error("[VideoQueue] deductCredits error:", err);
73
+ }
74
+ });
75
+ }
76
+
77
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
78
+ console.log("[VideoQueue] 🎯 Calling onSuccess callback now...", { persistenceSucceeded });
79
+ }
80
+ onSuccess?.(urls);
81
+
82
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
83
+ console.log("[VideoQueue] ✅ onSuccess callback completed");
84
+ }
85
+ },
86
+ [userId, persistence, deductCredits, creditCost, onSuccess, onError, resetRefs, clearPolling, refs],
87
+ );
88
+ }
89
+
90
+ /**
91
+ * Create error handler callback
92
+ */
93
+ export function useErrorHandler(
94
+ props: UseVideoQueueGenerationProps,
95
+ refs: VideoQueueRefs,
96
+ clearPolling: () => void,
97
+ resetRefs: () => void,
98
+ ) {
99
+ const { userId, persistence, onError } = props;
100
+
101
+ return useCallback(
102
+ async (errorMsg: string) => {
103
+ clearPolling();
104
+ const creationId = refs.creationIdRef.current;
105
+ if (creationId && userId) {
106
+ try {
107
+ await persistence.updateToFailed(userId, creationId, errorMsg);
108
+ } catch (error) {
109
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
110
+ console.error("[VideoQueue] Failed to update error status:", error);
111
+ }
112
+ }
113
+ }
114
+ resetRefs();
115
+ onError?.(errorMsg);
116
+ },
117
+ [userId, persistence, onError, resetRefs, clearPolling, refs],
118
+ );
119
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Video Queue Generation Hook - Polling Logic
3
+ */
4
+
5
+ import { useCallback, useEffect } from "react";
6
+ import { pollQueueStatus } from "../videoQueuePoller";
7
+ import {
8
+ DEFAULT_MAX_POLL_TIME_MS,
9
+ } from "../../../../../../infrastructure/constants/polling.constants";
10
+ import type { VideoQueueRefs } from "./useVideoQueueGenerationRefs";
11
+
12
+ /**
13
+ * Create poll status callback
14
+ */
15
+ export function usePollStatus(
16
+ refs: VideoQueueRefs,
17
+ ): () => Promise<void> {
18
+ const { requestIdRef, modelRef, isPollingRef, pollingRef, consecutiveErrorsRef, pollStartTimeRef, handleCompleteRef, handleErrorRef } = refs;
19
+
20
+ return useCallback(async () => {
21
+ const requestId = requestIdRef.current;
22
+ const model = modelRef.current;
23
+ if (!requestId || !model) return;
24
+
25
+ // Check max poll time
26
+ if (pollStartTimeRef.current !== null) {
27
+ const elapsed = Date.now() - pollStartTimeRef.current;
28
+ if (elapsed >= DEFAULT_MAX_POLL_TIME_MS) {
29
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
30
+ console.warn("[VideoQueue] ⏰ Max poll time exceeded, aborting");
31
+ }
32
+ await handleErrorRef.current("Generation timed out. Please try again.");
33
+ return;
34
+ }
35
+ }
36
+
37
+ try {
38
+ await pollQueueStatus({
39
+ requestId,
40
+ model,
41
+ isPollingRef,
42
+ pollingRef,
43
+ consecutiveErrorsRef,
44
+ onComplete: handleCompleteRef.current,
45
+ onError: handleErrorRef.current,
46
+ });
47
+ } catch (error) {
48
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
49
+ console.error("[VideoQueue] Unexpected poll error:", error);
50
+ }
51
+ }
52
+ }, [requestIdRef, modelRef, isPollingRef, pollingRef, consecutiveErrorsRef, pollStartTimeRef, handleCompleteRef, handleErrorRef]);
53
+ }
54
+
55
+ /**
56
+ * Hook to sync callback refs
57
+ */
58
+ export function useCallbackRefs(
59
+ handleComplete: (urls: import("../../generation-result.utils").GenerationUrls) => Promise<void>,
60
+ handleError: (errorMsg: string) => Promise<void>,
61
+ pollStatus: () => Promise<void>,
62
+ refs: VideoQueueRefs,
63
+ ) {
64
+ useEffect(() => {
65
+ refs.handleCompleteRef.current = handleComplete;
66
+ }, [handleComplete, refs]);
67
+
68
+ useEffect(() => {
69
+ refs.handleErrorRef.current = handleError;
70
+ }, [handleError, refs]);
71
+
72
+ useEffect(() => {
73
+ refs.pollStatusRef.current = pollStatus;
74
+ }, [pollStatus, refs]);
75
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Video Queue Generation Hook - Refs and State Management
3
+ */
4
+
5
+ import { useRef, useState } from "react";
6
+
7
+ export interface VideoQueueRefs {
8
+ readonly creationIdRef: React.MutableRefObject<string | null>;
9
+ readonly requestIdRef: React.MutableRefObject<string | null>;
10
+ readonly modelRef: React.MutableRefObject<string | null>;
11
+ readonly pollingRef: React.MutableRefObject<ReturnType<typeof setInterval> | null>;
12
+ readonly isGeneratingRef: React.MutableRefObject<boolean>;
13
+ readonly isPollingRef: React.MutableRefObject<boolean>;
14
+ readonly consecutiveErrorsRef: React.MutableRefObject<number>;
15
+ readonly pollStartTimeRef: React.MutableRefObject<number | null>;
16
+ readonly handleCompleteRef: React.MutableRefObject<(urls: import("../generation-result.utils").GenerationUrls) => Promise<void>>;
17
+ readonly handleErrorRef: React.MutableRefObject<(errorMsg: string) => Promise<void>>;
18
+ readonly pollStatusRef: React.MutableRefObject<() => Promise<void>>;
19
+ }
20
+
21
+ export interface VideoQueueState {
22
+ readonly isGenerating: boolean;
23
+ readonly setIsGenerating: React.Dispatch<React.SetStateAction<boolean>>;
24
+ }
25
+
26
+ /**
27
+ * Initialize refs for video queue generation
28
+ */
29
+ export function useVideoQueueGenerationRefs(): VideoQueueRefs {
30
+ const creationIdRef = useRef<string | null>(null);
31
+ const requestIdRef = useRef<string | null>(null);
32
+ const modelRef = useRef<string | null>(null);
33
+ const pollingRef = useRef<ReturnType<typeof setInterval> | null>(null);
34
+ const isGeneratingRef = useRef(false);
35
+ const isPollingRef = useRef(false);
36
+ const consecutiveErrorsRef = useRef(0);
37
+ const pollStartTimeRef = useRef<number | null>(null);
38
+
39
+ // Placeholders for callback refs - will be set by the hook
40
+ const handleCompleteRef = useRef<VideoQueueRefs["handleCompleteRef"]["current"]>(async () => {});
41
+ const handleErrorRef = useRef<VideoQueueRefs["handleErrorRef"]["current"]>(async () => {});
42
+ const pollStatusRef = useRef<VideoQueueRefs["pollStatusRef"]["current"]>(async () => {});
43
+
44
+ return {
45
+ creationIdRef,
46
+ requestIdRef,
47
+ modelRef,
48
+ pollingRef,
49
+ isGeneratingRef,
50
+ isPollingRef,
51
+ consecutiveErrorsRef,
52
+ pollStartTimeRef,
53
+ handleCompleteRef,
54
+ handleErrorRef,
55
+ pollStatusRef,
56
+ };
57
+ }
58
+
59
+ /**
60
+ * Initialize state for video queue generation
61
+ */
62
+ export function useVideoQueueGenerationState(): VideoQueueState {
63
+ const [isGenerating, setIsGenerating] = useState(false);
64
+ return { isGenerating, setIsGenerating };
65
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Video Queue Generation Hook - Start Generation Logic
3
+ */
4
+
5
+ import { useCallback } from "react";
6
+ import {
7
+ DEFAULT_POLL_INTERVAL_MS,
8
+ } from "../../../../../../infrastructure/constants/polling.constants";
9
+ import { extractInputMetadata } from "./use-video-queue-utils";
10
+ import type {
11
+ UseVideoQueueGenerationProps,
12
+ } from "../use-video-queue-generation.types";
13
+ import type { VideoQueueRefs, VideoQueueState } from "./useVideoQueueGenerationRefs";
14
+
15
+ /**
16
+ * Create start generation callback
17
+ */
18
+ export function useStartGeneration(
19
+ props: UseVideoQueueGenerationProps,
20
+ refs: VideoQueueRefs,
21
+ state: VideoQueueState,
22
+ _clearPolling: () => void,
23
+ ): (input: unknown, prompt: string) => Promise<void> {
24
+ const { userId, scenario, persistence, strategy, creditCost, onError } = props;
25
+ const { setIsGenerating } = state;
26
+ const { creationIdRef, requestIdRef, modelRef, pollStartTimeRef, isGeneratingRef, pollingRef, pollStatusRef } = refs;
27
+
28
+ return useCallback(
29
+ async (input: unknown, prompt: string) => {
30
+ if (!strategy.submitToQueue) {
31
+ onError?.("Queue submission not available");
32
+ return;
33
+ }
34
+ if (isGeneratingRef.current) return;
35
+
36
+ isGeneratingRef.current = true;
37
+ setIsGenerating(true);
38
+
39
+ let creationId: string | null = null;
40
+ if (userId && prompt) {
41
+ try {
42
+ const { duration, resolution, aspectRatio } = extractInputMetadata(input);
43
+
44
+ const result = await persistence.saveAsProcessing(userId, {
45
+ scenarioId: scenario.id,
46
+ scenarioTitle: scenario.title || scenario.id,
47
+ prompt,
48
+ duration,
49
+ resolution,
50
+ creditCost,
51
+ aspectRatio,
52
+ provider: "fal",
53
+ outputType: scenario.outputType,
54
+ });
55
+ creationId = result.creationId;
56
+ creationIdRef.current = creationId;
57
+ // Record the actual DB-level start time for accurate durationMs
58
+ pollStartTimeRef.current = result.startedAt.getTime();
59
+ } catch (error) {
60
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
61
+ console.error("[VideoQueue] Failed to save processing creation:", error);
62
+ }
63
+ }
64
+ }
65
+
66
+ let queueResult;
67
+ try {
68
+ queueResult = await strategy.submitToQueue(input);
69
+ } catch (error) {
70
+ if (creationId && userId) {
71
+ try {
72
+ await persistence.updateToFailed(userId, creationId, error instanceof Error ? error.message : "Queue submission failed");
73
+ } catch (persistError) {
74
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
75
+ console.error("[VideoQueue] Failed to persist submission error:", persistError);
76
+ }
77
+ }
78
+ }
79
+ isGeneratingRef.current = false;
80
+ setIsGenerating(false);
81
+ onError?.(error instanceof Error ? error.message : "Queue submission failed");
82
+ return;
83
+ }
84
+
85
+ if (!queueResult.success || !queueResult.requestId || !queueResult.model) {
86
+ if (creationId && userId) {
87
+ try {
88
+ await persistence.updateToFailed(userId, creationId, queueResult.error || "Queue submission failed");
89
+ } catch (persistError) {
90
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
91
+ console.error("[VideoQueue] Failed to persist queue failure:", persistError);
92
+ }
93
+ }
94
+ }
95
+ isGeneratingRef.current = false;
96
+ setIsGenerating(false);
97
+ onError?.(queueResult.error || "Queue submission failed");
98
+ return;
99
+ }
100
+
101
+ requestIdRef.current = queueResult.requestId;
102
+ modelRef.current = queueResult.model;
103
+
104
+ if (creationId && userId && queueResult.requestId && queueResult.model) {
105
+ try {
106
+ await persistence.updateRequestId(userId, creationId, queueResult.requestId, queueResult.model);
107
+ } catch (error) {
108
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
109
+ console.error("[VideoQueue] Failed to update request ID:", error);
110
+ }
111
+ }
112
+ }
113
+
114
+ // Start polling: use DB-level startedAt if available, otherwise fallback to now
115
+ if (pollStartTimeRef.current === null) {
116
+ pollStartTimeRef.current = Date.now();
117
+ }
118
+ pollingRef.current = setInterval(() => void pollStatusRef.current(), DEFAULT_POLL_INTERVAL_MS);
119
+ void pollStatusRef.current();
120
+ },
121
+ [userId, scenario, persistence, strategy, creditCost, onError, setIsGenerating, creationIdRef, requestIdRef, modelRef, pollStartTimeRef, isGeneratingRef, pollingRef, pollStatusRef],
122
+ );
123
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Video Queue Generation Hook
3
+ */
4
+
5
+ export { useVideoQueueGeneration } from "./useVideoQueueGeneration";
6
+ export type {
7
+ UseVideoQueueGenerationProps,
8
+ UseVideoQueueGenerationReturn,
9
+ } from "./use-video-queue-generation.types";
@@ -1,17 +1,24 @@
1
1
  /**
2
2
  * Image-to-Video State Types
3
+ * Refactored to use shared kernel types
3
4
  */
4
5
 
5
- export interface ImageToVideoFeatureState {
6
+ import type { BaseFeatureState } from '../../../../shared-kernel/base-types';
7
+
8
+ /**
9
+ * Image-to-video feature state
10
+ * Extends base feature state with image-specific fields
11
+ */
12
+ export interface ImageToVideoFeatureState extends BaseFeatureState {
6
13
  imageUri: string | null;
7
14
  motionPrompt: string;
8
15
  videoUrl: string | null;
9
16
  thumbnailUrl: string | null;
10
- isProcessing: boolean;
11
- progress: number;
12
- error: string | null;
13
17
  }
14
18
 
19
+ /**
20
+ * Image-to-video translations
21
+ */
15
22
  export interface ImageToVideoTranslations {
16
23
  uploadTitle: string;
17
24
  uploadSubtitle: string;
@@ -8,18 +8,17 @@ export {
8
8
  export interface PromptSuggestion {
9
9
  readonly id: string;
10
10
  readonly translationKey: string;
11
- readonly fallbackText: string;
12
11
  }
13
12
 
14
13
  /** Default text-to-image example prompts */
15
14
  export const DEFAULT_TEXT_TO_IMAGE_PROMPTS: readonly PromptSuggestion[] = [
16
- { id: "1", translationKey: "prompts.text2image.fantasy", fallbackText: "A mystical forest with glowing mushrooms" },
17
- { id: "2", translationKey: "prompts.text2image.portrait", fallbackText: "Professional portrait with studio lighting" },
18
- { id: "3", translationKey: "prompts.text2image.landscape", fallbackText: "Sunset over mountains with lake reflection" },
15
+ { id: "1", translationKey: "prompts.text2image.fantasy" },
16
+ { id: "2", translationKey: "prompts.text2image.portrait" },
17
+ { id: "3", translationKey: "prompts.text2image.landscape" },
19
18
  ];
20
19
 
21
20
  /** Default text-to-voice example prompts */
22
21
  export const DEFAULT_TEXT_TO_VOICE_PROMPTS: readonly PromptSuggestion[] = [
23
- { id: "1", translationKey: "prompts.text2voice.greeting", fallbackText: "Hello, welcome to our application" },
24
- { id: "2", translationKey: "prompts.text2voice.story", fallbackText: "Once upon a time in a land far away" },
22
+ { id: "1", translationKey: "prompts.text2voice.greeting" },
23
+ { id: "2", translationKey: "prompts.text2voice.story" },
25
24
  ];
@@ -1,58 +1,79 @@
1
1
  /**
2
2
  * Text-to-Image Feature Types
3
- * Request, Result, Config types for text-to-image generation
3
+ * Refactored to use shared kernel types
4
4
  */
5
5
 
6
- export interface TextToImageOptions {
7
- aspectRatio?: "16:9" | "9:16" | "1:1";
8
- size?: "512x512" | "768x768" | "1024x1024" | "1024x1792" | "1792x1024";
6
+ import type {
7
+ BaseGenerationOptions,
8
+ BaseGenerationResult,
9
+ BaseRequestMeta,
10
+ BaseFeatureState,
11
+ BaseGenerationCallbacks,
12
+ } from '../../../../shared-kernel/base-types';
13
+
14
+ /**
15
+ * Text-to-image specific options
16
+ * Extends base options with image-specific fields
17
+ */
18
+ export interface TextToImageOptions extends BaseGenerationOptions {
19
+ /** Image size dimensions */
20
+ size?: '512x512' | '768x768' | '1024x1024' | '1024x1792' | '1792x1024';
21
+ /** Number of images to generate */
9
22
  numImages?: number;
10
- guidanceScale?: number;
11
- seed?: number;
12
23
  }
13
24
 
25
+ /**
26
+ * Text-to-image request
27
+ * Uses base metadata from shared kernel
28
+ */
14
29
  export interface TextToImageRequest {
15
30
  prompt: string;
16
- userId: string;
17
31
  negativePrompt?: string;
18
32
  options?: TextToImageOptions;
33
+ meta: BaseRequestMeta;
19
34
  }
20
35
 
21
- export interface TextToImageResult {
22
- success: boolean;
36
+ /**
37
+ * Text-to-image result
38
+ * Extends base result with image-specific output
39
+ */
40
+ export interface TextToImageResult extends BaseGenerationResult<string | string[]> {
23
41
  imageUrl?: string;
24
42
  imageUrls?: string[];
25
- error?: string;
26
- requestId?: string;
27
43
  }
28
44
 
29
- export interface TextToImageFeatureState {
45
+ /**
46
+ * Text-to-image feature state
47
+ * Extends base feature state with prompt field
48
+ */
49
+ export interface TextToImageFeatureState extends BaseFeatureState<string | string[]> {
30
50
  prompt: string;
31
- imageUrl: string | null;
32
- imageUrls: string[];
33
- isProcessing: boolean;
34
- progress: number;
35
- error: string | null;
36
51
  }
37
52
 
38
-
53
+ /**
54
+ * Input builder type
55
+ */
39
56
  export type TextToImageInputBuilder = (
40
57
  prompt: string,
41
58
  options?: TextToImageOptions,
42
59
  ) => Record<string, unknown>;
43
60
 
61
+ /**
62
+ * Result extractor type
63
+ */
44
64
  export type TextToImageResultExtractor = (
45
65
  result: unknown,
46
66
  ) => { imageUrl?: string; imageUrls?: string[] } | undefined;
47
67
 
68
+ /**
69
+ * Text-to-image feature configuration
70
+ * Uses shared callbacks
71
+ */
48
72
  export interface TextToImageFeatureConfig {
49
73
  providerId?: string;
50
74
  creditCost?: number;
51
75
  model: string;
52
76
  buildInput: TextToImageInputBuilder;
53
77
  extractResult?: TextToImageResultExtractor;
54
- onPromptChange?: (prompt: string) => void;
55
- onProcessingStart?: () => void;
56
- onProcessingComplete?: (result: TextToImageResult) => void;
57
- onError?: (error: string) => void;
78
+ callbacks?: BaseGenerationCallbacks<string | string[]>;
58
79
  }
@@ -1,36 +1,59 @@
1
1
  /**
2
2
  * Text-to-Video Request/Response Types
3
- * Single Responsibility: Define API request and response structures
3
+ * Refactored to use shared kernel types
4
4
  */
5
5
 
6
- export interface TextToVideoOptions {
6
+ import type {
7
+ BaseGenerationOptions,
8
+ BaseGenerationResult,
9
+ BaseRequestMeta,
10
+ } from '../../../../shared-kernel/base-types';
11
+
12
+ /**
13
+ * Text-to-video specific options
14
+ * Extends base options with video-specific fields
15
+ */
16
+ export interface TextToVideoOptions extends BaseGenerationOptions {
17
+ /** Video duration in seconds */
7
18
  duration?: number;
19
+ /** Frames per second */
8
20
  fps?: number;
9
- guidanceScale?: number;
10
- aspectRatio?: "16:9" | "9:16" | "1:1";
21
+ /** Video style preset */
11
22
  style?: string;
23
+ /** Negative prompt for content avoidance */
12
24
  negativePrompt?: string;
13
25
  }
14
26
 
27
+ /**
28
+ * Text-to-video request
29
+ * Uses base metadata from shared kernel
30
+ */
15
31
  export interface TextToVideoRequest {
16
32
  prompt: string;
17
- userId: string;
18
33
  options?: TextToVideoOptions;
34
+ meta: BaseRequestMeta;
19
35
  }
20
36
 
21
- export interface TextToVideoResult {
22
- success: boolean;
37
+ /**
38
+ * Text-to-video result
39
+ * Extends base result with video-specific output
40
+ */
41
+ export interface TextToVideoResult extends BaseGenerationResult {
23
42
  videoUrl?: string;
24
43
  thumbnailUrl?: string;
25
- error?: string;
26
- requestId?: string;
27
44
  }
28
45
 
46
+ /**
47
+ * Input builder type
48
+ */
29
49
  export type TextToVideoInputBuilder = (
30
50
  prompt: string,
31
51
  options?: TextToVideoOptions,
32
52
  ) => Record<string, unknown>;
33
53
 
54
+ /**
55
+ * Result extractor type
56
+ */
34
57
  export type TextToVideoResultExtractor = (
35
58
  result: unknown,
36
59
  ) => { videoUrl?: string; thumbnailUrl?: string } | undefined;
@@ -1,17 +1,24 @@
1
1
  /**
2
2
  * Text-to-Video Feature State Types
3
- * Single Responsibility: Define internal state structures
3
+ * Refactored to use shared kernel types
4
4
  */
5
5
 
6
- export interface TextToVideoFeatureState {
6
+ import type { BaseFeatureState } from '../../../../shared-kernel/base-types';
7
+
8
+ /**
9
+ * Text-to-video feature state
10
+ * Extends base feature state with video-specific fields
11
+ */
12
+ export interface TextToVideoFeatureState extends BaseFeatureState {
7
13
  prompt: string;
8
14
  videoUrl: string | null;
9
15
  thumbnailUrl: string | null;
10
- isProcessing: boolean;
11
- progress: number;
12
- error: string | null;
13
16
  }
14
17
 
18
+ /**
19
+ * Text-to-video form state
20
+ * UI-specific state, separate from feature state
21
+ */
15
22
  export interface TextToVideoFormState {
16
23
  prompt: string;
17
24
  style: string;
@@ -22,32 +29,25 @@ export interface TextToVideoFormState {
22
29
  professionalMode: boolean;
23
30
  }
24
31
 
25
- export interface TextToVideoGenerationState {
26
- isGenerating: boolean;
27
- progress: number;
28
- contentWarnings: string[];
29
- error: string | null;
30
- }
31
-
32
+ /**
33
+ * Frame data structure
34
+ */
32
35
  export interface FrameData {
33
36
  id: string;
34
37
  url: string;
35
38
  order: number;
36
39
  }
37
40
 
41
+ /**
42
+ * Initial form state
43
+ */
38
44
  export const INITIAL_FORM_STATE: TextToVideoFormState = {
39
- prompt: "",
40
- style: "realistic",
41
- aspectRatio: "16:9",
45
+ prompt: '',
46
+ style: 'realistic',
47
+ aspectRatio: '16:9',
42
48
  duration: 4,
43
- activeTab: "text-to-video",
49
+ activeTab: 'text-to-video',
44
50
  soundEnabled: false,
45
51
  professionalMode: false,
46
52
  };
47
53
 
48
- export const INITIAL_GENERATION_STATE: TextToVideoGenerationState = {
49
- isGenerating: false,
50
- progress: 0,
51
- contentWarnings: [],
52
- error: null,
53
- };