@umituz/react-native-ai-generation-content 1.37.13 → 1.37.14
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 +55 -17
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +50 -9
- package/src/domains/generation/wizard/infrastructure/strategies/wizard-strategy.types.ts +4 -1
- package/src/domains/generation/wizard/presentation/hooks/useWizardGeneration.ts +28 -46
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.37.
|
|
3
|
+
"version": "1.37.14",
|
|
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
|
@@ -80,11 +80,14 @@ function applyStyleEnhancements(prompt: string, wizardData: Record<string, unkno
|
|
|
80
80
|
// Strategy Factory
|
|
81
81
|
// ============================================================================
|
|
82
82
|
|
|
83
|
+
declare const __DEV__: boolean;
|
|
84
|
+
|
|
83
85
|
export function createImageStrategy(options: CreateImageStrategyOptions): WizardStrategy {
|
|
84
86
|
const { scenario, collectionName = "creations" } = options;
|
|
85
87
|
const repository = createCreationsRepository(collectionName);
|
|
86
88
|
|
|
87
89
|
let lastInputRef: WizardImageInput | null = null;
|
|
90
|
+
let processingCreationId: string | null = null;
|
|
88
91
|
|
|
89
92
|
return {
|
|
90
93
|
execute: async (input: unknown) => {
|
|
@@ -106,28 +109,63 @@ export function createImageStrategy(options: CreateImageStrategyOptions): Wizard
|
|
|
106
109
|
|
|
107
110
|
getCreditCost: () => 1,
|
|
108
111
|
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
|
|
112
|
+
saveAsProcessing: async (uid: string, input: unknown) => {
|
|
113
|
+
const imageInput = input as WizardImageInput;
|
|
114
|
+
const creationId = `${scenario.id}_${Date.now()}`;
|
|
115
|
+
processingCreationId = creationId;
|
|
113
116
|
|
|
114
|
-
|
|
115
|
-
id:
|
|
116
|
-
uri:
|
|
117
|
+
await repository.create(uid, {
|
|
118
|
+
id: creationId,
|
|
119
|
+
uri: "",
|
|
117
120
|
type: scenario.id,
|
|
118
|
-
prompt:
|
|
119
|
-
status: "
|
|
121
|
+
prompt: imageInput.prompt,
|
|
122
|
+
status: "processing" as const,
|
|
120
123
|
createdAt: new Date(),
|
|
121
124
|
isShared: false,
|
|
122
125
|
isFavorite: false,
|
|
123
|
-
metadata: {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
126
|
+
metadata: { scenarioId: scenario.id, scenarioTitle: scenario.title },
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
130
|
+
console.log("[ImageStrategy] Saved as processing", { creationId });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return creationId;
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
save: async (result: unknown, uid: string, creationId?: string) => {
|
|
137
|
+
const input = lastInputRef;
|
|
138
|
+
const imageResult = result as { imageUrl?: string };
|
|
139
|
+
if (!input || !scenario?.id || !imageResult.imageUrl) return;
|
|
140
|
+
|
|
141
|
+
const idToUpdate = creationId || processingCreationId;
|
|
142
|
+
|
|
143
|
+
if (idToUpdate) {
|
|
144
|
+
// Update existing processing creation to completed
|
|
145
|
+
await repository.update(uid, idToUpdate, {
|
|
146
|
+
uri: imageResult.imageUrl,
|
|
147
|
+
status: "completed" as const,
|
|
148
|
+
output: { imageUrl: imageResult.imageUrl },
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
152
|
+
console.log("[ImageStrategy] Updated to completed", { creationId: idToUpdate });
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
// Fallback: create new (shouldn't happen normally)
|
|
156
|
+
await repository.create(uid, {
|
|
157
|
+
id: `${scenario.id}_${Date.now()}`,
|
|
158
|
+
uri: imageResult.imageUrl,
|
|
159
|
+
type: scenario.id,
|
|
160
|
+
prompt: input.prompt,
|
|
161
|
+
status: "completed" as const,
|
|
162
|
+
createdAt: new Date(),
|
|
163
|
+
isShared: false,
|
|
164
|
+
isFavorite: false,
|
|
165
|
+
metadata: { scenarioId: scenario.id, scenarioTitle: scenario.title },
|
|
166
|
+
output: { imageUrl: imageResult.imageUrl },
|
|
167
|
+
});
|
|
168
|
+
}
|
|
131
169
|
},
|
|
132
170
|
};
|
|
133
171
|
}
|
package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts
CHANGED
|
@@ -76,6 +76,7 @@ export function createVideoStrategy(options: CreateVideoStrategyOptions): Wizard
|
|
|
76
76
|
const videoFeatureType = getVideoFeatureType(scenario.id);
|
|
77
77
|
|
|
78
78
|
let lastInputRef: WizardVideoInput | null = null;
|
|
79
|
+
let processingCreationId: string | null = null;
|
|
79
80
|
|
|
80
81
|
return {
|
|
81
82
|
execute: async (input: unknown) => {
|
|
@@ -102,23 +103,63 @@ export function createVideoStrategy(options: CreateVideoStrategyOptions): Wizard
|
|
|
102
103
|
|
|
103
104
|
getCreditCost: () => 1,
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
106
|
+
saveAsProcessing: async (uid: string, input: unknown) => {
|
|
107
|
+
const videoInput = input as WizardVideoInput;
|
|
108
|
+
const creationId = `${scenario.id}_${Date.now()}`;
|
|
109
|
+
processingCreationId = creationId;
|
|
109
110
|
|
|
110
111
|
await repository.create(uid, {
|
|
111
|
-
id:
|
|
112
|
-
uri:
|
|
112
|
+
id: creationId,
|
|
113
|
+
uri: "",
|
|
113
114
|
type: scenario.id,
|
|
114
|
-
prompt:
|
|
115
|
-
status: "
|
|
115
|
+
prompt: videoInput.prompt,
|
|
116
|
+
status: "processing" as const,
|
|
116
117
|
createdAt: new Date(),
|
|
117
118
|
isShared: false,
|
|
118
119
|
isFavorite: false,
|
|
119
120
|
metadata: { scenarioId: scenario.id, scenarioTitle: scenario.title },
|
|
120
|
-
output: { videoUrl: videoResult.videoUrl },
|
|
121
121
|
});
|
|
122
|
+
|
|
123
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
124
|
+
console.log("[VideoStrategy] Saved as processing", { creationId });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return creationId;
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
save: async (result: unknown, uid: string, creationId?: string) => {
|
|
131
|
+
const input = lastInputRef;
|
|
132
|
+
const videoResult = result as { videoUrl?: string };
|
|
133
|
+
if (!input || !scenario?.id || !videoResult.videoUrl) return;
|
|
134
|
+
|
|
135
|
+
const idToUpdate = creationId || processingCreationId;
|
|
136
|
+
|
|
137
|
+
if (idToUpdate) {
|
|
138
|
+
// Update existing processing creation to completed
|
|
139
|
+
await repository.update(uid, idToUpdate, {
|
|
140
|
+
uri: videoResult.videoUrl,
|
|
141
|
+
status: "completed" as const,
|
|
142
|
+
output: { videoUrl: videoResult.videoUrl },
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
146
|
+
console.log("[VideoStrategy] Updated to completed", { creationId: idToUpdate });
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
// Fallback: create new (shouldn't happen normally)
|
|
150
|
+
await repository.create(uid, {
|
|
151
|
+
id: `${scenario.id}_${Date.now()}`,
|
|
152
|
+
uri: videoResult.videoUrl,
|
|
153
|
+
type: scenario.id,
|
|
154
|
+
prompt: input.prompt,
|
|
155
|
+
status: "completed" as const,
|
|
156
|
+
createdAt: new Date(),
|
|
157
|
+
isShared: false,
|
|
158
|
+
isFavorite: false,
|
|
159
|
+
metadata: { scenarioId: scenario.id, scenarioTitle: scenario.title },
|
|
160
|
+
output: { videoUrl: videoResult.videoUrl },
|
|
161
|
+
});
|
|
162
|
+
}
|
|
122
163
|
},
|
|
123
164
|
};
|
|
124
165
|
}
|
|
@@ -6,5 +6,8 @@
|
|
|
6
6
|
export interface WizardStrategy {
|
|
7
7
|
execute: (input: unknown) => Promise<{ imageUrl?: string; videoUrl?: string }>;
|
|
8
8
|
getCreditCost: () => number;
|
|
9
|
-
|
|
9
|
+
/** Save as processing when generation starts - returns creation ID */
|
|
10
|
+
saveAsProcessing?: (userId: string, input: unknown) => Promise<string>;
|
|
11
|
+
/** Update to completed when generation finishes */
|
|
12
|
+
save?: (result: unknown, userId: string, creationId?: string) => Promise<void>;
|
|
10
13
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* useWizardGeneration Hook
|
|
3
3
|
* Wizard generation using orchestrator + strategy factory pattern
|
|
4
|
-
*
|
|
4
|
+
* Saves to Firestore with status="processing" at start for gallery display
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { useEffect, useRef, useMemo, useCallback } from "react";
|
|
8
8
|
import { useGenerationOrchestrator } from "../../../../../presentation/hooks/generation";
|
|
9
|
-
import { usePendingJobs } from "../../../../../presentation/hooks/use-pending-jobs";
|
|
10
9
|
import { createWizardStrategy, buildWizardInput } from "../../infrastructure/strategies";
|
|
11
10
|
import type {
|
|
12
11
|
UseWizardGenerationProps,
|
|
@@ -34,23 +33,19 @@ export const useWizardGeneration = (
|
|
|
34
33
|
onSuccess,
|
|
35
34
|
onError,
|
|
36
35
|
onCreditsExhausted,
|
|
37
|
-
trackAsBackgroundJob = true,
|
|
38
36
|
} = props;
|
|
39
37
|
|
|
40
38
|
const hasStarted = useRef(false);
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
const { addJob, updateJob, removeJob } = usePendingJobs();
|
|
39
|
+
const currentCreationIdRef = useRef<string | null>(null);
|
|
44
40
|
|
|
45
41
|
useEffect(() => {
|
|
46
42
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
47
43
|
console.log("[useWizardGeneration] Initialized", {
|
|
48
44
|
scenarioId: scenario.id,
|
|
49
45
|
outputType: scenario.outputType,
|
|
50
|
-
trackAsBackgroundJob,
|
|
51
46
|
});
|
|
52
47
|
}
|
|
53
|
-
}, [scenario.id, scenario.outputType
|
|
48
|
+
}, [scenario.id, scenario.outputType]);
|
|
54
49
|
|
|
55
50
|
const strategy = useMemo(() => {
|
|
56
51
|
return createWizardStrategy({
|
|
@@ -62,17 +57,14 @@ export const useWizardGeneration = (
|
|
|
62
57
|
const handleSuccess = useCallback(
|
|
63
58
|
(result: unknown) => {
|
|
64
59
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
65
|
-
console.log("[useWizardGeneration] Success"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (trackAsBackgroundJob && currentJobIdRef.current) {
|
|
69
|
-
removeJob(currentJobIdRef.current);
|
|
70
|
-
currentJobIdRef.current = null;
|
|
60
|
+
console.log("[useWizardGeneration] Success", {
|
|
61
|
+
creationId: currentCreationIdRef.current,
|
|
62
|
+
});
|
|
71
63
|
}
|
|
72
|
-
|
|
64
|
+
currentCreationIdRef.current = null;
|
|
73
65
|
onSuccess?.(result);
|
|
74
66
|
},
|
|
75
|
-
[
|
|
67
|
+
[onSuccess],
|
|
76
68
|
);
|
|
77
69
|
|
|
78
70
|
const handleError = useCallback(
|
|
@@ -80,17 +72,11 @@ export const useWizardGeneration = (
|
|
|
80
72
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
81
73
|
console.log("[useWizardGeneration] Error:", err.message);
|
|
82
74
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
updateJob({
|
|
86
|
-
id: currentJobIdRef.current,
|
|
87
|
-
updates: { status: "failed", error: err.message, progress: 0 },
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
75
|
+
// Note: Failed status update is handled by orchestrator via strategy
|
|
76
|
+
currentCreationIdRef.current = null;
|
|
91
77
|
onError?.(err.message);
|
|
92
78
|
},
|
|
93
|
-
[
|
|
79
|
+
[onError],
|
|
94
80
|
);
|
|
95
81
|
|
|
96
82
|
const { generate, isGenerating } = useGenerationOrchestrator(strategy, {
|
|
@@ -113,31 +99,27 @@ export const useWizardGeneration = (
|
|
|
113
99
|
hasStarted.current = true;
|
|
114
100
|
|
|
115
101
|
buildWizardInput(wizardData, scenario)
|
|
116
|
-
.then((input) => {
|
|
102
|
+
.then(async (input) => {
|
|
117
103
|
if (!input) {
|
|
118
104
|
hasStarted.current = false;
|
|
119
105
|
onError?.("Failed to build generation input");
|
|
120
106
|
return;
|
|
121
107
|
}
|
|
122
108
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
140
|
-
console.log("[useWizardGeneration] Created background job:", jobId);
|
|
109
|
+
// Save to Firestore with status="processing" BEFORE starting generation
|
|
110
|
+
if (strategy.saveAsProcessing && userId) {
|
|
111
|
+
try {
|
|
112
|
+
const creationId = await strategy.saveAsProcessing(userId, input);
|
|
113
|
+
currentCreationIdRef.current = creationId;
|
|
114
|
+
|
|
115
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
116
|
+
console.log("[useWizardGeneration] Saved as processing:", creationId);
|
|
117
|
+
}
|
|
118
|
+
} catch (err) {
|
|
119
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
120
|
+
console.error("[useWizardGeneration] saveAsProcessing error:", err);
|
|
121
|
+
}
|
|
122
|
+
// Continue with generation even if save fails
|
|
141
123
|
}
|
|
142
124
|
}
|
|
143
125
|
|
|
@@ -162,8 +144,8 @@ export const useWizardGeneration = (
|
|
|
162
144
|
isGenerating,
|
|
163
145
|
generate,
|
|
164
146
|
onError,
|
|
165
|
-
|
|
166
|
-
|
|
147
|
+
strategy,
|
|
148
|
+
userId,
|
|
167
149
|
]);
|
|
168
150
|
|
|
169
151
|
return { isGenerating };
|