@umituz/react-native-ai-generation-content 1.56.2 → 1.57.0

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.56.2",
3
+ "version": "1.57.0",
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",
@@ -3,9 +3,12 @@
3
3
  * Orchestrates wizard-based generation by delegating to appropriate mode:
4
4
  * - Video: Queue-based generation with background support
5
5
  * - Photo: Blocking execution for quick results
6
+ *
7
+ * Architecture: State machine pattern with useReducer
8
+ * States: IDLE → PREPARING → GENERATING → COMPLETED/ERROR → IDLE
6
9
  */
7
10
 
8
- import { useEffect, useRef, useMemo } from "react";
11
+ import { useEffect, useReducer, useMemo } from "react";
9
12
  import { createWizardStrategy, buildWizardInput } from "../../infrastructure/strategies";
10
13
  import { createCreationPersistence } from "../../infrastructure/utils/creation-persistence.util";
11
14
  import { useVideoQueueGeneration } from "./useVideoQueueGeneration";
@@ -17,6 +20,57 @@ import type {
17
20
 
18
21
  declare const __DEV__: boolean;
19
22
 
23
+ /**
24
+ * Generation orchestration states
25
+ */
26
+ type GenerationStatus =
27
+ | "IDLE" // Not started
28
+ | "PREPARING" // Building input
29
+ | "GENERATING" // Generation in progress
30
+ | "ERROR" // Failed (prevents retry)
31
+ | "COMPLETED"; // Success
32
+
33
+ /**
34
+ * State machine state
35
+ */
36
+ interface GenerationState {
37
+ status: GenerationStatus;
38
+ error?: string;
39
+ }
40
+
41
+ /**
42
+ * State machine actions
43
+ */
44
+ type GenerationAction =
45
+ | { type: "START_PREPARATION" }
46
+ | { type: "START_GENERATION" }
47
+ | { type: "COMPLETE" }
48
+ | { type: "ERROR"; error: string }
49
+ | { type: "RESET" };
50
+
51
+ /**
52
+ * State machine reducer
53
+ */
54
+ const generationReducer = (
55
+ state: GenerationState,
56
+ action: GenerationAction,
57
+ ): GenerationState => {
58
+ switch (action.type) {
59
+ case "START_PREPARATION":
60
+ return { status: "PREPARING" };
61
+ case "START_GENERATION":
62
+ return { status: "GENERATING" };
63
+ case "COMPLETE":
64
+ return { status: "COMPLETED" };
65
+ case "ERROR":
66
+ return { status: "ERROR", error: action.error };
67
+ case "RESET":
68
+ return { status: "IDLE" };
69
+ default:
70
+ return state;
71
+ }
72
+ };
73
+
20
74
  export type {
21
75
  WizardOutputType,
22
76
  WizardScenarioData,
@@ -39,7 +93,8 @@ export const useWizardGeneration = (
39
93
  onCreditsExhausted,
40
94
  } = props;
41
95
 
42
- const hasStarted = useRef(false);
96
+ // State machine: replaces multiple useRef flags
97
+ const [state, dispatch] = useReducer(generationReducer, { status: "IDLE" });
43
98
 
44
99
  const persistence = useMemo(() => createCreationPersistence(), []);
45
100
  const strategy = useMemo(
@@ -75,20 +130,28 @@ export const useWizardGeneration = (
75
130
  useEffect(() => {
76
131
  const isAlreadyGenerating = videoGeneration.isGenerating || photoGeneration.isGenerating;
77
132
 
78
- if (isGeneratingStep && !hasStarted.current && !isAlreadyGenerating) {
79
- hasStarted.current = true;
133
+ // Start generation: Simple single condition using state machine
134
+ if (isGeneratingStep && state.status === "IDLE" && !isAlreadyGenerating) {
135
+ dispatch({ type: "START_PREPARATION" });
136
+
137
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
138
+ console.log("[WizardGeneration] State: PREPARING");
139
+ }
80
140
 
81
141
  buildWizardInput(wizardData, scenario)
82
142
  .then(async (input) => {
83
143
  if (!input) {
84
- hasStarted.current = false;
144
+ dispatch({ type: "ERROR", error: "Failed to build generation input" });
85
145
  onError?.("Failed to build generation input");
86
146
  return;
87
147
  }
88
148
 
149
+ dispatch({ type: "START_GENERATION" });
150
+
89
151
  const typedInput = input as { prompt?: string };
90
152
 
91
153
  if (typeof __DEV__ !== "undefined" && __DEV__) {
154
+ console.log("[WizardGeneration] State: GENERATING");
92
155
  console.log("[WizardGeneration] Mode:", isVideoMode ? "VIDEO_QUEUE" : "PHOTO_BLOCKING");
93
156
  }
94
157
 
@@ -97,21 +160,28 @@ export const useWizardGeneration = (
97
160
  } else {
98
161
  await photoGeneration.startGeneration(input, typedInput.prompt || "");
99
162
  }
163
+
164
+ dispatch({ type: "COMPLETE" });
100
165
  })
101
166
  .catch((error) => {
102
167
  if (typeof __DEV__ !== "undefined" && __DEV__) {
103
168
  console.error("[WizardGeneration] Build input error:", error.message);
104
169
  }
105
- hasStarted.current = false;
170
+ dispatch({ type: "ERROR", error: error.message });
106
171
  onError?.(error.message);
107
172
  });
108
173
  }
109
174
 
110
- if (!isGeneratingStep && hasStarted.current) {
111
- hasStarted.current = false;
175
+ // Reset state when leaving generating step
176
+ if (!isGeneratingStep && state.status !== "IDLE") {
177
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
178
+ console.log("[WizardGeneration] State: RESET");
179
+ }
180
+ dispatch({ type: "RESET" });
112
181
  }
113
182
  }, [
114
183
  isGeneratingStep,
184
+ state.status,
115
185
  scenario,
116
186
  wizardData,
117
187
  isVideoMode,