@umituz/react-native-ai-generation-content 1.61.25 → 1.61.27
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 -1
- package/src/core/types/error.types.ts +3 -30
- package/src/core/types/provider.types.ts +35 -188
- package/src/core/types/result.types.ts +12 -96
- package/src/domain/entities/flow-config.types.ts +2 -2
- package/src/domain/entities/generation.types.ts +1 -0
- package/src/domains/creations/presentation/hooks/useProcessingJobsPoller.ts +16 -4
- package/src/domains/generation/domain/generation.types.ts +4 -7
- package/src/domains/generation/index.ts +1 -1
- package/src/domains/generation/infrastructure/flow/useFlowStore.ts +2 -1
- package/src/domains/generation/presentation/useAIGeneration.hook.ts +3 -15
- package/src/domains/generation/wizard/presentation/hooks/useGenerationPhase.ts +2 -3
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.ts +1 -1
- package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +4 -0
- package/src/domains/generation/wizard/presentation/hooks/useWizardGeneration.ts +4 -2
- package/src/exports/infrastructure.ts +1 -1
- package/src/features/image-to-video/infrastructure/services/image-to-video-executor.ts +10 -37
- package/src/features/image-to-video/presentation/components/DurationSelector.tsx +1 -1
- package/src/features/image-to-video/presentation/hooks/image-to-video-feature.types.ts +2 -12
- package/src/features/image-to-video/presentation/hooks/useImageToVideoFeature.ts +24 -13
- package/src/features/text-to-video/infrastructure/services/text-to-video-executor.ts +5 -37
- package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +26 -26
- package/src/infrastructure/orchestration/GenerationOrchestrator.ts +17 -14
- package/src/infrastructure/orchestration/orchestrator.types.ts +2 -5
- package/src/infrastructure/providers/generation-config.provider.tsx +4 -4
- package/src/infrastructure/services/generation-orchestrator.service.ts +7 -6
- package/src/infrastructure/services/job-poller.service.ts +2 -4
- package/src/infrastructure/services/multi-image-generation.executor.ts +6 -11
- package/src/infrastructure/utils/README.md +7 -7
- package/src/infrastructure/utils/base64.util.ts +15 -0
- package/src/infrastructure/utils/error-classifier.util.ts +27 -10
- package/src/infrastructure/utils/error-message-extractor.util.ts +3 -3
- package/src/infrastructure/utils/error-patterns.constants.ts +21 -8
- package/src/infrastructure/utils/id-generator.util.ts +11 -0
- package/src/infrastructure/utils/index.ts +3 -0
- package/src/infrastructure/utils/polling-interval.util.ts +1 -14
- package/src/infrastructure/utils/provider-validator.util.ts +2 -2
- package/src/infrastructure/utils/video-result-extractor.util.ts +38 -0
- package/src/presentation/components/AIGenerationForm.tsx +3 -3
- package/src/presentation/components/selectors/AspectRatioSelector.tsx +3 -3
- package/src/presentation/components/selectors/DurationSelector.tsx +3 -3
- package/src/presentation/components/selectors/GridSelector.tsx +5 -5
- package/src/presentation/components/selectors/StyleSelector.tsx +3 -3
- package/src/presentation/constants/alert-messages.ts +14 -0
- package/src/presentation/hooks/generation/errors.ts +5 -1
- package/src/presentation/hooks/generation/useImageGeneration.ts +6 -2
- package/src/presentation/hooks/generation/useVideoGeneration.ts +6 -2
- package/src/presentation/hooks/use-background-generation.ts +8 -10
- package/src/presentation/hooks/use-generation.ts +8 -1
- package/src/presentation/hooks/useGenerationFlow.ts +18 -23
- package/src/presentation/layouts/DualImageFeatureLayout.tsx +0 -1
- package/src/presentation/layouts/DualImageVideoFeatureLayout.tsx +1 -1
- package/src/presentation/layouts/SingleImageFeatureLayout.tsx +1 -1
- package/src/presentation/layouts/SingleImageWithPromptFeatureLayout.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.61.
|
|
3
|
+
"version": "1.61.27",
|
|
4
4
|
"description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -1,36 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AI Generation Error Types
|
|
3
|
-
*
|
|
3
|
+
* Re-exports from canonical domain source
|
|
4
4
|
*
|
|
5
5
|
* @module @umituz/react-native-ai-generation-content/core
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
RATE_LIMIT = "RATE_LIMIT",
|
|
11
|
-
AUTHENTICATION = "AUTHENTICATION",
|
|
12
|
-
VALIDATION = "VALIDATION",
|
|
13
|
-
CONTENT_POLICY = "CONTENT_POLICY",
|
|
14
|
-
SERVER = "SERVER",
|
|
15
|
-
TIMEOUT = "TIMEOUT",
|
|
16
|
-
UNKNOWN = "UNKNOWN",
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface AIErrorInfo {
|
|
20
|
-
type: AIErrorType;
|
|
21
|
-
messageKey: string;
|
|
22
|
-
retryable: boolean;
|
|
23
|
-
originalError?: unknown;
|
|
24
|
-
statusCode?: number;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface AIErrorMessages {
|
|
28
|
-
[AIErrorType.NETWORK]: string;
|
|
29
|
-
[AIErrorType.RATE_LIMIT]: string;
|
|
30
|
-
[AIErrorType.AUTHENTICATION]: string;
|
|
31
|
-
[AIErrorType.VALIDATION]: string;
|
|
32
|
-
[AIErrorType.CONTENT_POLICY]: string;
|
|
33
|
-
[AIErrorType.SERVER]: string;
|
|
34
|
-
[AIErrorType.TIMEOUT]: string;
|
|
35
|
-
[AIErrorType.UNKNOWN]: string;
|
|
36
|
-
}
|
|
8
|
+
export { AIErrorType } from "../../domain/entities/error.types";
|
|
9
|
+
export type { AIErrorInfo, AIErrorMessages } from "../../domain/entities/error.types";
|
|
@@ -1,192 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AI Provider Types - Core interfaces for AI generation providers
|
|
3
|
+
* Re-exports from canonical domain sources
|
|
4
|
+
*
|
|
5
|
+
* @module @umituz/react-native-ai-generation-content/core
|
|
3
6
|
*/
|
|
4
7
|
|
|
5
|
-
//
|
|
6
|
-
export type
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// =============================================================================
|
|
40
|
-
// Status Types
|
|
41
|
-
// =============================================================================
|
|
42
|
-
|
|
43
|
-
export type AIJobStatusType =
|
|
44
|
-
| "IN_QUEUE"
|
|
45
|
-
| "IN_PROGRESS"
|
|
46
|
-
| "COMPLETED"
|
|
47
|
-
| "FAILED";
|
|
48
|
-
|
|
49
|
-
export interface AILogEntry {
|
|
50
|
-
message: string;
|
|
51
|
-
level: "info" | "warn" | "error";
|
|
52
|
-
timestamp?: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface JobSubmission {
|
|
56
|
-
requestId: string;
|
|
57
|
-
statusUrl?: string;
|
|
58
|
-
responseUrl?: string;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface JobStatus {
|
|
62
|
-
status: AIJobStatusType;
|
|
63
|
-
logs?: AILogEntry[];
|
|
64
|
-
queuePosition?: number;
|
|
65
|
-
eta?: number;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// =============================================================================
|
|
69
|
-
// Progress & Options
|
|
70
|
-
// =============================================================================
|
|
71
|
-
|
|
72
|
-
export interface ProviderProgressInfo {
|
|
73
|
-
progress: number;
|
|
74
|
-
status?: AIJobStatusType;
|
|
75
|
-
message?: string;
|
|
76
|
-
estimatedTimeRemaining?: number;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface SubscribeOptions<T = unknown> {
|
|
80
|
-
timeoutMs?: number;
|
|
81
|
-
onQueueUpdate?: (status: JobStatus) => void;
|
|
82
|
-
onProgress?: (progress: ProviderProgressInfo) => void;
|
|
83
|
-
onResult?: (result: T) => void;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface RunOptions {
|
|
87
|
-
onProgress?: (progress: ProviderProgressInfo) => void;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// =============================================================================
|
|
91
|
-
// Capabilities
|
|
92
|
-
// =============================================================================
|
|
93
|
-
|
|
94
|
-
export interface ProviderCapabilities {
|
|
95
|
-
imageFeatures: readonly ImageFeatureType[];
|
|
96
|
-
videoFeatures: readonly VideoFeatureType[];
|
|
97
|
-
textToImage: boolean;
|
|
98
|
-
textToVideo: boolean;
|
|
99
|
-
imageToVideo: boolean;
|
|
100
|
-
textToVoice: boolean;
|
|
101
|
-
textToText: boolean;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// =============================================================================
|
|
105
|
-
// Feature Input Data
|
|
106
|
-
// =============================================================================
|
|
107
|
-
|
|
108
|
-
export interface ImageFeatureInputData {
|
|
109
|
-
imageBase64: string;
|
|
110
|
-
targetImageBase64?: string;
|
|
111
|
-
prompt?: string;
|
|
112
|
-
options?: Record<string, unknown>;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export interface VideoFeatureInputData {
|
|
116
|
-
sourceImageBase64?: string;
|
|
117
|
-
targetImageBase64?: string;
|
|
118
|
-
prompt?: string;
|
|
119
|
-
options?: Record<string, unknown>;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// =============================================================================
|
|
123
|
-
// Provider Sub-Interfaces (Interface Segregation Principle)
|
|
124
|
-
// =============================================================================
|
|
125
|
-
|
|
126
|
-
export interface IAIProviderLifecycle {
|
|
127
|
-
initialize(config: AIProviderConfig): void;
|
|
128
|
-
isInitialized(): boolean;
|
|
129
|
-
reset(): void;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export interface IAIProviderCapabilities {
|
|
133
|
-
getCapabilities(): ProviderCapabilities;
|
|
134
|
-
isFeatureSupported(feature: ImageFeatureType | VideoFeatureType): boolean;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export interface IAIProviderJobManager {
|
|
138
|
-
submitJob(
|
|
139
|
-
model: string,
|
|
140
|
-
input: Record<string, unknown>,
|
|
141
|
-
): Promise<JobSubmission>;
|
|
142
|
-
getJobStatus(model: string, requestId: string): Promise<JobStatus>;
|
|
143
|
-
getJobResult<T = unknown>(model: string, requestId: string): Promise<T>;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export interface IAIProviderExecutor {
|
|
147
|
-
subscribe<T = unknown>(
|
|
148
|
-
model: string,
|
|
149
|
-
input: Record<string, unknown>,
|
|
150
|
-
options?: SubscribeOptions<T>,
|
|
151
|
-
): Promise<T>;
|
|
152
|
-
run<T = unknown>(
|
|
153
|
-
model: string,
|
|
154
|
-
input: Record<string, unknown>,
|
|
155
|
-
options?: RunOptions,
|
|
156
|
-
): Promise<T>;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export interface IAIProviderImageFeatures {
|
|
160
|
-
getImageFeatureModel(feature: ImageFeatureType): string;
|
|
161
|
-
buildImageFeatureInput(
|
|
162
|
-
feature: ImageFeatureType,
|
|
163
|
-
data: ImageFeatureInputData,
|
|
164
|
-
): Record<string, unknown>;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export interface IAIProviderVideoFeatures {
|
|
168
|
-
getVideoFeatureModel(feature: VideoFeatureType): string;
|
|
169
|
-
buildVideoFeatureInput(
|
|
170
|
-
feature: VideoFeatureType,
|
|
171
|
-
data: VideoFeatureInputData,
|
|
172
|
-
): Record<string, unknown>;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// =============================================================================
|
|
176
|
-
// Main Provider Interface
|
|
177
|
-
// =============================================================================
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Main AI Provider Interface
|
|
181
|
-
* Composition of segregated interfaces following SOLID principles
|
|
182
|
-
*/
|
|
183
|
-
export interface IAIProvider
|
|
184
|
-
extends IAIProviderLifecycle,
|
|
185
|
-
IAIProviderCapabilities,
|
|
186
|
-
IAIProviderJobManager,
|
|
187
|
-
IAIProviderExecutor,
|
|
188
|
-
IAIProviderImageFeatures,
|
|
189
|
-
IAIProviderVideoFeatures {
|
|
190
|
-
readonly providerId: string;
|
|
191
|
-
readonly providerName: string;
|
|
192
|
-
}
|
|
8
|
+
// Main provider types from ai-provider.interface
|
|
9
|
+
export type {
|
|
10
|
+
// Feature Types
|
|
11
|
+
ImageFeatureType,
|
|
12
|
+
VideoFeatureType,
|
|
13
|
+
// Config
|
|
14
|
+
AIProviderConfig,
|
|
15
|
+
// Status
|
|
16
|
+
AIJobStatusType,
|
|
17
|
+
AILogEntry,
|
|
18
|
+
JobSubmission,
|
|
19
|
+
JobStatus,
|
|
20
|
+
// Progress
|
|
21
|
+
ProviderProgressInfo,
|
|
22
|
+
SubscribeOptions,
|
|
23
|
+
RunOptions,
|
|
24
|
+
// Capabilities
|
|
25
|
+
ProviderCapabilities,
|
|
26
|
+
// Input Data
|
|
27
|
+
ImageFeatureInputData,
|
|
28
|
+
VideoFeatureInputData,
|
|
29
|
+
// Main Provider Interface
|
|
30
|
+
IAIProvider,
|
|
31
|
+
} from "../../domain/interfaces/ai-provider.interface";
|
|
32
|
+
|
|
33
|
+
// Segregated provider sub-interfaces
|
|
34
|
+
export type { IAIProviderLifecycle } from "../../domain/interfaces/provider-lifecycle.interface";
|
|
35
|
+
export type { IAIProviderCapabilities } from "../../domain/interfaces/provider-capabilities.interface";
|
|
36
|
+
export type { IAIProviderJobManager } from "../../domain/interfaces/provider-job-manager.interface";
|
|
37
|
+
export type { IAIProviderExecutor } from "../../domain/interfaces/provider-executor.interface";
|
|
38
|
+
export type { IAIProviderImageFeatures } from "../../domain/interfaces/provider-image-features.interface";
|
|
39
|
+
export type { IAIProviderVideoFeatures } from "../../domain/interfaces/provider-video-features.interface";
|
|
@@ -1,102 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Result Type Pattern for Functional Error Handling
|
|
3
|
-
*
|
|
3
|
+
* Re-exports from canonical domain source
|
|
4
4
|
*
|
|
5
5
|
* @module @umituz/react-native-ai-generation-content/core
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export interface Failure<E> {
|
|
20
|
-
success: false;
|
|
21
|
-
error: E;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Result type that can be either Success or Failure
|
|
26
|
-
* Forces explicit error handling at compile time
|
|
27
|
-
*/
|
|
28
|
-
export type Result<T, E = string> = Success<T> | Failure<E>;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Create a successful result
|
|
32
|
-
*/
|
|
33
|
-
export function success<T>(value: T): Success<T> {
|
|
34
|
-
return { success: true, value };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Create a failed result
|
|
39
|
-
*/
|
|
40
|
-
export function failure<E>(error: E): Failure<E> {
|
|
41
|
-
return { success: false, error };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Type guard to check if result is successful
|
|
46
|
-
*/
|
|
47
|
-
export function isSuccess<T, E>(result: Result<T, E>): result is Success<T> {
|
|
48
|
-
return result.success === true;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Type guard to check if result is a failure
|
|
53
|
-
*/
|
|
54
|
-
export function isFailure<T, E>(result: Result<T, E>): result is Failure<E> {
|
|
55
|
-
return result.success === false;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Map a successful result to a new value
|
|
60
|
-
*/
|
|
61
|
-
export function mapResult<T, U, E>(
|
|
62
|
-
result: Result<T, E>,
|
|
63
|
-
fn: (value: T) => U,
|
|
64
|
-
): Result<U, E> {
|
|
65
|
-
if (isSuccess(result)) {
|
|
66
|
-
return success(fn(result.value));
|
|
67
|
-
}
|
|
68
|
-
return result;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Chain async operations on Result types
|
|
73
|
-
*/
|
|
74
|
-
export async function andThen<T, U, E>(
|
|
75
|
-
result: Result<T, E>,
|
|
76
|
-
fn: (value: T) => Promise<Result<U, E>>,
|
|
77
|
-
): Promise<Result<U, E>> {
|
|
78
|
-
if (isSuccess(result)) {
|
|
79
|
-
return fn(result.value);
|
|
80
|
-
}
|
|
81
|
-
return result;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Unwrap a result, throwing if it's a failure
|
|
86
|
-
*/
|
|
87
|
-
export function unwrap<T, E>(result: Result<T, E>): T {
|
|
88
|
-
if (isSuccess(result)) {
|
|
89
|
-
return result.value;
|
|
90
|
-
}
|
|
91
|
-
throw new Error(`Called unwrap on a failure: ${String(result.error)}`);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Unwrap a result or return a default value
|
|
96
|
-
*/
|
|
97
|
-
export function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T {
|
|
98
|
-
if (isSuccess(result)) {
|
|
99
|
-
return result.value;
|
|
100
|
-
}
|
|
101
|
-
return defaultValue;
|
|
102
|
-
}
|
|
8
|
+
export type { Result, Success, Failure } from "../../domain/types/result.types";
|
|
9
|
+
export {
|
|
10
|
+
success,
|
|
11
|
+
failure,
|
|
12
|
+
isSuccess,
|
|
13
|
+
isFailure,
|
|
14
|
+
mapResult,
|
|
15
|
+
andThen,
|
|
16
|
+
unwrap,
|
|
17
|
+
unwrapOr,
|
|
18
|
+
} from "../../domain/types/result.types";
|
|
@@ -79,8 +79,8 @@ export interface StepDefinition<TConfig = unknown> {
|
|
|
79
79
|
readonly component?: React.ComponentType<StepComponentProps>;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
/** Flow Generation Status */
|
|
83
|
-
export type FlowGenerationStatus = "idle" | "preparing" | "generating" | "completed" | "failed"
|
|
82
|
+
/** Flow Generation Status - subset of GenerationStatus */
|
|
83
|
+
export type FlowGenerationStatus = Extract<import("./generation.types").GenerationStatus, "idle" | "preparing" | "generating" | "completed" | "failed">;
|
|
84
84
|
|
|
85
85
|
/** Flow State */
|
|
86
86
|
export interface FlowState {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Uses provider registry internally - no need to pass FAL functions
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { useEffect, useRef, useCallback } from "react";
|
|
8
|
+
import { useEffect, useRef, useCallback, useMemo } from "react";
|
|
9
9
|
import { providerRegistry } from "../../../../infrastructure/services/provider-registry.service";
|
|
10
10
|
import { QUEUE_STATUS, CREATION_STATUS } from "../../../../domain/constants/queue-status.constants";
|
|
11
11
|
import {
|
|
@@ -43,9 +43,21 @@ export function useProcessingJobsPoller(
|
|
|
43
43
|
const pollingRef = useRef<Set<string>>(new Set());
|
|
44
44
|
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
45
45
|
|
|
46
|
-
// Find creations that need polling
|
|
47
|
-
const
|
|
48
|
-
(
|
|
46
|
+
// Find creations that need polling - stabilize reference with useMemo
|
|
47
|
+
const processingJobIds = useMemo(
|
|
48
|
+
() => creations
|
|
49
|
+
.filter((c) => c.status === CREATION_STATUS.PROCESSING && c.requestId && c.model)
|
|
50
|
+
.map((c) => c.id)
|
|
51
|
+
.join(","),
|
|
52
|
+
[creations],
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const processingJobs = useMemo(
|
|
56
|
+
() => creations.filter(
|
|
57
|
+
(c) => c.status === CREATION_STATUS.PROCESSING && c.requestId && c.model,
|
|
58
|
+
),
|
|
59
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
60
|
+
[processingJobIds],
|
|
49
61
|
);
|
|
50
62
|
|
|
51
63
|
const pollJob = useCallback(
|
|
@@ -13,14 +13,11 @@ export interface GenerationOptions {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
// ============================================================================
|
|
16
|
-
// Generation Result
|
|
16
|
+
// Generation Result (re-exported from canonical source)
|
|
17
17
|
// ============================================================================
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
data?: T;
|
|
22
|
-
error?: string;
|
|
23
|
-
}
|
|
19
|
+
import type { GenerationResult as _GenerationResult } from "../../../domain/entities/generation.types";
|
|
20
|
+
export type { GenerationResult } from "../../../domain/entities/generation.types";
|
|
24
21
|
|
|
25
22
|
// ============================================================================
|
|
26
23
|
// Input Types (by generation type)
|
|
@@ -86,5 +83,5 @@ export interface GenerationExecutor<TInput, TOutput> {
|
|
|
86
83
|
model: string,
|
|
87
84
|
input: TInput,
|
|
88
85
|
options?: GenerationOptions,
|
|
89
|
-
): Promise<
|
|
86
|
+
): Promise<_GenerationResult<TOutput>>;
|
|
90
87
|
}
|
|
@@ -2,8 +2,8 @@ export {
|
|
|
2
2
|
useAIGeneration,
|
|
3
3
|
type UseAIGenerationProps,
|
|
4
4
|
type UseAIGenerationReturn,
|
|
5
|
-
type AlertMessages,
|
|
6
5
|
} from "./presentation/useAIGeneration.hook";
|
|
6
|
+
export type { AlertMessages } from "../../presentation/hooks/generation/types";
|
|
7
7
|
|
|
8
8
|
export { featureRegistry } from "./application/feature-registry";
|
|
9
9
|
export { createGenerationStrategy } from "./application/generation-strategy.factory";
|
|
@@ -133,7 +133,8 @@ export const createFlowStore = (config: FlowStoreConfig) => {
|
|
|
133
133
|
},
|
|
134
134
|
|
|
135
135
|
updateProgress: (progress: number) => {
|
|
136
|
-
|
|
136
|
+
const generationStatus = progress >= 100 ? "completed" : progress > 0 ? "generating" : "preparing";
|
|
137
|
+
set({ generationProgress: progress, generationStatus });
|
|
137
138
|
},
|
|
138
139
|
|
|
139
140
|
setResult: (result: unknown) => {
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { useGenerationOrchestrator } from "../../../presentation/hooks/generation/orchestrator";
|
|
8
|
+
import type { AlertMessages } from "../../../presentation/hooks/generation/types";
|
|
9
|
+
import { DEFAULT_ALERT_MESSAGES } from "../../../presentation/constants/alert-messages";
|
|
8
10
|
import { createGenerationStrategy } from "../application/generation-strategy.factory";
|
|
9
11
|
|
|
10
12
|
declare const __DEV__: boolean;
|
|
@@ -13,14 +15,6 @@ declare const __DEV__: boolean;
|
|
|
13
15
|
// Types
|
|
14
16
|
// ============================================================================
|
|
15
17
|
|
|
16
|
-
export interface AlertMessages {
|
|
17
|
-
networkError: string;
|
|
18
|
-
policyViolation: string;
|
|
19
|
-
saveFailed: string;
|
|
20
|
-
creditFailed: string;
|
|
21
|
-
unknown: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
18
|
export interface UseAIGenerationProps {
|
|
25
19
|
/** Feature ID from feature registry */
|
|
26
20
|
featureId: string;
|
|
@@ -89,13 +83,7 @@ export function useAIGeneration(
|
|
|
89
83
|
// Use orchestrator for lifecycle management
|
|
90
84
|
const orchestrator = useGenerationOrchestrator(strategy, {
|
|
91
85
|
userId,
|
|
92
|
-
alertMessages: alertMessages ||
|
|
93
|
-
networkError: "No internet connection",
|
|
94
|
-
policyViolation: "Content policy violation",
|
|
95
|
-
saveFailed: "Failed to save",
|
|
96
|
-
creditFailed: "Failed to deduct credits",
|
|
97
|
-
unknown: "An error occurred",
|
|
98
|
-
},
|
|
86
|
+
alertMessages: alertMessages || DEFAULT_ALERT_MESSAGES,
|
|
99
87
|
onSuccess,
|
|
100
88
|
onError: onError ? (error) => onError(error.message) : undefined,
|
|
101
89
|
onCreditsExhausted,
|
|
@@ -33,10 +33,9 @@ export function useGenerationPhase(options?: UseGenerationPhaseOptions): Generat
|
|
|
33
33
|
const interval = setInterval(() => {
|
|
34
34
|
const elapsed = Date.now() - startTimeRef.current;
|
|
35
35
|
|
|
36
|
-
if (elapsed
|
|
37
|
-
setPhase("queued");
|
|
38
|
-
} else {
|
|
36
|
+
if (elapsed >= queuedDuration) {
|
|
39
37
|
setPhase("processing");
|
|
38
|
+
clearInterval(interval);
|
|
40
39
|
}
|
|
41
40
|
}, 1000);
|
|
42
41
|
|
|
@@ -41,6 +41,7 @@ export function useVideoQueueGeneration(
|
|
|
41
41
|
const requestIdRef = useRef<string | null>(null);
|
|
42
42
|
const modelRef = useRef<string | null>(null);
|
|
43
43
|
const pollingRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
44
|
+
const isGeneratingRef = useRef(false);
|
|
44
45
|
const [isGenerating, setIsGenerating] = useState(false);
|
|
45
46
|
|
|
46
47
|
// Cleanup polling on unmount
|
|
@@ -57,6 +58,7 @@ export function useVideoQueueGeneration(
|
|
|
57
58
|
creationIdRef.current = null;
|
|
58
59
|
requestIdRef.current = null;
|
|
59
60
|
modelRef.current = null;
|
|
61
|
+
isGeneratingRef.current = false;
|
|
60
62
|
setIsGenerating(false);
|
|
61
63
|
}, []);
|
|
62
64
|
|
|
@@ -138,6 +140,8 @@ export function useVideoQueueGeneration(
|
|
|
138
140
|
const startGeneration = useCallback(
|
|
139
141
|
async (input: unknown, prompt: string) => {
|
|
140
142
|
if (!strategy.submitToQueue) { onError?.("Queue submission not available"); return; }
|
|
143
|
+
if (isGeneratingRef.current) return;
|
|
144
|
+
isGeneratingRef.current = true;
|
|
141
145
|
setIsGenerating(true);
|
|
142
146
|
|
|
143
147
|
// Save to Firestore FIRST (enables background visibility)
|
|
@@ -186,8 +186,10 @@ export const useWizardGeneration = (
|
|
|
186
186
|
scenario,
|
|
187
187
|
wizardData,
|
|
188
188
|
isVideoMode,
|
|
189
|
-
videoGeneration,
|
|
190
|
-
|
|
189
|
+
videoGeneration.isGenerating,
|
|
190
|
+
videoGeneration.startGeneration,
|
|
191
|
+
photoGeneration.isGenerating,
|
|
192
|
+
photoGeneration.startGeneration,
|
|
191
193
|
onError,
|
|
192
194
|
]);
|
|
193
195
|
|
|
@@ -29,7 +29,7 @@ export type {
|
|
|
29
29
|
// Utils
|
|
30
30
|
export {
|
|
31
31
|
classifyError, isTransientError, isPermanentError, isResultNotReady, calculatePollingInterval,
|
|
32
|
-
|
|
32
|
+
checkStatusForErrors, isJobComplete, isJobProcessing, isJobFailed,
|
|
33
33
|
validateResult, extractOutputUrl, extractOutputUrls, extractVideoUrl, extractThumbnailUrl,
|
|
34
34
|
extractAudioUrl, extractImageUrls, cleanBase64, addBase64Prefix, preparePhoto, preparePhotos,
|
|
35
35
|
isValidBase64, getBase64Size, getBase64SizeMB, prepareImage, createDevCallbacks, createFeatureUtils,
|