@umituz/react-native-ai-generation-content 1.10.2 → 1.11.0

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.10.2",
3
+ "version": "1.11.0",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
package/src/index.ts CHANGED
@@ -157,6 +157,7 @@ export {
157
157
  useGeneration,
158
158
  usePendingJobs,
159
159
  useBackgroundGeneration,
160
+ usePhotoGeneration,
160
161
  } from "./presentation/hooks";
161
162
 
162
163
  export type {
@@ -167,6 +168,13 @@ export type {
167
168
  UseBackgroundGenerationOptions,
168
169
  UseBackgroundGenerationReturn,
169
170
  DirectExecutionResult,
171
+ UsePhotoGenerationReturn,
172
+ PhotoGenerationInput,
173
+ PhotoGenerationResult,
174
+ PhotoGenerationError,
175
+ PhotoGenerationConfig,
176
+ PhotoGenerationState,
177
+ PhotoGenerationStatus,
170
178
  } from "./presentation/hooks";
171
179
 
172
180
  // =============================================================================
@@ -20,3 +20,17 @@ export type {
20
20
  UseBackgroundGenerationReturn,
21
21
  DirectExecutionResult,
22
22
  } from "./use-background-generation";
23
+
24
+ export { usePhotoGeneration } from "./usePhotoGeneration";
25
+ export type {
26
+ UsePhotoGenerationReturn,
27
+ } from "./usePhotoGeneration";
28
+
29
+ export type {
30
+ PhotoGenerationInput,
31
+ PhotoGenerationResult,
32
+ PhotoGenerationError,
33
+ PhotoGenerationConfig,
34
+ PhotoGenerationState,
35
+ PhotoGenerationStatus,
36
+ } from "./photo-generation.types";
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Photo Generation Types
3
+ * Generic types for photo-based AI generation workflows
4
+ */
5
+
6
+ export interface PhotoGenerationInput<TMetadata = any> {
7
+ photos: Array<{ uri: string; base64: string }>;
8
+ metadata?: TMetadata;
9
+ }
10
+
11
+ export interface PhotoGenerationResult<TResult = any> {
12
+ success: boolean;
13
+ data?: TResult;
14
+ error?: PhotoGenerationError;
15
+ }
16
+
17
+ export interface PhotoGenerationError {
18
+ type: "network_error" | "policy_violation" | "save_failed" | "credit_failed" | "unknown";
19
+ message: string;
20
+ originalError?: Error;
21
+ }
22
+
23
+ export interface PhotoGenerationConfig<TInput, TResult, TSaveInput> {
24
+ generate: (input: TInput) => Promise<TResult>;
25
+ save?: (result: TResult, input: TInput) => Promise<TSaveInput>;
26
+ checkCredits?: () => Promise<boolean>;
27
+ checkNetwork?: () => Promise<boolean>;
28
+ deductCredits?: () => Promise<void>;
29
+ onSuccess?: (result: TResult) => void;
30
+ onError?: (error: PhotoGenerationError) => void;
31
+ onSaveComplete?: (saveResult: TSaveInput) => void;
32
+ }
33
+
34
+ export interface PhotoGenerationState<TResult = any> {
35
+ isGenerating: boolean;
36
+ result: TResult | null;
37
+ error: PhotoGenerationError | null;
38
+ progress: number;
39
+ }
40
+
41
+ export type PhotoGenerationStatus = "idle" | "validating" | "generating" | "saving" | "success" | "error";
@@ -0,0 +1,173 @@
1
+ /**
2
+ * usePhotoGeneration Hook
3
+ * Generic hook for photo-based AI generation workflows
4
+ */
5
+
6
+ import { useState, useCallback, useRef } from "react";
7
+ import type {
8
+ PhotoGenerationConfig,
9
+ PhotoGenerationState,
10
+ PhotoGenerationError,
11
+ PhotoGenerationStatus,
12
+ } from "./photo-generation.types";
13
+
14
+ export interface UsePhotoGenerationReturn<TResult> extends PhotoGenerationState<TResult> {
15
+ generate: <TInput>(input: TInput) => Promise<void>;
16
+ reset: () => void;
17
+ status: PhotoGenerationStatus;
18
+ }
19
+
20
+ export const usePhotoGeneration = <TInput, TResult, TSaveInput = any>(
21
+ config: PhotoGenerationConfig<TInput, TResult, TSaveInput>,
22
+ ): UsePhotoGenerationReturn<TResult> => {
23
+ const {
24
+ generate: generateFn,
25
+ save: saveFn,
26
+ checkCredits,
27
+ checkNetwork,
28
+ deductCredits,
29
+ onSuccess,
30
+ onError,
31
+ onSaveComplete,
32
+ } = config;
33
+
34
+ const [state, setState] = useState<PhotoGenerationState<TResult>>({
35
+ isGenerating: false,
36
+ result: null,
37
+ error: null,
38
+ progress: 0,
39
+ });
40
+
41
+ const [status, setStatus] = useState<PhotoGenerationStatus>("idle");
42
+ const isGeneratingRef = useRef(false);
43
+
44
+ const createError = useCallback(
45
+ (
46
+ type: PhotoGenerationError["type"],
47
+ message: string,
48
+ originalError?: Error,
49
+ ): PhotoGenerationError => ({
50
+ type,
51
+ message,
52
+ originalError,
53
+ }),
54
+ [],
55
+ );
56
+
57
+ const generate = useCallback(
58
+ async (input: TInput) => {
59
+ if (isGeneratingRef.current) {
60
+ if (__DEV__) console.warn("[usePhotoGeneration] Generation already in progress");
61
+ return;
62
+ }
63
+
64
+ isGeneratingRef.current = true;
65
+ setState({ isGenerating: true, result: null, error: null, progress: 0 });
66
+ setStatus("validating");
67
+
68
+ try {
69
+ // Check network connectivity
70
+ if (checkNetwork) {
71
+ const isOnline = await checkNetwork();
72
+ if (!isOnline) {
73
+ throw createError("network_error", "No internet connection");
74
+ }
75
+ }
76
+
77
+ // Check credits
78
+ if (checkCredits) {
79
+ const hasCredits = await checkCredits();
80
+ if (!hasCredits) {
81
+ throw createError("credit_failed", "Insufficient credits");
82
+ }
83
+ }
84
+
85
+ setStatus("generating");
86
+ setState((prev) => ({ ...prev, progress: 20 }));
87
+
88
+ // Generate without timeout - let AI provider handle its own timeout
89
+ const result = await generateFn(input);
90
+
91
+ setState((prev) => ({ ...prev, progress: 60 }));
92
+
93
+ // Save result
94
+ if (saveFn) {
95
+ setStatus("saving");
96
+ try {
97
+ const saveResult = await saveFn(result, input);
98
+ onSaveComplete?.(saveResult);
99
+ } catch (saveError) {
100
+ throw createError(
101
+ "save_failed",
102
+ "Failed to save result",
103
+ saveError as Error,
104
+ );
105
+ }
106
+ }
107
+
108
+ setState((prev) => ({ ...prev, progress: 80 }));
109
+
110
+ // Deduct credits after successful generation
111
+ if (deductCredits) {
112
+ try {
113
+ await deductCredits();
114
+ } catch (deductError) {
115
+ if (__DEV__)
116
+ console.error("[usePhotoGeneration] Credit deduction failed", deductError);
117
+ }
118
+ }
119
+
120
+ setState({
121
+ isGenerating: false,
122
+ result,
123
+ error: null,
124
+ progress: 100,
125
+ });
126
+ setStatus("success");
127
+ onSuccess?.(result);
128
+ } catch (error: any) {
129
+ const generationError =
130
+ error.type
131
+ ? error
132
+ : error.name === "ContentPolicyViolationError"
133
+ ? createError("policy_violation", "Content policy violation", error)
134
+ : createError("unknown", error.message || "Generation failed", error);
135
+
136
+ setState({
137
+ isGenerating: false,
138
+ result: null,
139
+ error: generationError,
140
+ progress: 0,
141
+ });
142
+ setStatus("error");
143
+ onError?.(generationError);
144
+ } finally {
145
+ isGeneratingRef.current = false;
146
+ }
147
+ },
148
+ [
149
+ generateFn,
150
+ saveFn,
151
+ checkCredits,
152
+ checkNetwork,
153
+ deductCredits,
154
+ onSuccess,
155
+ onError,
156
+ onSaveComplete,
157
+ createError,
158
+ ],
159
+ );
160
+
161
+ const reset = useCallback(() => {
162
+ setState({ isGenerating: false, result: null, error: null, progress: 0 });
163
+ setStatus("idle");
164
+ isGeneratingRef.current = false;
165
+ }, []);
166
+
167
+ return {
168
+ ...state,
169
+ generate,
170
+ reset,
171
+ status,
172
+ };
173
+ };