@umituz/react-native-ai-generation-content 1.17.162 → 1.17.164

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.17.162",
3
+ "version": "1.17.164",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -38,6 +38,7 @@
38
38
  "url": "git+https://github.com/umituz/react-native-ai-generation-content.git"
39
39
  },
40
40
  "dependencies": {
41
+ "@umituz/react-native-auth": "latest",
41
42
  "@umituz/react-native-design-system": "latest",
42
43
  "@umituz/react-native-filesystem": "latest",
43
44
  "@umituz/react-native-firebase": "latest",
@@ -120,8 +120,8 @@ export { useCreationPersistence } from "./presentation/hooks/useCreationPersiste
120
120
  export type {
121
121
  UseCreationPersistenceConfig,
122
122
  UseCreationPersistenceReturn,
123
- ProcessingStartData,
124
- ProcessingResult,
123
+ BaseProcessingStartData,
124
+ BaseProcessingResult,
125
125
  } from "./presentation/hooks/useCreationPersistence";
126
126
 
127
127
  // =============================================================================
@@ -18,6 +18,6 @@ export { useCreationPersistence } from "./useCreationPersistence";
18
18
  export type {
19
19
  UseCreationPersistenceConfig,
20
20
  UseCreationPersistenceReturn,
21
- ProcessingStartData,
22
- ProcessingResult,
21
+ BaseProcessingStartData,
22
+ BaseProcessingResult,
23
23
  } from "./useCreationPersistence";
@@ -21,29 +21,27 @@ export interface UseCreationPersistenceConfig {
21
21
  }
22
22
 
23
23
  /**
24
- * Generic processing start data - all features must have creationId
24
+ * Base processing start data - all features must have creationId
25
25
  */
26
- export interface ProcessingStartData {
26
+ export interface BaseProcessingStartData {
27
27
  readonly creationId: string;
28
- readonly [key: string]: unknown;
29
28
  }
30
29
 
31
30
  /**
32
- * Generic processing result - all features should have creationId
31
+ * Base processing result - all features should have creationId
33
32
  */
34
- export interface ProcessingResult {
33
+ export interface BaseProcessingResult {
35
34
  readonly creationId?: string;
36
35
  readonly imageUrl?: string;
37
36
  readonly videoUrl?: string;
38
- readonly [key: string]: unknown;
39
37
  }
40
38
 
41
39
  /**
42
- * Return type for useCreationPersistence
40
+ * Return type for useCreationPersistence - uses generic callbacks
43
41
  */
44
42
  export interface UseCreationPersistenceReturn {
45
- readonly onProcessingStart: (data: ProcessingStartData) => void;
46
- readonly onProcessingComplete: (result: ProcessingResult) => void;
43
+ readonly onProcessingStart: <T extends BaseProcessingStartData>(data: T) => void;
44
+ readonly onProcessingComplete: <T extends BaseProcessingResult>(result: T) => void;
47
45
  readonly onError: (error: string, creationId?: string) => void;
48
46
  }
49
47
 
@@ -71,10 +69,14 @@ export function useCreationPersistence(
71
69
  );
72
70
 
73
71
  const onProcessingStart = useCallback(
74
- (data: ProcessingStartData) => {
72
+ <T extends BaseProcessingStartData>(data: T) => {
75
73
  if (!userId) return;
76
74
 
77
75
  const { creationId, ...rest } = data;
76
+ const cleanMetadata = Object.fromEntries(
77
+ Object.entries(rest).filter(([, v]) => v !== undefined && v !== null),
78
+ );
79
+
78
80
  const creation: Creation = {
79
81
  id: creationId,
80
82
  uri: "",
@@ -83,7 +85,7 @@ export function useCreationPersistence(
83
85
  createdAt: new Date(),
84
86
  isShared: false,
85
87
  isFavorite: false,
86
- metadata: rest,
88
+ metadata: cleanMetadata,
87
89
  };
88
90
 
89
91
  repository.create(userId, creation);
@@ -93,7 +95,7 @@ export function useCreationPersistence(
93
95
  );
94
96
 
95
97
  const onProcessingComplete = useCallback(
96
- (result: ProcessingResult) => {
98
+ <T extends BaseProcessingResult>(result: T) => {
97
99
  if (!userId || !result.creationId) return;
98
100
 
99
101
  const uri = result.imageUrl || result.videoUrl || "";
@@ -102,24 +102,56 @@ export interface BaseDualImageTranslations {
102
102
  */
103
103
  export type ImageResultExtractor = (result: unknown) => string | undefined;
104
104
 
105
+ /**
106
+ * Base processing start data for persistence
107
+ */
108
+ export interface BaseProcessingStartData {
109
+ creationId: string;
110
+ }
111
+
112
+ /**
113
+ * Single image processing start data
114
+ */
115
+ export interface SingleImageProcessingStartData extends BaseProcessingStartData {
116
+ imageUri: string;
117
+ }
118
+
119
+ /**
120
+ * Dual image processing start data
121
+ */
122
+ export interface DualImageProcessingStartData extends BaseProcessingStartData {
123
+ sourceImageUri: string;
124
+ targetImageUri: string;
125
+ }
126
+
127
+ /**
128
+ * Base result with optional creationId for persistence
129
+ */
130
+ export interface BaseImageResultWithCreationId extends BaseImageResult {
131
+ creationId?: string;
132
+ }
133
+
105
134
  /**
106
135
  * Base config for all image features
107
136
  */
108
- export interface BaseImageConfig<TResult extends BaseImageResult = BaseImageResult> {
137
+ export interface BaseImageConfig<
138
+ TResult extends BaseImageResult = BaseImageResult,
139
+ TStartData extends BaseProcessingStartData = BaseProcessingStartData,
140
+ > {
109
141
  featureType: ImageFeatureType;
110
142
  creditCost?: number;
111
143
  extractResult?: ImageResultExtractor;
112
144
  prepareImage: (imageUri: string) => Promise<string>;
113
- onProcessingStart?: () => void;
145
+ onProcessingStart?: (data: TStartData) => void;
114
146
  onProcessingComplete?: (result: TResult) => void;
115
- onError?: (error: string) => void;
147
+ onError?: (error: string, creationId?: string) => void;
116
148
  }
117
149
 
118
150
  /**
119
151
  * Config for single image features
120
152
  */
121
153
  export interface SingleImageConfig<TResult extends BaseImageResult = BaseImageResult>
122
- extends BaseImageConfig<TResult> {
154
+ extends BaseImageConfig<TResult, SingleImageProcessingStartData> {
123
155
  onImageSelect?: (uri: string) => void;
124
156
  }
125
157
 
@@ -127,7 +159,7 @@ export interface SingleImageConfig<TResult extends BaseImageResult = BaseImageRe
127
159
  * Config for dual image features
128
160
  */
129
161
  export interface DualImageConfig<TResult extends BaseImageResult = BaseImageResult>
130
- extends BaseImageConfig<TResult> {
162
+ extends BaseImageConfig<TResult, DualImageProcessingStartData> {
131
163
  onSourceImageSelect?: (uri: string) => void;
132
164
  onTargetImageSelect?: (uri: string) => void;
133
165
  }
@@ -3,7 +3,8 @@
3
3
  * Base hook for dual image processing features (e.g., face-swap)
4
4
  */
5
5
 
6
- import { useState, useCallback } from "react";
6
+ import { useState, useCallback, useRef } from "react";
7
+ import { generateCreationId } from "@umituz/react-native-uuid";
7
8
  import { executeImageFeature } from "../../../../infrastructure/services";
8
9
  import type {
9
10
  BaseDualImageState,
@@ -39,6 +40,7 @@ export function useDualImageFeature<
39
40
  ): BaseDualImageHookReturn {
40
41
  const { config, onSelectSourceImage, onSelectTargetImage, onSaveImage, onBeforeProcess } = props;
41
42
  const [state, setState] = useState<BaseDualImageState>(INITIAL_STATE);
43
+ const creationIdRef = useRef<string | null>(null);
42
44
 
43
45
  const selectSourceImage = useCallback(async () => {
44
46
  try {
@@ -73,12 +75,14 @@ export function useDualImageFeature<
73
75
  const process = useCallback(async () => {
74
76
  if (!state.sourceImageUri || !state.targetImageUri) return;
75
77
 
76
- // Check if processing is allowed (credit check, etc.)
77
78
  if (onBeforeProcess) {
78
79
  const canProceed = await onBeforeProcess();
79
80
  if (!canProceed) return;
80
81
  }
81
82
 
83
+ const creationId = generateCreationId();
84
+ creationIdRef.current = creationId;
85
+
82
86
  setState((prev) => ({
83
87
  ...prev,
84
88
  isProcessing: true,
@@ -86,7 +90,11 @@ export function useDualImageFeature<
86
90
  error: null,
87
91
  }));
88
92
 
89
- config.onProcessingStart?.();
93
+ config.onProcessingStart?.({
94
+ creationId,
95
+ sourceImageUri: state.sourceImageUri,
96
+ targetImageUri: state.targetImageUri,
97
+ });
90
98
 
91
99
  try {
92
100
  const [sourceBase64, targetBase64] = await Promise.all([
@@ -111,7 +119,7 @@ export function useDualImageFeature<
111
119
  processedUrl: result.imageUrl!,
112
120
  progress: 100,
113
121
  }));
114
- config.onProcessingComplete?.(result as TResult);
122
+ config.onProcessingComplete?.({ ...result, creationId } as TResult);
115
123
  } else {
116
124
  const errorMessage = result.error || "Processing failed";
117
125
  setState((prev) => ({
@@ -120,7 +128,7 @@ export function useDualImageFeature<
120
128
  error: errorMessage,
121
129
  progress: 0,
122
130
  }));
123
- config.onError?.(errorMessage);
131
+ config.onError?.(errorMessage, creationId);
124
132
  }
125
133
  } catch (error) {
126
134
  const message = error instanceof Error ? error.message : String(error);
@@ -130,7 +138,7 @@ export function useDualImageFeature<
130
138
  error: message,
131
139
  progress: 0,
132
140
  }));
133
- config.onError?.(message);
141
+ config.onError?.(message, creationIdRef.current ?? undefined);
134
142
  }
135
143
  }, [state.sourceImageUri, state.targetImageUri, config, options, handleProgress, onBeforeProcess]);
136
144
 
@@ -3,7 +3,8 @@
3
3
  * Base hook for image + prompt processing features (e.g., replace-background)
4
4
  */
5
5
 
6
- import { useState, useCallback } from "react";
6
+ import { useState, useCallback, useRef } from "react";
7
+ import { generateCreationId } from "@umituz/react-native-uuid";
7
8
  import { executeImageFeature } from "../../../../infrastructure/services";
8
9
  import type {
9
10
  BaseImageWithPromptState,
@@ -65,6 +66,7 @@ export function useImageWithPromptFeature<
65
66
  ...INITIAL_STATE,
66
67
  prompt: config.defaultPrompt || "",
67
68
  });
69
+ const creationIdRef = useRef<string | null>(null);
68
70
 
69
71
  const selectImage = useCallback(async () => {
70
72
  try {
@@ -94,7 +96,6 @@ export function useImageWithPromptFeature<
94
96
  const process = useCallback(async () => {
95
97
  if (!state.imageUri) return;
96
98
 
97
- // Check if processing is allowed (credit check, etc.)
98
99
  if (onBeforeProcess) {
99
100
  const canProceed = await onBeforeProcess();
100
101
  if (!canProceed) return;
@@ -103,10 +104,13 @@ export function useImageWithPromptFeature<
103
104
  if (options?.promptRequired && !state.prompt.trim()) {
104
105
  const error = "Prompt is required";
105
106
  setState((prev) => ({ ...prev, error }));
106
- config.onError?.(error);
107
+ config.onError?.(error, creationIdRef.current ?? undefined);
107
108
  return;
108
109
  }
109
110
 
111
+ const creationId = generateCreationId();
112
+ creationIdRef.current = creationId;
113
+
110
114
  setState((prev) => ({
111
115
  ...prev,
112
116
  isProcessing: true,
@@ -114,7 +118,7 @@ export function useImageWithPromptFeature<
114
118
  error: null,
115
119
  }));
116
120
 
117
- config.onProcessingStart?.();
121
+ config.onProcessingStart?.({ creationId, imageUri: state.imageUri });
118
122
 
119
123
  try {
120
124
  const imageBase64 = await config.prepareImage(state.imageUri);
@@ -136,7 +140,7 @@ export function useImageWithPromptFeature<
136
140
  processedUrl: result.imageUrl!,
137
141
  progress: 100,
138
142
  }));
139
- config.onProcessingComplete?.(result as TResult);
143
+ config.onProcessingComplete?.({ ...result, creationId } as TResult);
140
144
  } else {
141
145
  const errorMessage = result.error || "Processing failed";
142
146
  setState((prev) => ({
@@ -145,7 +149,7 @@ export function useImageWithPromptFeature<
145
149
  error: errorMessage,
146
150
  progress: 0,
147
151
  }));
148
- config.onError?.(errorMessage);
152
+ config.onError?.(errorMessage, creationId);
149
153
  }
150
154
  } catch (error) {
151
155
  const message = error instanceof Error ? error.message : String(error);
@@ -155,7 +159,7 @@ export function useImageWithPromptFeature<
155
159
  error: message,
156
160
  progress: 0,
157
161
  }));
158
- config.onError?.(message);
162
+ config.onError?.(message, creationIdRef.current ?? undefined);
159
163
  }
160
164
  }, [state.imageUri, state.prompt, config, options, handleProgress, onBeforeProcess]);
161
165
 
@@ -3,7 +3,8 @@
3
3
  * Base hook for single image processing features
4
4
  */
5
5
 
6
- import { useState, useCallback } from "react";
6
+ import { useState, useCallback, useRef } from "react";
7
+ import { generateCreationId } from "@umituz/react-native-uuid";
7
8
  import { executeImageFeature } from "../../../../infrastructure/services";
8
9
  import type {
9
10
  BaseSingleImageState,
@@ -34,6 +35,7 @@ export function useSingleImageFeature<
34
35
  ): BaseSingleImageHookReturn {
35
36
  const { config, onSelectImage, onSaveImage, onBeforeProcess } = props;
36
37
  const [state, setState] = useState<BaseSingleImageState>(INITIAL_STATE);
38
+ const creationIdRef = useRef<string | null>(null);
37
39
 
38
40
  const selectImage = useCallback(async () => {
39
41
  try {
@@ -55,12 +57,14 @@ export function useSingleImageFeature<
55
57
  const process = useCallback(async () => {
56
58
  if (!state.imageUri) return;
57
59
 
58
- // Check if processing is allowed (credit check, etc.)
59
60
  if (onBeforeProcess) {
60
61
  const canProceed = await onBeforeProcess();
61
62
  if (!canProceed) return;
62
63
  }
63
64
 
65
+ const creationId = generateCreationId();
66
+ creationIdRef.current = creationId;
67
+
64
68
  setState((prev) => ({
65
69
  ...prev,
66
70
  isProcessing: true,
@@ -68,7 +72,7 @@ export function useSingleImageFeature<
68
72
  error: null,
69
73
  }));
70
74
 
71
- config.onProcessingStart?.();
75
+ config.onProcessingStart?.({ creationId, imageUri: state.imageUri });
72
76
 
73
77
  try {
74
78
  const imageBase64 = await config.prepareImage(state.imageUri);
@@ -90,7 +94,7 @@ export function useSingleImageFeature<
90
94
  processedUrl: result.imageUrl!,
91
95
  progress: 100,
92
96
  }));
93
- config.onProcessingComplete?.(result as TResult);
97
+ config.onProcessingComplete?.({ ...result, creationId } as TResult);
94
98
  } else {
95
99
  const errorMessage = result.error || "Processing failed";
96
100
  setState((prev) => ({
@@ -99,7 +103,7 @@ export function useSingleImageFeature<
99
103
  error: errorMessage,
100
104
  progress: 0,
101
105
  }));
102
- config.onError?.(errorMessage);
106
+ config.onError?.(errorMessage, creationId);
103
107
  }
104
108
  } catch (error) {
105
109
  const message = error instanceof Error ? error.message : String(error);
@@ -109,7 +113,7 @@ export function useSingleImageFeature<
109
113
  error: message,
110
114
  progress: 0,
111
115
  }));
112
- config.onError?.(message);
116
+ config.onError?.(message, creationIdRef.current ?? undefined);
113
117
  }
114
118
  }, [state.imageUri, config, options, handleProgress, onBeforeProcess]);
115
119