@umituz/react-native-ai-generation-content 1.26.28 → 1.26.30
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 +1 -1
- package/src/infrastructure/constants/index.ts +9 -0
- package/src/infrastructure/services/image-feature-executor.service.ts +2 -30
- package/src/infrastructure/services/provider-validator.ts +17 -38
- package/src/infrastructure/services/video-feature-executor.service.ts +8 -45
- package/src/infrastructure/services/video-feature-executor.types.ts +1 -0
- package/src/infrastructure/utils/error-message-extractor.util.ts +41 -0
- package/src/infrastructure/utils/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.30",
|
|
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",
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { providerRegistry } from "./provider-registry.service";
|
|
8
|
-
import { cleanBase64 } from "../utils";
|
|
8
|
+
import { cleanBase64, extractErrorMessage } from "../utils";
|
|
9
9
|
import { extractImageResult } from "../utils/url-extractor";
|
|
10
10
|
import type { ImageResultExtractor } from "../utils/url-extractor";
|
|
11
11
|
import type { ImageFeatureType, ImageFeatureInputData } from "../../domain/interfaces";
|
|
@@ -68,8 +68,6 @@ export async function executeImageFeature(
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
try {
|
|
71
|
-
onProgress?.(10);
|
|
72
|
-
|
|
73
71
|
const inputData: ImageFeatureInputData = {
|
|
74
72
|
imageBase64: request.imageBase64 ? cleanBase64(request.imageBase64) : "",
|
|
75
73
|
targetImageBase64: request.targetImageBase64
|
|
@@ -79,16 +77,9 @@ export async function executeImageFeature(
|
|
|
79
77
|
options: request.options,
|
|
80
78
|
};
|
|
81
79
|
|
|
82
|
-
onProgress?.(30);
|
|
83
|
-
|
|
84
80
|
const input = provider.buildImageFeatureInput(featureType, inputData);
|
|
85
|
-
|
|
86
|
-
onProgress?.(40);
|
|
87
|
-
|
|
88
81
|
const result = await provider.run(model, input);
|
|
89
82
|
|
|
90
|
-
onProgress?.(90);
|
|
91
|
-
|
|
92
83
|
const extractor = extractResult ?? extractImageResult;
|
|
93
84
|
const imageUrl = extractor(result);
|
|
94
85
|
|
|
@@ -104,26 +95,7 @@ export async function executeImageFeature(
|
|
|
104
95
|
requestId: (result as { requestId?: string })?.requestId,
|
|
105
96
|
};
|
|
106
97
|
} catch (error) {
|
|
107
|
-
|
|
108
|
-
let message = "Processing failed";
|
|
109
|
-
if (error instanceof Error) {
|
|
110
|
-
message = error.message;
|
|
111
|
-
} else if (typeof error === "object" && error !== null) {
|
|
112
|
-
const errObj = error as Record<string, unknown>;
|
|
113
|
-
// FAL API error format: {detail: [{msg, type, loc}]} or {message}
|
|
114
|
-
if (Array.isArray(errObj.detail) && errObj.detail[0]?.msg) {
|
|
115
|
-
message = String(errObj.detail[0].msg);
|
|
116
|
-
} else if (errObj.detail) {
|
|
117
|
-
message = JSON.stringify(errObj.detail);
|
|
118
|
-
} else if (errObj.message) {
|
|
119
|
-
message = String(errObj.message);
|
|
120
|
-
} else if (errObj.msg) {
|
|
121
|
-
message = String(errObj.msg);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (__DEV__) {
|
|
125
|
-
console.error(`[Image:${featureType}] Error:`, message, error);
|
|
126
|
-
}
|
|
98
|
+
const message = extractErrorMessage(error, "Processing failed", `Image:${featureType}`);
|
|
127
99
|
return { success: false, error: message };
|
|
128
100
|
}
|
|
129
101
|
}
|
|
@@ -9,44 +9,23 @@ import { providerRegistry } from "./provider-registry.service";
|
|
|
9
9
|
declare const __DEV__: boolean;
|
|
10
10
|
|
|
11
11
|
export class ProviderValidator {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
22
|
-
|
|
23
|
-
console.error("[ProviderValidator] No active provider found!");
|
|
24
|
-
}
|
|
25
|
-
throw new Error(
|
|
26
|
-
"No active AI provider. Register and set a provider first.",
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (!provider.isInitialized()) {
|
|
31
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
32
|
-
|
|
33
|
-
console.error("[ProviderValidator] Provider not initialized:", provider.providerId);
|
|
34
|
-
}
|
|
35
|
-
throw new Error(
|
|
36
|
-
`Provider ${provider.providerId} is not initialized.`,
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
41
|
-
|
|
42
|
-
console.log("[ProviderValidator] getProvider() returning:", {
|
|
43
|
-
providerId: provider.providerId,
|
|
44
|
-
isInitialized: provider.isInitialized(),
|
|
45
|
-
});
|
|
46
|
-
}
|
|
12
|
+
getProvider(): IAIProvider {
|
|
13
|
+
const provider = providerRegistry.getActiveProvider();
|
|
14
|
+
|
|
15
|
+
if (!provider) {
|
|
16
|
+
if (__DEV__) {
|
|
17
|
+
console.error("[ProviderValidator] No active provider found");
|
|
18
|
+
}
|
|
19
|
+
throw new Error("No active AI provider. Register and set a provider first.");
|
|
20
|
+
}
|
|
47
21
|
|
|
48
|
-
|
|
22
|
+
if (!provider.isInitialized()) {
|
|
23
|
+
if (__DEV__) {
|
|
24
|
+
console.error("[ProviderValidator] Provider not initialized:", provider.providerId);
|
|
25
|
+
}
|
|
26
|
+
throw new Error(`Provider ${provider.providerId} is not initialized.`);
|
|
49
27
|
}
|
|
50
|
-
}
|
|
51
28
|
|
|
52
|
-
|
|
29
|
+
return provider;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { providerRegistry } from "./provider-registry.service";
|
|
8
|
-
import { cleanBase64 } from "../utils";
|
|
8
|
+
import { cleanBase64, extractErrorMessage } from "../utils";
|
|
9
9
|
import { extractVideoResult } from "../utils/url-extractor";
|
|
10
|
+
import { VIDEO_TIMEOUT_MS } from "../constants";
|
|
10
11
|
import type { VideoFeatureType, VideoFeatureInputData } from "../../domain/interfaces";
|
|
11
12
|
import type {
|
|
12
13
|
ExecuteVideoFeatureOptions,
|
|
@@ -35,7 +36,7 @@ export async function executeVideoFeature(
|
|
|
35
36
|
return { success: false, error: "AI provider not initialized" };
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
const { extractResult, onProgress } = options ?? {};
|
|
39
|
+
const { extractResult, onProgress, onStatusChange } = options ?? {};
|
|
39
40
|
|
|
40
41
|
const model = provider.getVideoFeatureModel(featureType);
|
|
41
42
|
|
|
@@ -44,8 +45,6 @@ export async function executeVideoFeature(
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
try {
|
|
47
|
-
onProgress?.(5);
|
|
48
|
-
|
|
49
48
|
const inputData: VideoFeatureInputData = {
|
|
50
49
|
sourceImageBase64: cleanBase64(request.sourceImageBase64),
|
|
51
50
|
targetImageBase64: cleanBase64(request.targetImageBase64),
|
|
@@ -53,30 +52,18 @@ export async function executeVideoFeature(
|
|
|
53
52
|
options: request.options,
|
|
54
53
|
};
|
|
55
54
|
|
|
56
|
-
onProgress?.(10);
|
|
57
|
-
|
|
58
55
|
const input = provider.buildVideoFeatureInput(featureType, inputData);
|
|
59
56
|
|
|
60
|
-
onProgress?.(15);
|
|
61
|
-
|
|
62
|
-
// Use subscribe for video features - provides queue updates and handles long-running tasks
|
|
63
57
|
const result = await provider.subscribe(model, input, {
|
|
64
|
-
timeoutMs:
|
|
58
|
+
timeoutMs: VIDEO_TIMEOUT_MS,
|
|
65
59
|
onQueueUpdate: (status) => {
|
|
66
60
|
if (__DEV__) {
|
|
67
|
-
console.log(`[Video:${featureType}] Queue
|
|
68
|
-
}
|
|
69
|
-
// Map queue status to progress percentage
|
|
70
|
-
if (status.status === "IN_QUEUE") {
|
|
71
|
-
onProgress?.(20);
|
|
72
|
-
} else if (status.status === "IN_PROGRESS") {
|
|
73
|
-
onProgress?.(50);
|
|
61
|
+
console.log(`[Video:${featureType}] Queue status:`, status.status);
|
|
74
62
|
}
|
|
63
|
+
onStatusChange?.(status.status);
|
|
75
64
|
},
|
|
76
65
|
});
|
|
77
66
|
|
|
78
|
-
onProgress?.(90);
|
|
79
|
-
|
|
80
67
|
const extractor = extractResult ?? extractVideoResult;
|
|
81
68
|
const videoUrl = extractor(result);
|
|
82
69
|
|
|
@@ -84,7 +71,7 @@ export async function executeVideoFeature(
|
|
|
84
71
|
|
|
85
72
|
if (!videoUrl) {
|
|
86
73
|
if (__DEV__) {
|
|
87
|
-
console.log(`[Video:${featureType}] No video URL found in result
|
|
74
|
+
console.log(`[Video:${featureType}] No video URL found in result`);
|
|
88
75
|
}
|
|
89
76
|
return { success: false, error: "No video in response" };
|
|
90
77
|
}
|
|
@@ -95,35 +82,11 @@ export async function executeVideoFeature(
|
|
|
95
82
|
requestId: (result as { requestId?: string })?.requestId,
|
|
96
83
|
};
|
|
97
84
|
} catch (error) {
|
|
98
|
-
const message = extractErrorMessage(error, featureType);
|
|
85
|
+
const message = extractErrorMessage(error, "Processing failed", `Video:${featureType}`);
|
|
99
86
|
return { success: false, error: message };
|
|
100
87
|
}
|
|
101
88
|
}
|
|
102
89
|
|
|
103
|
-
/**
|
|
104
|
-
* Extract error message from various error formats
|
|
105
|
-
*/
|
|
106
|
-
function extractErrorMessage(error: unknown, featureType: VideoFeatureType): string {
|
|
107
|
-
let message = "Processing failed";
|
|
108
|
-
|
|
109
|
-
if (error instanceof Error) {
|
|
110
|
-
message = error.message;
|
|
111
|
-
} else if (typeof error === "object" && error !== null) {
|
|
112
|
-
const errObj = error as Record<string, unknown>;
|
|
113
|
-
if (errObj.detail) {
|
|
114
|
-
message = JSON.stringify(errObj.detail);
|
|
115
|
-
} else if (errObj.message) {
|
|
116
|
-
message = String(errObj.message);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (__DEV__) {
|
|
121
|
-
console.error(`[Video:${featureType}] Error:`, message, error);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return message;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
90
|
/**
|
|
128
91
|
* Check if video features are supported
|
|
129
92
|
*/
|
|
@@ -10,6 +10,7 @@ import type { VideoResultExtractor } from "../utils/url-extractor";
|
|
|
10
10
|
export interface ExecuteVideoFeatureOptions {
|
|
11
11
|
extractResult?: VideoResultExtractor;
|
|
12
12
|
onProgress?: (progress: number) => void;
|
|
13
|
+
onStatusChange?: (status: string) => void;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Message Extractor
|
|
3
|
+
* Extracts error messages from various API error formats
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
declare const __DEV__: boolean;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Extract error message from FAL API and other error formats
|
|
10
|
+
* Supports: Error instances, FAL API errors, generic objects
|
|
11
|
+
*/
|
|
12
|
+
export function extractErrorMessage(
|
|
13
|
+
error: unknown,
|
|
14
|
+
defaultMessage = "Processing failed",
|
|
15
|
+
debugPrefix?: string,
|
|
16
|
+
): string {
|
|
17
|
+
let message = defaultMessage;
|
|
18
|
+
|
|
19
|
+
if (error instanceof Error) {
|
|
20
|
+
message = error.message;
|
|
21
|
+
} else if (typeof error === "object" && error !== null) {
|
|
22
|
+
const errObj = error as Record<string, unknown>;
|
|
23
|
+
|
|
24
|
+
// FAL API error format: {detail: [{msg, type, loc}]}
|
|
25
|
+
if (Array.isArray(errObj.detail) && errObj.detail[0]?.msg) {
|
|
26
|
+
message = String(errObj.detail[0].msg);
|
|
27
|
+
} else if (errObj.detail) {
|
|
28
|
+
message = JSON.stringify(errObj.detail);
|
|
29
|
+
} else if (errObj.message) {
|
|
30
|
+
message = String(errObj.message);
|
|
31
|
+
} else if (errObj.msg) {
|
|
32
|
+
message = String(errObj.msg);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (__DEV__ && debugPrefix) {
|
|
37
|
+
console.error(`[${debugPrefix}] Error:`, message, error);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return message;
|
|
41
|
+
}
|