@umituz/react-native-ai-generation-content 1.44.4 → 1.44.5
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/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +18 -2
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.types.ts +2 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +18 -2
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.types.ts +2 -0
- package/src/presentation/hooks/generation/orchestrator.ts +13 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.44.
|
|
3
|
+
"version": "1.44.5",
|
|
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",
|
package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts
CHANGED
|
@@ -79,8 +79,24 @@ function applyStyleEnhancements(prompt: string, wizardData: Record<string, unkno
|
|
|
79
79
|
// Strategy Factory
|
|
80
80
|
// ============================================================================
|
|
81
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Calculate credit cost based on scenario input type
|
|
84
|
+
* - dual: 2 credits (2 photos)
|
|
85
|
+
* - single: 1 credit (1 photo)
|
|
86
|
+
* - text: 1 credit (text-to-image)
|
|
87
|
+
*/
|
|
88
|
+
function calculateCreditCost(inputType?: string): number {
|
|
89
|
+
if (inputType === "dual") {
|
|
90
|
+
return 2;
|
|
91
|
+
}
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
|
|
82
95
|
export function createImageStrategy(options: CreateImageStrategyOptions): WizardStrategy {
|
|
83
|
-
const { scenario } = options;
|
|
96
|
+
const { scenario, creditCost } = options;
|
|
97
|
+
|
|
98
|
+
// Use explicit creditCost if provided, otherwise calculate from inputType
|
|
99
|
+
const resolvedCreditCost = creditCost ?? calculateCreditCost(scenario.inputType);
|
|
84
100
|
|
|
85
101
|
return {
|
|
86
102
|
execute: async (input: unknown) => {
|
|
@@ -98,6 +114,6 @@ export function createImageStrategy(options: CreateImageStrategyOptions): Wizard
|
|
|
98
114
|
return { imageUrl: result.imageUrl };
|
|
99
115
|
},
|
|
100
116
|
|
|
101
|
-
getCreditCost: () =>
|
|
117
|
+
getCreditCost: () => resolvedCreditCost,
|
|
102
118
|
};
|
|
103
119
|
}
|
|
@@ -23,4 +23,6 @@ export interface WizardImageResult {
|
|
|
23
23
|
export interface CreateImageStrategyOptions {
|
|
24
24
|
readonly scenario: WizardScenarioData;
|
|
25
25
|
readonly collectionName?: string;
|
|
26
|
+
/** Override credit cost (defaults to inputType-based calculation: dual=2, single/text=1) */
|
|
27
|
+
readonly creditCost?: number;
|
|
26
28
|
}
|
package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts
CHANGED
|
@@ -69,10 +69,26 @@ export async function buildVideoInput(
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Calculate credit cost based on scenario input type
|
|
74
|
+
* - dual: 2 credits (2 photos)
|
|
75
|
+
* - single: 1 credit (1 photo)
|
|
76
|
+
* - text: 1 credit (text-to-video)
|
|
77
|
+
*/
|
|
78
|
+
function calculateCreditCost(inputType?: string): number {
|
|
79
|
+
if (inputType === "dual") {
|
|
80
|
+
return 2;
|
|
81
|
+
}
|
|
82
|
+
return 1;
|
|
83
|
+
}
|
|
84
|
+
|
|
72
85
|
export function createVideoStrategy(options: CreateVideoStrategyOptions): WizardStrategy {
|
|
73
|
-
const { scenario } = options;
|
|
86
|
+
const { scenario, creditCost } = options;
|
|
74
87
|
const videoFeatureType = getVideoFeatureType(scenario.id);
|
|
75
88
|
|
|
89
|
+
// Use explicit creditCost if provided, otherwise calculate from inputType
|
|
90
|
+
const resolvedCreditCost = creditCost ?? calculateCreditCost(scenario.inputType);
|
|
91
|
+
|
|
76
92
|
return {
|
|
77
93
|
execute: async (input: unknown) => {
|
|
78
94
|
const videoInput = input as WizardVideoInput;
|
|
@@ -95,6 +111,6 @@ export function createVideoStrategy(options: CreateVideoStrategyOptions): Wizard
|
|
|
95
111
|
return { videoUrl: result.videoUrl };
|
|
96
112
|
},
|
|
97
113
|
|
|
98
|
-
getCreditCost: () =>
|
|
114
|
+
getCreditCost: () => resolvedCreditCost,
|
|
99
115
|
};
|
|
100
116
|
}
|
|
@@ -27,6 +27,8 @@ export interface WizardVideoResult {
|
|
|
27
27
|
export interface CreateVideoStrategyOptions {
|
|
28
28
|
readonly scenario: WizardScenarioData;
|
|
29
29
|
readonly collectionName?: string;
|
|
30
|
+
/** Override credit cost (defaults to inputType-based calculation: dual=2, single/text=1) */
|
|
31
|
+
readonly creditCost?: number;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
export interface PhotoValidationResult {
|
|
@@ -36,7 +36,7 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
36
36
|
|
|
37
37
|
const offlineStore = useOfflineStore();
|
|
38
38
|
const { showError, showSuccess } = useAlert();
|
|
39
|
-
const { deductCredit } = useDeductCredit({ userId, onCreditsExhausted });
|
|
39
|
+
const { deductCredit, checkCredits } = useDeductCredit({ userId, onCreditsExhausted });
|
|
40
40
|
|
|
41
41
|
useEffect(() => {
|
|
42
42
|
isMountedRef.current = true;
|
|
@@ -93,6 +93,17 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
93
93
|
try {
|
|
94
94
|
if (!offlineStore.isOnline) throw createGenerationError("network", alertMessages.networkError);
|
|
95
95
|
|
|
96
|
+
// Pre-validate credits before generation to catch concurrent consumption
|
|
97
|
+
const creditCost = strategy.getCreditCost();
|
|
98
|
+
const hasEnoughCredits = await checkCredits(creditCost);
|
|
99
|
+
if (!hasEnoughCredits) {
|
|
100
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
101
|
+
console.log("[Orchestrator] Pre-validation: insufficient credits");
|
|
102
|
+
}
|
|
103
|
+
onCreditsExhausted?.();
|
|
104
|
+
throw createGenerationError("credits", alertMessages.creditFailed);
|
|
105
|
+
}
|
|
106
|
+
|
|
96
107
|
return await handleModeration({
|
|
97
108
|
input,
|
|
98
109
|
moderation,
|
|
@@ -118,7 +129,7 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
118
129
|
isGeneratingRef.current = false;
|
|
119
130
|
}
|
|
120
131
|
},
|
|
121
|
-
[moderation, alertMessages, offlineStore.isOnline, executeGeneration, showError, onError, handleLifecycleComplete],
|
|
132
|
+
[moderation, alertMessages, offlineStore.isOnline, strategy, checkCredits, onCreditsExhausted, executeGeneration, showError, onError, handleLifecycleComplete],
|
|
122
133
|
);
|
|
123
134
|
|
|
124
135
|
const reset = useCallback(() => {
|