@umituz/react-native-ai-generation-content 1.10.2 → 1.10.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.10.2",
3
+ "version": "1.10.4",
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: "timeout" | "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
+ deductCredits?: () => Promise<void>;
28
+ timeout?: number;
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,169 @@
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
+ const DEFAULT_TIMEOUT = 60000;
15
+
16
+ export interface UsePhotoGenerationReturn<TResult> extends PhotoGenerationState<TResult> {
17
+ generate: <TInput>(input: TInput) => Promise<void>;
18
+ reset: () => void;
19
+ status: PhotoGenerationStatus;
20
+ }
21
+
22
+ export const usePhotoGeneration = <TInput, TResult, TSaveInput = any>(
23
+ config: PhotoGenerationConfig<TInput, TResult, TSaveInput>,
24
+ ): UsePhotoGenerationReturn<TResult> => {
25
+ const {
26
+ generate: generateFn,
27
+ save: saveFn,
28
+ checkCredits,
29
+ deductCredits,
30
+ timeout = DEFAULT_TIMEOUT,
31
+ onSuccess,
32
+ onError,
33
+ onSaveComplete,
34
+ } = config;
35
+
36
+ const [state, setState] = useState<PhotoGenerationState<TResult>>({
37
+ isGenerating: false,
38
+ result: null,
39
+ error: null,
40
+ progress: 0,
41
+ });
42
+
43
+ const [status, setStatus] = useState<PhotoGenerationStatus>("idle");
44
+ const isGeneratingRef = useRef(false);
45
+
46
+ const createError = useCallback(
47
+ (
48
+ type: PhotoGenerationError["type"],
49
+ message: string,
50
+ originalError?: Error,
51
+ ): PhotoGenerationError => ({
52
+ type,
53
+ message,
54
+ originalError,
55
+ }),
56
+ [],
57
+ );
58
+
59
+ const generate = useCallback(
60
+ async (input: TInput) => {
61
+ if (isGeneratingRef.current) {
62
+ if (__DEV__) console.warn("[usePhotoGeneration] Generation already in progress");
63
+ return;
64
+ }
65
+
66
+ isGeneratingRef.current = true;
67
+ setState({ isGenerating: true, result: null, error: null, progress: 0 });
68
+ setStatus("validating");
69
+
70
+ try {
71
+ if (checkCredits) {
72
+ const hasCredits = await checkCredits();
73
+ if (!hasCredits) {
74
+ throw createError("credit_failed", "Insufficient credits");
75
+ }
76
+ }
77
+
78
+ setStatus("generating");
79
+ setState((prev) => ({ ...prev, progress: 20 }));
80
+
81
+ const timeoutPromise = new Promise<never>((_, reject) =>
82
+ setTimeout(() => reject(new Error("Generation timeout")), timeout),
83
+ );
84
+
85
+ const result = await Promise.race([generateFn(input), timeoutPromise]);
86
+
87
+ setState((prev) => ({ ...prev, progress: 60 }));
88
+
89
+ if (saveFn) {
90
+ setStatus("saving");
91
+ try {
92
+ const saveResult = await saveFn(result, input);
93
+ onSaveComplete?.(saveResult);
94
+ } catch (saveError) {
95
+ throw createError(
96
+ "save_failed",
97
+ "Failed to save result",
98
+ saveError as Error,
99
+ );
100
+ }
101
+ }
102
+
103
+ setState((prev) => ({ ...prev, progress: 80 }));
104
+
105
+ if (deductCredits) {
106
+ try {
107
+ await deductCredits();
108
+ } catch (deductError) {
109
+ if (__DEV__)
110
+ console.error("[usePhotoGeneration] Credit deduction failed", deductError);
111
+ }
112
+ }
113
+
114
+ setState({
115
+ isGenerating: false,
116
+ result,
117
+ error: null,
118
+ progress: 100,
119
+ });
120
+ setStatus("success");
121
+ onSuccess?.(result);
122
+ } catch (error: any) {
123
+ const generationError =
124
+ error.type
125
+ ? error
126
+ : error.message === "Generation timeout"
127
+ ? createError("timeout", "Generation timed out", error)
128
+ : error.name === "ContentPolicyViolationError"
129
+ ? createError("policy_violation", "Content policy violation", error)
130
+ : createError("unknown", error.message || "Generation failed", error);
131
+
132
+ setState({
133
+ isGenerating: false,
134
+ result: null,
135
+ error: generationError,
136
+ progress: 0,
137
+ });
138
+ setStatus("error");
139
+ onError?.(generationError);
140
+ } finally {
141
+ isGeneratingRef.current = false;
142
+ }
143
+ },
144
+ [
145
+ generateFn,
146
+ saveFn,
147
+ checkCredits,
148
+ deductCredits,
149
+ timeout,
150
+ onSuccess,
151
+ onError,
152
+ onSaveComplete,
153
+ createError,
154
+ ],
155
+ );
156
+
157
+ const reset = useCallback(() => {
158
+ setState({ isGenerating: false, result: null, error: null, progress: 0 });
159
+ setStatus("idle");
160
+ isGeneratingRef.current = false;
161
+ }, []);
162
+
163
+ return {
164
+ ...state,
165
+ generate,
166
+ reset,
167
+ status,
168
+ };
169
+ };