@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.
- package/package.json +3 -3
- 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/domain/interfaces/index.ts +3 -0
- package/src/domains/background/infrastructure/services/job-poller-index.ts +7 -0
- package/src/domains/background/infrastructure/services/job-poller-utils.ts +127 -0
- package/src/domains/background/infrastructure/services/job-poller.service.ts +85 -140
- 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/index.ts +7 -13
- 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/content-moderation/infrastructure/services/pattern-matcher.service.ts +1 -2
- 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 +7 -114
- package/src/domains/creations/domain/utils/creation-display.util.ts +1 -1
- package/src/domains/creations/domain/utils/status-helpers.ts +1 -1
- 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/hooks/useCreations.ts +1 -1
- package/src/domains/creations/presentation/hooks/useProcessingJobsPoller.ts +18 -235
- package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +1 -2
- 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/appearance-analysis/index.ts +5 -0
- 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 +112 -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 +74 -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 +41 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor-index.ts +10 -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 +61 -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 -176
- 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 -130
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.validation.ts +136 -0
- package/src/domains/generation/wizard/presentation/hooks/photo-upload/index.ts +40 -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 +102 -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 +77 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/use-video-queue-utils.ts +123 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationCallbacks.ts +119 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationPolling.ts +75 -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/constants/index.ts +5 -6
- package/src/domains/text-to-image/domain/types/text-to-image.types.ts +43 -22
- package/src/domains/text-to-video/domain/types/request.types.ts +32 -9
- package/src/domains/text-to-video/domain/types/state.types.ts +22 -22
- 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/exports/features.ts +1 -1
- 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 +9 -0
- package/src/infrastructure/utils/couple-input-photorealistic.ts +40 -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 +11 -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 +3 -26
- 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 +106 -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 +70 -0
- package/src/domains/content-moderation/infrastructure/services/index.ts +0 -8
- package/src/domains/creations/domain/constants/index.ts +0 -12
- package/src/domains/creations/domain/utils/index.ts +0 -12
- package/src/domains/generation/infrastructure/couple-generation-builder.ts +0 -374
- package/src/domains/image-to-video/domain/index.ts +0 -2
- package/src/domains/image-to-video/infrastructure/index.ts +0 -1
- package/src/domains/image-to-video/presentation/index.ts +0 -5
- package/src/domains/text-to-video/domain/index.ts +0 -1
- package/src/domains/text-to-video/presentation/index.ts +0 -7
- 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
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generation Orchestrator
|
|
3
|
-
* Handles AI generation execution with network check, moderation, credit deduction, and error handling
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { useState, useCallback, useRef, useEffect } from "react";
|
|
7
|
-
import { useAlert } from "@umituz/react-native-design-system/molecules";
|
|
8
|
-
import { useOfflineStore } from "@umituz/react-native-design-system/offline";
|
|
9
|
-
import { createGenerationError, getAlertMessage, parseError } from "./errors";
|
|
10
|
-
import { handleModeration } from "./moderation-handler";
|
|
11
|
-
import type {
|
|
12
|
-
GenerationStrategy,
|
|
13
|
-
GenerationConfig,
|
|
14
|
-
GenerationState,
|
|
15
|
-
GenerationError,
|
|
16
|
-
UseGenerationOrchestratorReturn,
|
|
17
|
-
} from "./types";
|
|
18
|
-
|
|
19
|
-
const getInitialState = <T>(): GenerationState<T> => ({
|
|
20
|
-
status: "idle",
|
|
21
|
-
isGenerating: false,
|
|
22
|
-
result: null,
|
|
23
|
-
error: null,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
export const useGenerationOrchestrator = <TInput, TResult>(
|
|
27
|
-
strategy: GenerationStrategy<TInput, TResult>,
|
|
28
|
-
config: GenerationConfig,
|
|
29
|
-
): UseGenerationOrchestratorReturn<TInput, TResult> => {
|
|
30
|
-
const { userId, alertMessages, onSuccess, onError, moderation, lifecycle } = config;
|
|
31
|
-
|
|
32
|
-
const [state, setState] = useState<GenerationState<TResult>>(getInitialState<TResult>());
|
|
33
|
-
const isGeneratingRef = useRef(false);
|
|
34
|
-
const isMountedRef = useRef(true);
|
|
35
|
-
const abortControllerRef = useRef<AbortController | null>(null);
|
|
36
|
-
const cleanupTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
37
|
-
|
|
38
|
-
// Stable refs for callbacks — prevents useCallback deps from thrashing when
|
|
39
|
-
// callers pass inline functions (which create new references every render).
|
|
40
|
-
const onSuccessRef = useRef(onSuccess);
|
|
41
|
-
const onErrorRef = useRef(onError);
|
|
42
|
-
// Update refs in render body (not useEffect) so they're always in sync — no 1-frame delay
|
|
43
|
-
onSuccessRef.current = onSuccess;
|
|
44
|
-
onErrorRef.current = onError;
|
|
45
|
-
|
|
46
|
-
const offlineStore = useOfflineStore();
|
|
47
|
-
const { showError, showSuccess } = useAlert();
|
|
48
|
-
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
isMountedRef.current = true;
|
|
51
|
-
return () => {
|
|
52
|
-
isMountedRef.current = false;
|
|
53
|
-
abortControllerRef.current?.abort();
|
|
54
|
-
// Clear any pending lifecycle complete timeout
|
|
55
|
-
if (cleanupTimeoutRef.current) {
|
|
56
|
-
clearTimeout(cleanupTimeoutRef.current);
|
|
57
|
-
cleanupTimeoutRef.current = null;
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
}, []);
|
|
61
|
-
|
|
62
|
-
const handleLifecycleComplete = useCallback(
|
|
63
|
-
(status: "success" | "error", result?: TResult, error?: GenerationError) => {
|
|
64
|
-
if (!lifecycle?.onComplete) return;
|
|
65
|
-
|
|
66
|
-
// Clear any existing timeout first
|
|
67
|
-
if (cleanupTimeoutRef.current) {
|
|
68
|
-
clearTimeout(cleanupTimeoutRef.current);
|
|
69
|
-
cleanupTimeoutRef.current = null;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const delay = lifecycle.completeDelay ?? 500;
|
|
73
|
-
cleanupTimeoutRef.current = setTimeout(() => {
|
|
74
|
-
if (isMountedRef.current) {
|
|
75
|
-
lifecycle.onComplete?.(status, result, error);
|
|
76
|
-
}
|
|
77
|
-
cleanupTimeoutRef.current = null;
|
|
78
|
-
}, delay);
|
|
79
|
-
},
|
|
80
|
-
[lifecycle],
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
const executeGeneration = useCallback(
|
|
84
|
-
async (input: TInput) => {
|
|
85
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
86
|
-
console.log("[Orchestrator] ----------------------------------------");
|
|
87
|
-
console.log("[Orchestrator] executeGeneration() called");
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Check abort signal before starting
|
|
91
|
-
if (abortControllerRef.current?.signal.aborted) {
|
|
92
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
93
|
-
console.log("[Orchestrator] Aborted before generation started");
|
|
94
|
-
}
|
|
95
|
-
throw new Error("Generation aborted");
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
setState((prev) => ({ ...prev, status: "generating" }));
|
|
99
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
100
|
-
console.log("[Orchestrator] State: generating - calling strategy.execute()");
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const result = await strategy.execute(input);
|
|
104
|
-
|
|
105
|
-
// Check abort signal after execution
|
|
106
|
-
if (abortControllerRef.current?.signal.aborted) {
|
|
107
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
108
|
-
console.log("[Orchestrator] Aborted after generation completed");
|
|
109
|
-
}
|
|
110
|
-
throw new Error("Generation aborted");
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
114
|
-
console.log("[Orchestrator] strategy.execute() completed");
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (strategy.save && userId) {
|
|
118
|
-
// Check abort signal before save
|
|
119
|
-
if (abortControllerRef.current?.signal.aborted) {
|
|
120
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
121
|
-
console.log("[Orchestrator] Aborted before save");
|
|
122
|
-
}
|
|
123
|
-
throw new Error("Generation aborted");
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (isMountedRef.current) setState((prev) => ({ ...prev, status: "saving" }));
|
|
127
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
128
|
-
console.log("[Orchestrator] Saving result to Firestore");
|
|
129
|
-
}
|
|
130
|
-
try {
|
|
131
|
-
await strategy.save(result, userId);
|
|
132
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
133
|
-
console.log("[Orchestrator] Result saved successfully");
|
|
134
|
-
}
|
|
135
|
-
} catch (saveErr) {
|
|
136
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
137
|
-
console.log("[Orchestrator] ERROR: Save failed:", saveErr);
|
|
138
|
-
}
|
|
139
|
-
// Update state to error on save failure
|
|
140
|
-
if (isMountedRef.current) {
|
|
141
|
-
setState((prev) => ({ ...prev, status: "error", isGenerating: false }));
|
|
142
|
-
}
|
|
143
|
-
throw createGenerationError("save", alertMessages.saveFailed, saveErr instanceof Error ? saveErr : undefined);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Final abort check before success
|
|
148
|
-
if (abortControllerRef.current?.signal.aborted) {
|
|
149
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
150
|
-
console.log("[Orchestrator] Aborted before success callback");
|
|
151
|
-
}
|
|
152
|
-
throw new Error("Generation aborted");
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (isMountedRef.current) setState({ status: "success", isGenerating: false, result, error: null });
|
|
156
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
157
|
-
console.log("[Orchestrator] ✅ Generation SUCCESS");
|
|
158
|
-
console.log("[Orchestrator] ========================================");
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (alertMessages.success) showSuccess("Success", alertMessages.success);
|
|
162
|
-
await onSuccessRef.current?.(result);
|
|
163
|
-
handleLifecycleComplete("success", result);
|
|
164
|
-
return result;
|
|
165
|
-
},
|
|
166
|
-
[strategy, userId, alertMessages, showSuccess, handleLifecycleComplete],
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
const generate = useCallback(
|
|
170
|
-
async (input: TInput): Promise<TResult | void> => {
|
|
171
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
172
|
-
console.log("[Orchestrator] ========================================");
|
|
173
|
-
console.log("[Orchestrator] generate() called with input:", JSON.stringify(input).substring(0, 200));
|
|
174
|
-
console.log("[Orchestrator] isGenerating:", isGeneratingRef.current);
|
|
175
|
-
console.log("[Orchestrator] userId:", userId);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (isGeneratingRef.current) {
|
|
179
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
180
|
-
console.log("[Orchestrator] BLOCKED: Already generating");
|
|
181
|
-
}
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Create new AbortController for this generation
|
|
186
|
-
abortControllerRef.current = new AbortController();
|
|
187
|
-
isGeneratingRef.current = true;
|
|
188
|
-
let moderationPending = false;
|
|
189
|
-
setState({ ...getInitialState<TResult>(), status: "checking", isGenerating: true });
|
|
190
|
-
|
|
191
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
192
|
-
console.log("[Orchestrator] State set to 'checking', isGenerating: true");
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
try {
|
|
196
|
-
// Check online status inside the try block to avoid dependency on offlineStore.isOnline
|
|
197
|
-
if (!offlineStore.isOnline) {
|
|
198
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
199
|
-
console.log("[Orchestrator] ERROR: User is offline");
|
|
200
|
-
}
|
|
201
|
-
throw createGenerationError("network", alertMessages.networkError);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
205
|
-
console.log("[Orchestrator] Online check passed");
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Check if aborted before moderation
|
|
209
|
-
if (abortControllerRef.current.signal.aborted) {
|
|
210
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
211
|
-
console.log("[Orchestrator] ERROR: Generation aborted (2)");
|
|
212
|
-
}
|
|
213
|
-
throw new Error("Generation aborted");
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
217
|
-
console.log("[Orchestrator] Starting moderation check");
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const result = await handleModeration({
|
|
221
|
-
input,
|
|
222
|
-
moderation,
|
|
223
|
-
alertMessages,
|
|
224
|
-
isMountedRef,
|
|
225
|
-
isGeneratingRef,
|
|
226
|
-
setState: (s) => setState(s as GenerationState<TResult>),
|
|
227
|
-
resetState: () => setState(getInitialState<TResult>()),
|
|
228
|
-
executeGeneration,
|
|
229
|
-
showError,
|
|
230
|
-
onError,
|
|
231
|
-
handleLifecycleComplete,
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
// If handleModeration returned undefined, the warning dialog was shown.
|
|
235
|
-
// The dialog's proceed/cancel callbacks now own isGeneratingRef — don't reset in finally.
|
|
236
|
-
if (result === undefined && moderation) {
|
|
237
|
-
moderationPending = true;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
return result;
|
|
241
|
-
} catch (err) {
|
|
242
|
-
// Don't show error if aborted
|
|
243
|
-
if (abortControllerRef.current?.signal.aborted) {
|
|
244
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
245
|
-
console.log("[Orchestrator] Generation aborted");
|
|
246
|
-
}
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const error = parseError(err);
|
|
251
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) console.log("[Orchestrator] Error:", error);
|
|
252
|
-
if (isMountedRef.current) setState({ status: "error", isGenerating: false, result: null, error });
|
|
253
|
-
showError("Error", getAlertMessage(error, alertMessages));
|
|
254
|
-
await onErrorRef.current?.(error);
|
|
255
|
-
handleLifecycleComplete("error", undefined, error);
|
|
256
|
-
throw error;
|
|
257
|
-
} finally {
|
|
258
|
-
// Only reset if moderation dialog did not take ownership
|
|
259
|
-
if (!moderationPending) {
|
|
260
|
-
isGeneratingRef.current = false;
|
|
261
|
-
}
|
|
262
|
-
abortControllerRef.current = null;
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
[offlineStore, moderation, alertMessages, strategy, executeGeneration, showError, handleLifecycleComplete],
|
|
266
|
-
);
|
|
267
|
-
|
|
268
|
-
const reset = useCallback(() => {
|
|
269
|
-
abortControllerRef.current?.abort();
|
|
270
|
-
abortControllerRef.current = null;
|
|
271
|
-
setState(getInitialState<TResult>());
|
|
272
|
-
isGeneratingRef.current = false;
|
|
273
|
-
}, []);
|
|
274
|
-
|
|
275
|
-
return { generate, reset, status: state.status, isGenerating: state.isGenerating, result: state.result, error: state.error };
|
|
276
|
-
};
|
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic Generation Hook Factory
|
|
3
|
-
* Creates type-safe generation hooks with error handling, progress tracking, and abort support
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { useState, useCallback, useRef, useEffect } from "react";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Generation state
|
|
10
|
-
*/
|
|
11
|
-
export interface GenerationState {
|
|
12
|
-
isGenerating: boolean;
|
|
13
|
-
progress: number;
|
|
14
|
-
error: string | null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Generation callbacks
|
|
19
|
-
*/
|
|
20
|
-
export interface GenerationCallbacks<TResult> {
|
|
21
|
-
/** Called when generation succeeds */
|
|
22
|
-
onSuccess?: (result: TResult) => void;
|
|
23
|
-
/** Called when generation fails */
|
|
24
|
-
onError?: (error: string) => void;
|
|
25
|
-
/** Called on progress update */
|
|
26
|
-
onProgress?: (progress: number) => void;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Generation hook configuration
|
|
31
|
-
*/
|
|
32
|
-
export interface GenerationHookConfig<TRequest, TResult> {
|
|
33
|
-
/** Execute the generation request */
|
|
34
|
-
execute: (request: TRequest, signal?: AbortSignal) => Promise<TResult>;
|
|
35
|
-
/** Optional validation before execution */
|
|
36
|
-
validate?: (request: TRequest) => string | null;
|
|
37
|
-
/** Optional transform for errors */
|
|
38
|
-
transformError?: (error: unknown) => string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Generation hook return type
|
|
43
|
-
*/
|
|
44
|
-
export interface GenerationHookReturn<TRequest, TResult> {
|
|
45
|
-
generationState: GenerationState;
|
|
46
|
-
handleGenerate: (request: TRequest) => Promise<TResult | null>;
|
|
47
|
-
setProgress: (progress: number) => void;
|
|
48
|
-
setError: (error: string | null) => void;
|
|
49
|
-
abort: () => void;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const INITIAL_STATE: GenerationState = {
|
|
53
|
-
isGenerating: false,
|
|
54
|
-
progress: 0,
|
|
55
|
-
error: null,
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Creates a type-safe generation hook
|
|
60
|
-
* @param config - Generation hook configuration
|
|
61
|
-
* @param callbacks - Generation callbacks
|
|
62
|
-
* @returns Generation hook
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* ```ts
|
|
66
|
-
* const useMyGeneration = createGenerationHook({
|
|
67
|
-
* execute: async (request) => {
|
|
68
|
-
* return await api.generate(request);
|
|
69
|
-
* },
|
|
70
|
-
* validate: (request) => {
|
|
71
|
-
* if (!request.prompt) return "Prompt is required";
|
|
72
|
-
* return null;
|
|
73
|
-
* },
|
|
74
|
-
* });
|
|
75
|
-
*
|
|
76
|
-
* // Usage
|
|
77
|
-
* const { generationState, handleGenerate } = useMyGeneration({
|
|
78
|
-
* onSuccess: (result) => console.log("Success!", result),
|
|
79
|
-
* onError: (error) => console.error("Error:", error),
|
|
80
|
-
* });
|
|
81
|
-
* ```
|
|
82
|
-
*/
|
|
83
|
-
export function createGenerationHook<TRequest, TResult>(
|
|
84
|
-
config: GenerationHookConfig<TRequest, TResult>
|
|
85
|
-
) {
|
|
86
|
-
return function useGeneration(
|
|
87
|
-
callbacks: GenerationCallbacks<TResult> = {}
|
|
88
|
-
): GenerationHookReturn<TRequest, TResult> {
|
|
89
|
-
const [generationState, setGenerationState] = useState<GenerationState>(INITIAL_STATE);
|
|
90
|
-
|
|
91
|
-
const abortControllerRef = useRef<AbortController | null>(null);
|
|
92
|
-
const isMountedRef = useRef(true);
|
|
93
|
-
|
|
94
|
-
// Stabilize callbacks
|
|
95
|
-
const onSuccessRef = useRef(callbacks.onSuccess);
|
|
96
|
-
const onErrorRef = useRef(callbacks.onError);
|
|
97
|
-
const onProgressRef = useRef(callbacks.onProgress);
|
|
98
|
-
|
|
99
|
-
useEffect(() => {
|
|
100
|
-
onSuccessRef.current = callbacks.onSuccess;
|
|
101
|
-
onErrorRef.current = callbacks.onError;
|
|
102
|
-
onProgressRef.current = callbacks.onProgress;
|
|
103
|
-
}, [callbacks.onSuccess, callbacks.onError, callbacks.onProgress]);
|
|
104
|
-
|
|
105
|
-
// Cleanup on unmount
|
|
106
|
-
useEffect(() => {
|
|
107
|
-
isMountedRef.current = true;
|
|
108
|
-
return () => {
|
|
109
|
-
isMountedRef.current = false;
|
|
110
|
-
abortControllerRef.current?.abort();
|
|
111
|
-
};
|
|
112
|
-
}, []);
|
|
113
|
-
|
|
114
|
-
const setProgress = useCallback((progress: number) => {
|
|
115
|
-
if (!isMountedRef.current) return;
|
|
116
|
-
setGenerationState((prev) => ({ ...prev, progress }));
|
|
117
|
-
onProgressRef.current?.(progress);
|
|
118
|
-
}, []);
|
|
119
|
-
|
|
120
|
-
const setError = useCallback((error: string | null) => {
|
|
121
|
-
if (!isMountedRef.current) return;
|
|
122
|
-
setGenerationState((prev) => ({ ...prev, error, isGenerating: false }));
|
|
123
|
-
if (error) {
|
|
124
|
-
onErrorRef.current?.(error);
|
|
125
|
-
}
|
|
126
|
-
}, []);
|
|
127
|
-
|
|
128
|
-
const abort = useCallback(() => {
|
|
129
|
-
abortControllerRef.current?.abort();
|
|
130
|
-
if (isMountedRef.current) {
|
|
131
|
-
setGenerationState((prev) => ({
|
|
132
|
-
...prev,
|
|
133
|
-
isGenerating: false,
|
|
134
|
-
error: "Generation aborted",
|
|
135
|
-
}));
|
|
136
|
-
}
|
|
137
|
-
}, []);
|
|
138
|
-
|
|
139
|
-
const handleGenerate = useCallback(
|
|
140
|
-
async (request: TRequest): Promise<TResult | null> => {
|
|
141
|
-
// Validate request
|
|
142
|
-
if (config.validate) {
|
|
143
|
-
const validationError = config.validate(request);
|
|
144
|
-
if (validationError) {
|
|
145
|
-
setError(validationError);
|
|
146
|
-
return null;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Create new AbortController
|
|
151
|
-
abortControllerRef.current = new AbortController();
|
|
152
|
-
|
|
153
|
-
setGenerationState({
|
|
154
|
-
isGenerating: true,
|
|
155
|
-
progress: 0,
|
|
156
|
-
error: null,
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
try {
|
|
160
|
-
const result = await config.execute(
|
|
161
|
-
request,
|
|
162
|
-
abortControllerRef.current.signal
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
if (!isMountedRef.current || abortControllerRef.current.signal.aborted) {
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
setGenerationState((prev) => ({
|
|
170
|
-
...prev,
|
|
171
|
-
isGenerating: false,
|
|
172
|
-
progress: 100
|
|
173
|
-
}));
|
|
174
|
-
|
|
175
|
-
onSuccessRef.current?.(result);
|
|
176
|
-
return result;
|
|
177
|
-
} catch (error) {
|
|
178
|
-
if (!isMountedRef.current || abortControllerRef.current.signal.aborted) {
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const errorMessage = config.transformError
|
|
183
|
-
? config.transformError(error)
|
|
184
|
-
: error instanceof Error
|
|
185
|
-
? error.message
|
|
186
|
-
: String(error);
|
|
187
|
-
|
|
188
|
-
setError(errorMessage);
|
|
189
|
-
return null;
|
|
190
|
-
} finally {
|
|
191
|
-
abortControllerRef.current = null;
|
|
192
|
-
}
|
|
193
|
-
},
|
|
194
|
-
[config, setError]
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
return {
|
|
198
|
-
generationState,
|
|
199
|
-
handleGenerate,
|
|
200
|
-
setProgress,
|
|
201
|
-
setError,
|
|
202
|
-
abort,
|
|
203
|
-
};
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Creates a generation hook with progress updates
|
|
209
|
-
* Useful when the generation API supports progress callbacks
|
|
210
|
-
*/
|
|
211
|
-
export function createGenerationHookWithProgress<TRequest, TResult>(
|
|
212
|
-
config: GenerationHookConfig<TRequest, TResult> & {
|
|
213
|
-
/** Get progress stream or polling function */
|
|
214
|
-
subscribeToProgress?: (
|
|
215
|
-
request: TRequest,
|
|
216
|
-
onProgress: (progress: number) => void
|
|
217
|
-
) => () => void;
|
|
218
|
-
}
|
|
219
|
-
) {
|
|
220
|
-
const baseHook = createGenerationHook(config);
|
|
221
|
-
|
|
222
|
-
return function useGenerationWithProgress(
|
|
223
|
-
callbacks: GenerationCallbacks<TResult> = {}
|
|
224
|
-
): GenerationHookReturn<TRequest, TResult> {
|
|
225
|
-
const hookResult = baseHook(callbacks);
|
|
226
|
-
const unsubscribeRef = useRef<(() => void) | null>(null);
|
|
227
|
-
|
|
228
|
-
const handleGenerateWithProgress = useCallback(
|
|
229
|
-
async (request: TRequest): Promise<TResult | null> => {
|
|
230
|
-
// Subscribe to progress if available
|
|
231
|
-
if (config.subscribeToProgress) {
|
|
232
|
-
unsubscribeRef.current = config.subscribeToProgress(
|
|
233
|
-
request,
|
|
234
|
-
hookResult.setProgress
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
try {
|
|
239
|
-
return await hookResult.handleGenerate(request);
|
|
240
|
-
} finally {
|
|
241
|
-
unsubscribeRef.current?.();
|
|
242
|
-
unsubscribeRef.current = null;
|
|
243
|
-
}
|
|
244
|
-
},
|
|
245
|
-
[hookResult, config.subscribeToProgress]
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
return {
|
|
249
|
-
...hookResult,
|
|
250
|
-
handleGenerate: handleGenerateWithProgress,
|
|
251
|
-
};
|
|
252
|
-
};
|
|
253
|
-
}
|