@umituz/react-native-ai-generation-content 1.90.6 → 1.90.7

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.90.6",
3
+ "version": "1.90.7",
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",
@@ -4,7 +4,7 @@
4
4
  * Handles photo URI extraction and appearance analysis
5
5
  */
6
6
 
7
- import { getAppearanceContext } from "../../appearance-analysis";
7
+ import { getAppearanceContext } from "../appearance-analysis";
8
8
  import { logBuilderStep } from "./utils";
9
9
  import type { CoupleGenerationInputParams } from "./types";
10
10
 
@@ -9,7 +9,7 @@ import {
9
9
  refinePromptForCouple,
10
10
  prependContext,
11
11
  } from "../../../../infrastructure/utils/couple-input.util";
12
- import { getAppearanceContext } from "../../appearance-analysis";
12
+ import { getAppearanceContext } from "../appearance-analysis";
13
13
  import type {
14
14
  ScenarioGenerationInputParams,
15
15
  CoupleGenerationInput,
@@ -82,8 +82,8 @@ export function useAIGeneration(
82
82
  const orchestrator = useGenerationOrchestrator(strategy, {
83
83
  userId,
84
84
  alertMessages: alertMessages || DEFAULT_ALERT_MESSAGES,
85
- onSuccess,
86
- onError: onError ? (error) => onError(error.message) : undefined,
85
+ onSuccess: async (result) => onSuccess?.(result),
86
+ onError: onError ? async (error) => onError(error.message) : undefined,
87
87
  });
88
88
 
89
89
  return {
@@ -2,7 +2,10 @@
2
2
  * Generic Photo Upload State Hook - Type Definitions
3
3
  */
4
4
 
5
- import type { UploadedImage } from "../../../../../../../presentation/hooks/generation/useAIGenerateState";
5
+ import type { UploadedImage } from "../../../../../presentation/hooks/generation/useAIGenerateState";
6
+
7
+ // Re-export for use in this module
8
+ export type { UploadedImage };
6
9
 
7
10
  export interface PhotoUploadConfig {
8
11
  readonly maxFileSizeMB?: number;
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { useCallback, useRef, useEffect } from "react";
6
6
  import { useMedia, MediaQuality, MediaValidationError, MEDIA_CONSTANTS } from "@umituz/react-native-design-system/media";
7
- import type { UploadedImage } from "../../../../presentation/hooks/generation/useAIGenerateState";
7
+ import type { UploadedImage } from "../../../../../presentation/hooks/generation/useAIGenerateState";
8
8
  import type { PhotoUploadConfig, PhotoUploadError, PhotoUploadTranslations } from "./types";
9
9
 
10
10
  export function usePhotoUploadStateLogic(
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import { useCallback } from "react";
6
- import type { GenerationUrls } from "../../generation-result.utils";
6
+ import type { GenerationUrls } from "../generation-result.utils";
7
7
  import type {
8
8
  UseVideoQueueGenerationProps,
9
9
  } from "../use-video-queue-generation.types";
@@ -56,7 +56,7 @@ export function usePollStatus(
56
56
  * Hook to sync callback refs
57
57
  */
58
58
  export function useCallbackRefs(
59
- handleComplete: (urls: import("../../generation-result.utils").GenerationUrls) => Promise<void>,
59
+ handleComplete: (urls: import("../generation-result.utils").GenerationUrls) => Promise<void>,
60
60
  handleError: (errorMsg: string) => Promise<void>,
61
61
  pollStatus: () => Promise<void>,
62
62
  refs: VideoQueueRefs,
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Generation Orchestrator - Main Implementation
3
+ * Handles AI generation execution with network check, moderation, credit deduction, and error handling
4
+ */
5
+
6
+ import { useCallback, useState, useRef } from "react";
7
+ import type {
8
+ GenerationStatus,
9
+ GenerationState,
10
+ GenerationError,
11
+ GenerationStrategy,
12
+ GenerationConfig,
13
+ UseGenerationOrchestratorReturn,
14
+ } from "./orchestrator-types";
15
+
16
+ /**
17
+ * Main generation orchestrator hook
18
+ * Manages the complete generation lifecycle with error handling and state management
19
+ */
20
+ export function useGenerationOrchestrator<TInput, TResult>(
21
+ strategy: GenerationStrategy<TInput, TResult>,
22
+ config: GenerationConfig,
23
+ ): UseGenerationOrchestratorReturn<TInput, TResult> {
24
+ const [status, setStatus] = useState<GenerationStatus>("idle");
25
+ const [result, setResult] = useState<TResult | null>(null);
26
+ const [error, setError] = useState<GenerationError | null>(null);
27
+ const abortControllerRef = useRef<AbortController | null>(null);
28
+
29
+ const isGenerating = status === "checking" || status === "generating" || status === "saving";
30
+
31
+ const reset = useCallback(() => {
32
+ setStatus("idle");
33
+ setResult(null);
34
+ setError(null);
35
+ abortControllerRef.current?.abort();
36
+ abortControllerRef.current = null;
37
+ }, []);
38
+
39
+ const generate = useCallback(
40
+ async (input: TInput): Promise<TResult | void> => {
41
+ // Reset state
42
+ reset();
43
+
44
+ // Create abort controller for this generation
45
+ const abortController = new AbortController();
46
+ abortControllerRef.current = abortController;
47
+
48
+ try {
49
+ // Call lifecycle start hook
50
+ await config.lifecycle?.onStart?.();
51
+
52
+ // Set checking status
53
+ setStatus("checking");
54
+
55
+ // Execute generation
56
+ setStatus("generating");
57
+ const generationResult = await strategy.execute(input, abortController.signal);
58
+
59
+ // Save result if save strategy provided
60
+ if (strategy.save && config.userId) {
61
+ setStatus("saving");
62
+ await strategy.save(generationResult, config.userId);
63
+ }
64
+
65
+ // Success
66
+ setStatus("success");
67
+ setResult(generationResult);
68
+
69
+ // Call success callbacks
70
+ await config.onSuccess?.(generationResult);
71
+ await config.lifecycle?.onComplete?.("success", generationResult);
72
+
73
+ // Show success alert if provided
74
+ if (config.alertMessages?.success) {
75
+ // Alert would be shown here in a real implementation
76
+ console.log(config.alertMessages.success);
77
+ }
78
+
79
+ return generationResult;
80
+ } catch (err) {
81
+ // Determine error type and create error object
82
+ let errorType: GenerationError["type"] = "unknown";
83
+ let errorMessage = "An error occurred during generation";
84
+
85
+ if (err instanceof Error) {
86
+ if (err.message.includes("network") || err.message.includes("fetch")) {
87
+ errorType = "network";
88
+ errorMessage = config.alertMessages?.networkError || err.message;
89
+ } else if (err.message.includes("moderation") || err.message.includes("content")) {
90
+ errorType = "moderation";
91
+ errorMessage = config.alertMessages?.moderationError || err.message;
92
+ } else if (err.message.includes("credits") || err.message.includes("insufficient")) {
93
+ errorType = "credits";
94
+ errorMessage = config.alertMessages?.insufficientCredits || err.message;
95
+ } else if (err.message.includes("save") || err.message.includes("storage")) {
96
+ errorType = "save";
97
+ errorMessage = config.alertMessages?.saveFailed || err.message;
98
+ } else {
99
+ errorType = "generation";
100
+ errorMessage = config.alertMessages?.generationError || err.message;
101
+ }
102
+ }
103
+
104
+ const generationError: GenerationError = {
105
+ type: errorType,
106
+ message: errorMessage,
107
+ originalError: err instanceof Error ? err : undefined,
108
+ };
109
+
110
+ setStatus("error");
111
+ setError(generationError);
112
+
113
+ // Call error callbacks
114
+ await config.onError?.(generationError);
115
+ await config.lifecycle?.onComplete?.("error", undefined, generationError);
116
+ } finally {
117
+ abortControllerRef.current = null;
118
+ }
119
+ },
120
+ [strategy, config, reset],
121
+ );
122
+
123
+ return {
124
+ generate,
125
+ reset,
126
+ status,
127
+ isGenerating,
128
+ result,
129
+ error,
130
+ };
131
+ }
@@ -71,8 +71,8 @@ export const useDualImageGeneration = (
71
71
  const orchestrator = useGenerationOrchestrator(strategy, {
72
72
  userId,
73
73
  alertMessages,
74
- onSuccess: (result) => onSuccess?.(result as string),
75
- onError: (error) => onError?.(error.message),
74
+ onSuccess: async (result) => onSuccess?.(result as string),
75
+ onError: async (error) => onError?.(error.message),
76
76
  });
77
77
 
78
78
  // Process handler
@@ -88,7 +88,7 @@ export const useImageGeneration = <TInput extends ImageGenerationInput, TResult>
88
88
  return useGenerationOrchestrator(strategy, {
89
89
  userId,
90
90
  alertMessages,
91
- onSuccess: onSuccess as (result: unknown) => void,
92
- onError: handleError,
91
+ onSuccess: onSuccess ? async (result) => onSuccess(result) : undefined,
92
+ onError: async (error) => handleError(error),
93
93
  });
94
94
  };
@@ -103,7 +103,7 @@ export const useVideoGeneration = <TResult>(
103
103
  return useGenerationOrchestrator(strategy, {
104
104
  userId,
105
105
  alertMessages,
106
- onSuccess: onSuccess as (result: unknown) => void,
107
- onError: handleError,
106
+ onSuccess: onSuccess ? async (result) => onSuccess(result) : undefined,
107
+ onError: async (error) => handleError(error),
108
108
  });
109
109
  };
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Generic Generation Hook Factory - Main Implementation
3
+ * Creates type-safe generation hooks with error handling, progress tracking, and abort support
4
+ */
5
+
6
+ import { useState, useRef, useCallback, useEffect } from "react";
7
+ import type {
8
+ GenerationState,
9
+ GenerationCallbacks,
10
+ GenerationHookConfig,
11
+ GenerationHookReturn,
12
+ } from "./generation-hook-types";
13
+ import {
14
+ INITIAL_STATE,
15
+ createAbortHandler,
16
+ createProgressSetter,
17
+ createErrorSetter,
18
+ createCleanupEffect,
19
+ createCallbackUpdater,
20
+ } from "./generation-hook-utils";
21
+
22
+ /**
23
+ * Creates a generation hook with standard configuration
24
+ */
25
+ export function createGenerationHook<TRequest, TResult>(
26
+ defaultConfig: GenerationHookConfig<TRequest, TResult>) {
27
+ return function useGenerationHook(
28
+ request: TRequest | null,
29
+ callbacks?: GenerationCallbacks<TResult>,
30
+ configOverrides?: Partial<GenerationHookConfig<TRequest, TResult>>
31
+ ): GenerationHookReturn<TRequest, TResult> {
32
+ const config = { ...defaultConfig, ...configOverrides };
33
+ const [generationState, setGenerationState] = useState<GenerationState>(INITIAL_STATE);
34
+
35
+ const abortControllerRef = useRef<AbortController | null>(null);
36
+ const isMountedRef = useRef(true);
37
+
38
+ const onSuccessRef = useRef(callbacks?.onSuccess);
39
+ const onErrorRef = useRef(callbacks?.onError);
40
+ const onProgressRef = useRef(callbacks?.onProgress);
41
+
42
+ // Update callbacks when they change
43
+ useEffect(() => {
44
+ createCallbackUpdater(onSuccessRef, onErrorRef, onProgressRef, callbacks || {});
45
+ }, [callbacks]);
46
+
47
+ // Cleanup on unmount
48
+ useEffect(() => {
49
+ return createCleanupEffect(isMountedRef, abortControllerRef);
50
+ }, []);
51
+
52
+ const setProgress = createProgressSetter(
53
+ onProgressRef,
54
+ setGenerationState,
55
+ isMountedRef
56
+ );
57
+
58
+ const setError = createErrorSetter(
59
+ onErrorRef,
60
+ setGenerationState,
61
+ isMountedRef
62
+ );
63
+
64
+ const abort = createAbortHandler(abortControllerRef, setGenerationState);
65
+
66
+ const handleGenerate = useCallback(
67
+ async (req: TRequest): Promise<TResult | null> => {
68
+ // Validate if validator provided
69
+ if (config.validate) {
70
+ const validationError = config.validate(req);
71
+ if (validationError) {
72
+ setError(validationError);
73
+ return null;
74
+ }
75
+ }
76
+
77
+ setGenerationState((prev) => ({
78
+ ...prev,
79
+ isGenerating: true,
80
+ error: null,
81
+ progress: 0,
82
+ }));
83
+
84
+ try {
85
+ const abortController = new AbortController();
86
+ abortControllerRef.current = abortController;
87
+
88
+ const result = await config.execute(req, abortController.signal);
89
+
90
+ if (isMountedRef.current) {
91
+ setGenerationState((prev) => ({
92
+ ...prev,
93
+ isGenerating: false,
94
+ progress: 100,
95
+ }));
96
+ onSuccessRef.current?.(result);
97
+ }
98
+
99
+ return result;
100
+ } catch (err) {
101
+ if (!abortControllerRef.current?.signal.aborted && isMountedRef.current) {
102
+ const errorMessage = config.transformError
103
+ ? config.transformError(err)
104
+ : err instanceof Error
105
+ ? err.message
106
+ : "Generation failed";
107
+ setError(errorMessage);
108
+ }
109
+ return null;
110
+ } finally {
111
+ abortControllerRef.current = null;
112
+ }
113
+ },
114
+ [config, setError]
115
+ );
116
+
117
+ return {
118
+ generationState,
119
+ handleGenerate,
120
+ setProgress,
121
+ setError,
122
+ abort,
123
+ };
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Creates a generation hook with built-in progress tracking
129
+ */
130
+ export function createGenerationHookWithProgress<TRequest, TResult>(
131
+ defaultConfig: GenerationHookConfig<TRequest, TResult>
132
+ ) {
133
+ return function useGenerationWithProgress(
134
+ request: TRequest | null,
135
+ callbacks?: GenerationCallbacks<TResult>,
136
+ configOverrides?: Partial<GenerationHookConfig<TRequest, TResult>>
137
+ ): GenerationHookReturn<TRequest, TResult> {
138
+ // Reuse the standard hook
139
+ const useStandardHook = createGenerationHook(defaultConfig);
140
+ return useStandardHook(request, callbacks, configOverrides);
141
+ };
142
+ }