@umituz/react-native-ai-generation-content 1.86.0 → 1.87.1
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/presentation/hooks/generation/generation-execution.utils.ts +52 -0
- package/src/presentation/hooks/generation/repositorySingleton.ts +17 -0
- package/src/presentation/hooks/generation/useAudioGenerationExecutor.ts +9 -17
- package/src/presentation/hooks/generation/useImageGenerationExecutor.ts +11 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.87.1",
|
|
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",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generation Execution Utilities
|
|
3
|
+
* Shared utilities for image and audio generation executors to eliminate code duplication
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { generateUUID } from "@umituz/react-native-design-system/uuid";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resolve type from config - handles both static string and function types
|
|
10
|
+
*/
|
|
11
|
+
export function resolveType<P>(
|
|
12
|
+
typeConfig: string | ((params: P) => string),
|
|
13
|
+
params: P
|
|
14
|
+
): string {
|
|
15
|
+
return typeof typeConfig === "function" ? typeConfig(params) : typeConfig;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Handle credit refund with error logging
|
|
20
|
+
*/
|
|
21
|
+
export async function handleCreditRefund(
|
|
22
|
+
refundCredits: (amount: number) => Promise<void> | Promise<boolean>,
|
|
23
|
+
cost: number,
|
|
24
|
+
typeLabel: string
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
try {
|
|
27
|
+
await refundCredits(cost);
|
|
28
|
+
} catch {
|
|
29
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
30
|
+
console.error(`[${typeLabel}] Refund failed`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Log generation error in development
|
|
37
|
+
*/
|
|
38
|
+
export function logGenerationError(
|
|
39
|
+
typeLabel: string,
|
|
40
|
+
error: unknown
|
|
41
|
+
): void {
|
|
42
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
43
|
+
console.error(`[${typeLabel}]`, error);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Generate unique creation ID using Design System UUID
|
|
49
|
+
*/
|
|
50
|
+
export function generateCreationId(): string {
|
|
51
|
+
return generateUUID();
|
|
52
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository Singleton
|
|
3
|
+
* Prevents multiple repository instances across hooks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createCreationsRepository } from "../../../domains/creations/infrastructure/adapters";
|
|
7
|
+
|
|
8
|
+
const REPO_COLLECTION = "creations";
|
|
9
|
+
|
|
10
|
+
let repositoryInstance: ReturnType<typeof createCreationsRepository> | null = null;
|
|
11
|
+
|
|
12
|
+
export function getCreationsRepository() {
|
|
13
|
+
if (!repositoryInstance) {
|
|
14
|
+
repositoryInstance = createCreationsRepository(REPO_COLLECTION);
|
|
15
|
+
}
|
|
16
|
+
return repositoryInstance;
|
|
17
|
+
}
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
* - buildMetadata: creation metadata
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { useState, useCallback
|
|
12
|
+
import { useState, useCallback } from "react";
|
|
13
13
|
import { useGenerationServices } from "../../../infrastructure/providers/generation-services.provider";
|
|
14
14
|
import { resolveProvider } from "../../../infrastructure/services/provider-resolver";
|
|
15
|
-
import {
|
|
15
|
+
import { getCreationsRepository } from "./repositorySingleton";
|
|
16
16
|
import type { GenerationTarget } from "./useImageGenerationExecutor";
|
|
17
|
+
import { handleCreditRefund, logGenerationError, generateCreationId } from "./generation-execution.utils";
|
|
17
18
|
|
|
18
19
|
/** Domain-specific audio generation input returned by buildInput */
|
|
19
20
|
export interface AudioGenerationInput {
|
|
@@ -59,10 +60,7 @@ export function useAudioGenerationExecutor<P>(
|
|
|
59
60
|
): AudioGenerationExecutorReturn<P> {
|
|
60
61
|
const { userId, deductCredits, refundCredits, onGenerationSuccess } =
|
|
61
62
|
useGenerationServices();
|
|
62
|
-
const repository =
|
|
63
|
-
() => createCreationsRepository("creations"),
|
|
64
|
-
[],
|
|
65
|
-
);
|
|
63
|
+
const repository = getCreationsRepository();
|
|
66
64
|
const [error, setError] = useState<string | null>(null);
|
|
67
65
|
const [isLoading, setIsLoading] = useState(false);
|
|
68
66
|
|
|
@@ -95,7 +93,7 @@ export function useAudioGenerationExecutor<P>(
|
|
|
95
93
|
if (!audioUrl) throw new Error("No audio returned");
|
|
96
94
|
|
|
97
95
|
await repository.create(userId, {
|
|
98
|
-
id:
|
|
96
|
+
id: generateCreationId(),
|
|
99
97
|
type: config.type,
|
|
100
98
|
uri: audioUrl,
|
|
101
99
|
createdAt: new Date(),
|
|
@@ -117,18 +115,12 @@ export function useAudioGenerationExecutor<P>(
|
|
|
117
115
|
const message =
|
|
118
116
|
err instanceof Error ? err.message : "Generation failed";
|
|
119
117
|
setError(message);
|
|
118
|
+
|
|
120
119
|
if (deducted) {
|
|
121
|
-
|
|
122
|
-
await refundCredits(cost);
|
|
123
|
-
} catch {
|
|
124
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
125
|
-
console.error(`[${config.type}] Refund failed`);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
130
|
-
console.error(`[${config.type}]`, err);
|
|
120
|
+
await handleCreditRefund(refundCredits, cost, config.type);
|
|
131
121
|
}
|
|
122
|
+
|
|
123
|
+
logGenerationError(config.type, err);
|
|
132
124
|
return null;
|
|
133
125
|
} finally {
|
|
134
126
|
setIsLoading(false);
|
|
@@ -11,11 +11,12 @@
|
|
|
11
11
|
* Auth and credit services come from GenerationServicesProvider context.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { useState, useCallback
|
|
14
|
+
import { useState, useCallback } from "react";
|
|
15
15
|
import { useGenerationServices } from "../../../infrastructure/providers/generation-services.provider";
|
|
16
16
|
import { resolveProvider } from "../../../infrastructure/services/provider-resolver";
|
|
17
|
-
import {
|
|
17
|
+
import { getCreationsRepository } from "./repositorySingleton";
|
|
18
18
|
import { preprocessImageInputs } from "../../../infrastructure/utils/image-input-preprocessor.util";
|
|
19
|
+
import { resolveType, handleCreditRefund, logGenerationError, generateCreationId } from "./generation-execution.utils";
|
|
19
20
|
|
|
20
21
|
/** Target for generation: which model on which provider */
|
|
21
22
|
export interface GenerationTarget {
|
|
@@ -65,10 +66,7 @@ export function useImageGenerationExecutor<P>(
|
|
|
65
66
|
): ImageGenerationExecutorReturn<P> {
|
|
66
67
|
const { userId, deductCredits, refundCredits, onGenerationSuccess } =
|
|
67
68
|
useGenerationServices();
|
|
68
|
-
const repository =
|
|
69
|
-
() => createCreationsRepository("creations"),
|
|
70
|
-
[],
|
|
71
|
-
);
|
|
69
|
+
const repository = getCreationsRepository();
|
|
72
70
|
const [error, setError] = useState<string | null>(null);
|
|
73
71
|
const [isLoading, setIsLoading] = useState(false);
|
|
74
72
|
|
|
@@ -101,8 +99,8 @@ export function useImageGenerationExecutor<P>(
|
|
|
101
99
|
if (!imageUrl) throw new Error("No image returned");
|
|
102
100
|
|
|
103
101
|
await repository.create(userId, {
|
|
104
|
-
id:
|
|
105
|
-
type:
|
|
102
|
+
id: generateCreationId(),
|
|
103
|
+
type: resolveType(config.type, params),
|
|
106
104
|
uri: imageUrl,
|
|
107
105
|
createdAt: new Date(),
|
|
108
106
|
isShared: false,
|
|
@@ -123,19 +121,13 @@ export function useImageGenerationExecutor<P>(
|
|
|
123
121
|
const message =
|
|
124
122
|
err instanceof Error ? err.message : "Generation failed";
|
|
125
123
|
setError(message);
|
|
126
|
-
const typeLabel =
|
|
124
|
+
const typeLabel = resolveType(config.type, params);
|
|
125
|
+
|
|
127
126
|
if (deducted) {
|
|
128
|
-
|
|
129
|
-
await refundCredits(cost);
|
|
130
|
-
} catch {
|
|
131
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
132
|
-
console.error(`[${typeLabel}] Refund failed`);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
137
|
-
console.error(`[${typeLabel}]`, err);
|
|
127
|
+
await handleCreditRefund(refundCredits, cost, typeLabel);
|
|
138
128
|
}
|
|
129
|
+
|
|
130
|
+
logGenerationError(typeLabel, err);
|
|
139
131
|
return null;
|
|
140
132
|
} finally {
|
|
141
133
|
setIsLoading(false);
|